一、Ribboon配置
在Spring cloud Feign中客戶端負載均衡是通過Spring cloud Ribbon實現的,所以我們可以直接通過配置Ribbon客戶端的方式來自定義各個服務客戶端調用的參數。那么我們怎么在Spring cloud Feign中配置Ribbon呢?
全局配置
全局配置方法簡單,直接用ribbon.<key>=<value>的方式設置ribbon的默認參數。如下:
#ribbon請求連接的超時時間
ribbon.ConnectTimeout=250
#請求處理的超時時間
ribbon.ReadTimeout=1000
#對所有操作請求都進行重試
ribbon.OkToRetryOnAllOperations=true
#對當前實例的重試次數
ribbon.MaxAutoRetries=1
#對下個實例的重試次數
ribbon.MaxAutoRetriesNextServer=1
指定服務配置
為了有針對性的配置,針對各個服務客戶端進行個性化配置方式與使用Spring cloud Ribbon時的配置方式一樣的,都采用<client>.ribbon.<key>=<value>的格式進行設置。如下:
hello-service.ribbon.ConnectTimeout=500
hello-service.ribbon.ReadTimeout=1000
二、重試機制
#對所有操作請求都進行重試 ribbon.OkToRetryOnAllOperations=false #對當前實例的重試次數 ribbon.MaxAutoRetries=1 #對下個實例的重試次數 ribbon.MaxAutoRetriesNextServer=1
結果:
未超時(正常)時,compute服務被調用一次。
超時時,compute服務被調用3次。
三、Hystrix配置
在Spring cloud Feign中,除了引入Spring cloud Ribbon之外,還引入了服務保護與容錯的工具Hystrix。默認情況下, Spring cloud Feign會為將所有Feign客戶端的方法都封裝到Hystrix命令中進行服務保護。
那么在Spring cloud Feign如何配置Hystrix的屬性以及如何實現服務降級?
全局配置
全局配置通ribbon一樣,直接使用它的默認配置前綴hystrix.command.default就可以進行設置,
在設置之前,需要確認feign.hystrix.enabled參數是否設置為false,如果為false則關閉Feign客戶端的Hystrix支持。
或者使用hystrix.command.default.execution.timeout.enabled=false來關閉熔斷功能。
比如設置全局的超時時間:
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds
詳細參數列表見《服務容錯保護斷路器Hystrix之二:Hystrix工作流程解析》中的《2.8、關於配置》
指定服務配置
如果想局部關閉Hystrix,需要通過使用@Scope("prototype")注解為指定的客戶端配置Feign.Builder實例,詳細步驟如下:
package com.dxz.feign; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Scope; import feign.Feign; @Configuration public class DisableHystrixConfiguration { @Bean @Scope("prototype") public Feign.Builder feignBuilder() { return Feign.builder(); } }
package com.dxz.feign.remote; import org.springframework.cloud.netflix.feign.FeignClient; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import com.dxz.feign.DisableHystrixConfiguration; //@FeignClient("compute-service") @FeignClient(name="compute-service",configuration=DisableHystrixConfiguration.class) public interface HelloService { @RequestMapping(value="/add", method = RequestMethod.GET) String hello(@RequestParam("a") Integer a, @RequestParam("b") Integer b, @RequestParam("sn") Integer sn); }
結果:
下面的超時,不會熔斷調用fallback方法,而是等待。
四、服務降級配置
新增一個服務降級處理類:
package com.dxz.feign.remote; import org.springframework.stereotype.Service; @Service public class HelloServiceFallback implements HelloService { @Override public String hello(Integer a, Integer b, Integer sn) { System.out.println("HelloServiceFallback"); return "fallback"; } }
在服務綁定接口HelloService中,通過@FeignClient注解的fallback屬性來指定服務降級處理類:
package com.dxz.feign.remote; import org.springframework.cloud.netflix.feign.FeignClient; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import com.dxz.feign.DisableHystrixConfiguration; @FeignClient(name="compute-service", fallback=HelloServiceFallback.class) //@FeignClient(name="compute-service",configuration=DisableHystrixConfiguration.class) public interface HelloService { @RequestMapping(value="/add", method = RequestMethod.GET) String hello(@RequestParam("a") Integer a, @RequestParam("b") Integer b, @RequestParam("sn") Integer sn); }
測試:
其他配置
請求壓縮
Spring cloud Feign支持請求與響應的GZIP壓縮,以減少通訊過程中的性能損耗。只需要通過下面兩個參數設置,就能開啟請求與響應的壓縮功能:
feign.compression.request.enabled=true
feign.compression.response.enabled=true
日志配置
Spring cloud Feign在構建被@FeignClient修飾的服務客戶端時,會為每一個客戶端創建一個feign.Logger實例,我們可以利用該日志對象的DEBUG模式來幫助分析Feign的請求細節。
開啟方式:
logging.level.<FeignClient>=<LEVEL value>
logging.level.com.dxz.feign.remote.HelloService=DEBUG
但是,只添加了如上配置,還無法實現對DEBUG日志的輸出,這是由於Feign客戶端默認的Logger.LEVEL對象定義為NONE級別。該級別不吉利任何Feign調用過程中的信息,所以需要調整級別,針對全局日志調整,直接在啟動類里調整如下,
package com.dxz.feign; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.netflix.feign.EnableFeignClients; import org.springframework.context.annotation.Bean; import feign.Logger; @SpringBootApplication @EnableFeignClients @EnableDiscoveryClient public class ConsumerApplication { @Bean Logger.Level feignLoggerLevel() { return Logger.Level.FULL; } public static void main(String[] args) { SpringApplication.run(ConsumerApplication.class, args); } }
如果是局部調整,可以為日志級別增加配置類,如下:
package com.dxz.feign; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import feign.Logger; @Configuration public class FullLogConfiguation { @Bean Logger.Level feignLoggerLevel() { return Logger.Level.FULL; } }
package com.dxz.feign.remote; import org.springframework.cloud.netflix.feign.FeignClient; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import com.dxz.feign.DisableHystrixConfiguration; import com.dxz.feign.FullLogConfiguation; //@FeignClient(name="compute-service", fallback=HelloServiceFallback.class) //@FeignClient(name="compute-service",configuration=DisableHystrixConfiguration.class) @FeignClient(name="compute-service", fallback=HelloServiceFallback.class, configuration=FullLogConfiguation.class) public interface HelloService { @RequestMapping(value="/add", method = RequestMethod.GET) String hello(@RequestParam("a") Integer a, @RequestParam("b") Integer b, @RequestParam("sn") Integer sn); }
測試結果: