0406-服務註冊與發現-客戶端feign-使用、配置、日誌、timeout

官方地址:https://cloud.spring.io/spring-cloud-static/Edgware.SR3/single/spring-cloud.html#spring-cloud-feignhtml

1、概述

  Feign是一個聲明式Web服務客戶端。它使編寫Web服務客戶端變得更容易。使用Feign建立一個接口並對其進行註釋。它具備可插入的註釋支持,包括Feign註釋和JAX-RS註釋。Feign還支持可插拔編碼器和解碼器。 Spring Cloud添加了對Spring MVC註釋的支持,而且使用了Spring Web中默認使用的相同HttpMessageConverters。Spring Cloud將Ribbon和Eureka集成在一塊兒,在使用Feign時提供負載均衡的http客戶端。git

  注意:JAX-RSJAX-WSgithub

  源碼地址:https://github.com/OpenFeign/feignspring

1.一、基礎使用

1》添加pom

<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

2》啓動類上添加註解

@SpringBootApplication @EnableFeignClients public class ComsumerMovieFeignApplication { public static void main(String[] args) { SpringApplication.run(ComsumerMovieFeignApplication.class, args); } }

3》添加一個接口併爲接口添加註解,調用用戶服務

@FeignClient("microservice-provider-user") public interface UserFeignClient { // @GetMapping("/sample/{id}")
    @RequestMapping(method = RequestMethod.GET, value = "/movie/{id}") public User findById(@PathVariable("id") Long id); }

注意點:一、spring註解不能使用getMapping,需使用RequestMapping;二、@PathVariable必須添加參數;三、當服務接受參數是一個對象時候,此時默認會轉化爲post請求,及時接口寫的是get請求【?待解決】json

//請求不會成功,只要參數是複雜對象,即便指定了GET方法,feign依然會以post方法進行發送
    @RequestMapping(method = RequestMethod.GET, value = "/get-user") public User getUser(User user);

4》程序調用

 @Autowired private UserFeignClient userFeignClient; @GetMapping("/movie/{id}") public User findById(@PathVariable Long id) { return userFeignClient.findById(id); }

執行post相似服務器

參考代碼:https://github.com/bjlhx15/spring-cloud/tree/master/microservice-comsumer-movie-feign網絡

1.二、覆寫Feign的默認配置

1.2.一、概述

  Spring Cloud的Feign支持中的一箇中心概念是指定的客戶端。app

  每一個feign客戶端都是總體的一部分,這些組件是一塊兒工做以根據須要聯繫遠程服務器,而且該組件具備一個名稱,開發人員可使用@FeignClient批註命名。負載均衡

  Spring Cloud使用FeignClientsConfiguration建立一個新的集合,做爲每一個指定客戶端的ApplicationContext。這包含(除其餘外)feign.Decoder,feign.Encoder和feign.Contract。框架

  經過使用@FeignClient聲明額外配置(在FeignClientsConfiguration之上),Spring Cloud可以讓您徹底控制客戶端

示例

@FeignClient(name = "stores", configuration = FooConfiguration.class) public interface StoreClient { //..
}

  注意事項:FooConfiguration 同RibbonConfiguration一致放包問題,參看:http://www.cnblogs.com/bjlhx/p/8859088.html

  注意事項2:之前使用url能夠不用,如今必須使用name

1.2.二、默認配置

Spring Cloud Netflix默認提供如下bean for feign(BeanType beanName:ClassName):

  • Decoder feignDecoder: ResponseEntityDecoder (which wraps a SpringDecoder) 默認解碼
  • Encoder feignEncoder: SpringEncoder 默認編碼
  • Logger feignLogger: Slf4jLogger 默認日誌
  • Contract feignContract: SpringMvcContract 默認契約
  • Feign.Builder feignBuilder: HystrixFeign.Builder 默認構建builder
  • Client feignClient: if Ribbon is enabled it is a LoadBalancerFeignClient, otherwise the default feign client is used.  默認client

  經過將feign.okhttp.enabled或feign.httpclient.enabled分別設置爲true並將它們放在類路徑中,可使用OkHttpClient和ApacheHttpClient feign客戶端。當使用Apache或OkHttpClient使用OK HTTP時,能夠經過提供ClosableHttpClient的bean來定製HTTP客戶端。

1.2.三、非默認配置

  Spring Cloud Netflix默認狀況下不提供如下bean,但仍從應用程序上下文中查找這些類型的bean以建立假客戶端:

  • Logger.Level
  • Retryer
  • ErrorDecoder
  • Request.Options
  • Collection<RequestInterceptor>
  • SetterFactory

