Spring Cloud Feign 服務消費調用(三)

序言

Spring Cloud Netflix的微服務都是以HTTP接口的形式暴露的,因此能夠用Apache的HttpClient或Spring的RestTemplate去調用java

Feign是一個使用起來更加方便的HTTP客戶端,它用起來就好像調用本地方法同樣,徹底感受不到是調用的遠程方法 git

Feign是一個聲明式的Web Service客戶端,它的目的就是讓Web Service調用更加簡單。Feign提供了HTTP請求的模板,經過編寫簡單的接口和插入註解,就能夠定義好HTTP請求的參數、格式、地址等信息。 github

Feign會徹底代理HTTP請求,咱們只須要像調用方法同樣調用它就能夠完成服務請求及相關處理。spring

Feign整合了Ribbon和Hystrix(關於Hystrix咱們後面再講),可讓咱們再也不須要顯式地使用這兩個組件。 json

總起來講,Feign具備以下特性: app

  • 可插拔的註解支持,包括Feign註解和JAX-RS註解;
  • 支持可插拔的HTTP編碼器和解碼器;
  • 支持Hystrix和它的Fallback;
  • 支持Ribbon的負載均衡;
  • 支持HTTP請求和響應的壓縮。

https://github.com/Netflix/feign負載均衡

微服務提供方註冊服務到Eureka實例代碼

pom.xmlide

<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

 <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Finchley.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>       
        </dependencies>
    </dependencyManagement>

資源配置文件微服務

## server
server.port=8082

##eureka
eureka.client.serviceUrl.defaultZone=http://localhost:8081/eureka/
eureka.instance.instance-id=${spring.application.name}:${server.port}
# 設置微服務調用地址爲IP優先(缺省爲false)
eureka.instance.prefer-ip-address=true
# 心跳時間,即服務續約間隔時間(缺省爲30s)
eureka.instance.lease-renewal-interval-in-seconds=30
# 發呆時間,即服務續約到期時間(缺省爲90s)
eureka.instance.lease-expiration-duration-in-seconds=9

起始文件post

@EnableEurekaClient
public class StartMain {
    public static void main(String[] args) {
        SpringApplication.run(StartMain.class, args);
    }
}

接口controller,能夠沒有facade層的接口,這裏是爲拉給java其餘客戶端調用設計的。

//controller層
@RestController
@RequestMapping(value = "/Promotion",method = RequestMethod.GET)
public class PromotionController implements PromotionFacade {
    @Override
    @RequestMapping(value = "/delete")
    public String releasePromotion(@RequestParam int orderID){
        return orderID+"-- hello!";
    }
}

//facade層
public interface PromotionFacade {
    /**
     * 釋放門店優惠券
     */
    String releasePromotion(@RequestParam int orderID);
}

好啦,這個啓動起來以後,就註冊到啦eureka中啦,等待被調用吧。

Feign調用簡單示例

pom.xml

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
 <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
<dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Finchley.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>       
        </dependencies>
    </dependencyManagement>

資源配置文件

## server
server.port=8083
##eureka
eureka.instance.instance-id=${spring.application.name}:${server.port}
eureka.client.serviceUrl.defaultZone=http://localhost:8081/eureka/
#租期更新時間間隔(3)
eureka.instance.leaseRenewalIntervalInSeconds=30
#租期到期時間(默認90秒)
eureka.instance.leaseExpirationDurationInSeconds=90

起始文件

@SpringBootApplication
@EnableFeignClients(basePackages = { "trade.order.remote" })
@EnableEurekaClient
public class StartMain {
    public static void main(String[] args) {
        SpringApplication.run(StartMain.class, args);
    }
}

調用類

//remote層
@FeignClient(name = "trade-promotion")
public interface PromotionClient {
     @RequestMapping(value = "/Promotion/delete",method = RequestMethod.GET)
     String  releasePromotion(@RequestParam int orderID) ;
}

//controller 層
@RestController
@RequestMapping(value = "/promotion", method = RequestMethod.GET)
public class PromotionController {
    @Autowired
    PromotionClient promotionClient;

    @RequestMapping(value = "/delete")
    public String delete(@RequestParam int orderID) {
        return promotionClient.releasePromotion(orderID);
    }
}

note:

1.上述調用只又remote就能夠啦。

2.注意路由地址大小寫規範,不要覺得本身很牛逼,一會大一會小,要我說,你很挫,一直小就能夠啦。。