1.2.四、開發

編寫一個默認註解

@Configuration public class Configuration1 { @Bean public Contract feignContract() { return new feign.Contract.Default(); } }

  由於原默認註解使用spring的如今這裏改用feign契約,故如下調用須要使用feign的註解RequestLine等

編寫客戶端調用

@FeignClient(name = "microservice-provider-user", configuration = Configuration1.class) public interface UserFeignClient { @RequestLine("GET /sample/{id}") public User findById(@Param("id") Long id); }

程序使用便可。

參看代碼:https://github.com/bjlhx15/spring-cloud/tree/master/microservice-comsumer-movie-feign-customizing

1.2.五、若是請求eureka的接口如

@FeignClient(name = "xxxx", url = "http://localhost:8761/", configuration = Configuration2.class) public interface FeignClient2 { @RequestMapping(value = "/eureka/apps/{serviceName}") public String findServiceInfoFromEurekaByServiceName(@PathVariable("serviceName") String serviceName); }

由於eureka設置了權限此時訪問失敗

需增長配置類,Configuration2增長權限校驗

@Configuration public class Configuration2 { @Bean public BasicAuthRequestInterceptor basicAuthRequestInterceptor() { return new BasicAuthRequestInterceptor("user", "a123"); } }

1.2.六、Feign請求/響應壓縮

feign.compression.request.enabled=true feign.compression.response.enabled=true

Feign請求壓縮爲您提供了相似於您爲Web服務器設置的設置:

feign.compression.request.enabled=true feign.compression.request.mime-types=text/xml,application/xml,application/json feign.compression.request.min-request-size=2048

這些屬性使您能夠選擇壓縮媒體類型和最小請求閾值長度。

 1.三、feign日誌

  爲每一個建立的Feign客戶端建立一個記錄器。默認狀況下,記錄器的名稱是用於建立Feign客戶端的接口的完整類名稱。 Feign日誌記錄僅響應DEBUG級別。

application.yml. 

logging.level.project.user.UserClient: DEBUG

注level是具體類路徑。可能不生效,須要配置一下配置

您能夠爲每一個客戶端配置的Logger.Level對象告訴Feign要記錄多少。選擇是:

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

例如,如下操做將Logger.Level設置爲FULL:

@Configuration public class FooConfiguration { @Bean Logger.Level feignLoggerLevel() { return Logger.Level.FULL; } }

參看代碼:https://github.com/bjlhx15/spring-cloud/tree/master/microservice-comsumer-movie-feign-customizing

1.四、Feign第一次啓動timeout問題

  hystrix默認1秒超時

方法1、可配置超時時間增長:

hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 5000

方法2、關閉熔斷超時

hystrix.command.default.execution.timeout.enabled: false

方法3、關閉熔斷機制

feign.hystrix.enabled: false

能夠參看:https://github.com/Netflix/Hystrix/wiki/Configuration

1.五、手動建立Feign客戶端

@Import(FeignClientsConfiguration.class) class FooController { private FooClient fooClient; private FooClient adminClient; @Autowired public FooController(Decoder decoder, Encoder encoder, Client client, Contract contract) { this.fooClient = Feign.builder().client(client) .encoder(encoder) .decoder(decoder) .contract(contract) .requestInterceptor(new BasicAuthRequestInterceptor("user", "user")) .target(FooClient.class, "http://PROD-SVC"); this.adminClient = Feign.builder().client(client) .encoder(encoder) .decoder(decoder) .contract(contract) .requestInterceptor(new BasicAuthRequestInterceptor("admin", "admin")) .target(FooClient.class, "http://PROD-SVC"); } }
View Code

1.六、feign源碼實現過程

一、首先經過@EnabledFeignClients註解開啓FeignClient的功能。主要是啓動程序時開啓對@FeignClient註解的包掃描

二、根據feign的規則實現接口,並在接口上面加上@FeignClient註解

三、程序啓動後,進行包掃描,掃描全部的@FeignClient的註解的類,並將這些類放入Ioc容器。

四、當接口的方法被調用時,經過JDK的代理來生成具體的RequestTemplate模板對象

五、根據RequestTemplate再生成Http請求的Request對象。

六、Request對象交給Client去處理,其中Client的網絡請求框架能夠是HttpURLConnetion,HTTPClient和OkHttp等

七、最後Client被封裝到LoadBlanceClient類,這個類結合類Ribbon作負載均衡。 

相關文章
相關標籤/搜索