Feign 工做原理

  • 在開發微服務應用時,咱們會在主程序入口添加 @EnableFeignClients 註解開啓對 Feign Client 掃描加載處理。根據 Feign Client 的開發規範,定義接口並加 @FeignClients 註解。
  • 當程序啓動時,會進行包掃描,掃描全部 @FeignClients 的註解的類,並將這些信息注入 Spring IOC 容器中。當定義的 Feign 接口中的方法被調用時,經過JDK的代理的方式,來生成具體的 RequestTemplate。當生成代理時,Feign 會爲每一個接口方法建立一個 RequetTemplate 對象,該對象封裝了 HTTP 請求須要的所有信息,如請求參數名、請求方法等信息都是在這個過程當中肯定的。
  • 而後由 RequestTemplate 生成 Request,而後把 Request 交給 Client 去處理,這裏指的 Client 能夠是 JDK 原生的 URLConnection、Apache 的 Http Client 也能夠是 Okhttp。最後 Client 被封裝到 LoadBalanceclient 類,這個類結合 Ribbon 負載均衡發起服務之間的調用。

@FeignClient 註解

  • name:指定 Feign Client 的名稱,若是項目使用了 Eureka,name 屬性會做爲微服務的名稱,用於服務發現。
  • url:url 通常用於調試,能夠手動指定 @FeignClient 調用的地址。
  • decode404:當發生404錯誤時,若是該字段爲 true,會調用 decoder 進行解碼,不然拋出 FeignException。
  • configuration:Feign 配置類,能夠自定義 Feign 的 Encoder、Decoder、LogLevel、Contract。
  • fallback:定義容錯的處理類,當調用遠程接口失敗或超時時,會調用對應接口的容錯邏輯,fallback 指定的類必須實現 @FeignClient 標記的接口。
  • fallbackFactory:工廠類,用於生成 fallback 類示例,經過這個屬性咱們能夠實現每一個接口通用的容錯邏輯,減小重複的代碼。
  • path:定義當前 FeignClient 的統一前綴。

Feign參數綁定

@PathVariable

    /**
     * 在服務提供者咱們有一個方法是用直接寫在連接,SpringMVC中用的@PathVariable
     * 這裏邊和SpringMVC中有些有一點點出入,SpringMVC中只有一個參數並且參數名的話是不用額外指定參數名的,而feign中必須指定
     */
    @RequestMapping(value = "/greet/{dd}",method = RequestMethod.GET)
    String greetFeign(@PathVariable("dd") String dd);

@RequestParam

    /**
     * 這裏說下@RequestParam 註解和SpringMVC中差異也是不大,我認爲區別在於Feign中的是參數進入URL或請求體中,
     * 而SpringMVC中是參數從請求體中到方法中
     * @param ids id串,好比「1,2,3」
     * @return
     */
    @RequestMapping(value = "/users",method = RequestMethod.GET)
    public List<User> getUsersByIds(@RequestParam("ids") List<Long> ids);

@RequestHeader

 /**
     * 這裏是將參數添加到Headers中
     * @param name 參數
     */
    @RequestMapping(value = "/headers")
    String getParamByHeaders(@RequestHeader("name") String name);

@RequestBody

   /**
     * 調用服務提供者的post方法,接收回來再被服務提供者丟回來
     * @param user User對象
     */
    @RequestMapping(value = "/user", method = RequestMethod.POST)
    User getUserByRequestBody(@RequestBody User user);

Feign壓縮與日誌

1.請求壓縮(Feign request/response compression)

##這兩行便可開啓壓縮
feign.compression.request.enabled=true
feign.compression.response.enabled=true
## 配置壓縮具體信息
feign.compression.request.enabled=true
feign.compression.request.mime-types=text/xml,application/xml,application/json
feign.compression.request.min-request-size=2048

2. Feign日誌(Feign logging)

Feign對日誌的處理很是靈活,可爲每一個Feign客戶端指定日誌記錄策略,每一個Feign客戶端都會建立一個logger。默認狀況下,logger的名稱是Feigh接口的完整類名。須要注意的是,Feign的日誌打印只會對Debug級別作出響應。

咱們能夠爲每一個Feign客戶端配置各類的Logger.Level對象,告訴Feign記錄哪些日誌。Logger.Level的值有如下選擇。

  • NONE,無記錄(DEFAULT)。
  • BASIC,只記錄請求方法和URL以及響應狀態代碼和執行時間。
  • HEADERS,記錄基本信息以及請求和響應標頭。
  • FULL,記錄請求和響應的頭文件,正文和元數據。

開啓記錄

logging.level.com.cnblogs.hellxz.client.EurekaServiceFeign: DEBUG

總結

多看文檔吧

相關文章
相關標籤/搜索