Feign可以把Rest請求進行封裝,將遠程調用的請求封裝成本地請求的方式,不需要再手動拼接url和路徑
1請求路徑
2請求參數
3請求方式
4返回結果
我們使用注解的方式將此四項參數提供給Feign,Feign即可幫我們自動完成一次遠程請求
注解:
主類上方加入:
@EnableFeignClients
新建一個接口,並使用注解方式提供4項參數:
@FeignClient("user-service")//提供請求地址 public interface UserClient { @GetMapping("user/{id}")//提供請求路徑及參數 String queryById(@PathVariable("id") Long id);//提供請求方式及返回結果 }
服務調用代碼的改變:
原來的代碼:
@RestController @RequestMapping("consumer") @DefaultProperties(defaultFallback = "fallBack") public class UserController { @Autowired private RestTemplate restTemplate; @GetMapping("{id}") @HystrixCommand public String queryById(@PathVariable("id") Long id){ String url = "http://user-server/user/"+id; String user = restTemplate.getForObject(url, String.class); return user; } public String fallBack(Long id){ return "服務太擁擠了,請稍后再試!"; } }
改為:
@RestController @RequestMapping("consumer") @DefaultProperties(defaultFallback = "fallBack") public class UserController { @Autowired private UserClient userClient; //注意這里不再有RestTemplate了 @GetMapping("{id}") @HystrixCommand public String queryById(@PathVariable("id") Long id){ return String user = userClient.queryById(id); //此處看起來就是本地的調用了一個方法 } public String fallBack(Long id){ return "服務太擁擠了,請稍后再試!"; } }
主類:
@SpringCloudApplication public class ConsumerApplication { @Bean @LoadBalanced public RestTemplate restTemplate(){ return new RestTemplate(); } public static void main(String[] args) { SpringApplication.run(ConsumerApplication.class, args); } }
改為:
@EnableFeignClients @SpringCloudApplication public class ConsumerApplication { public static void main(String[] args) { SpringApplication.run(ConsumerApplication.class, args); } }
除此之外Feign還支持請求壓縮和日志級別,此處不詳述
OpenFeign超時時長設置及詳解
概念明確:
1 hystrix可配置的部分
hystrix.command.default.execution.timeout.enable=true //為false則超時控制有ribbon控制,為true則hystrix超時和ribbon超時都是用,但是誰小誰生效,默認為true hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=3000//熔斷器的超時時長默認1秒,最常修改的參數 circuitBreaker.requestVolumeThreshold=20 //觸發熔斷的最小請求次數,默認為20 circuitBreaker.sleepWindowInMilliseconds=5000 //休眠時長,默認為5秒 circuitBreaker.errorThresholdPercentage=50 //觸發熔斷的失敗請求最小占比,默認50%
2 ribbon的可配置部分
ribbon.ReadTimeout=1000 //處理請求的超時時間,默認為1秒 ribbon.ConnectTimeout=1000 //連接建立的超時時長,默認1秒 ribbon.MaxAutoRetries=1 //同一台實例的最大重試次數,但是不包括首次調用,默認為1次 ribbon.MaxAutoRetriesNextServer=0 //重試負載均衡其他實例的最大重試次數,不包括首次調用,默認為0次 ribbon.OkToRetryOnAllOperations=false //是否對所有操作都重試,默認false
3 Feign的可配置部分
feign.hystrix.enabled=false //Feign是否啟用斷路器,默認為false feign.client.config.default.connectTimeout=10000 //Feign的連接建立超時時間,默認為10秒 feign.client.config.default.readTimeout=60000 //Feign的請求處理超時時間,默認為60 feign.client.config.default.retryer=feign.Retryer.Default //Feign使用默認的超時配置,在該類源碼中可見,默認單次請求最大時長1秒,重試5次
另外以上各種超時配置,如果都存在,則時間小的配置生效
好的,現在來說Feign的超時時長設置:
1 Feign的默認配置,是不啟用hystrix,並且Feign的底層是調用ribbon來實現負載均衡的,所以為了不和ribbon的重試機制沖突因此也不會啟用重試機制
因此配置Feign是必須要做的就是
feign.hystrix.enabled=true //開啟Feign的hystrix,這樣配置文件中的hystrix的配置才會生效,否則依然是默認的規則
之后設置hystrix的相關配置才可以在Feign中生效,因為Feign也調用了hystrix
2 ribbon和hystrix的配置
因為hystrix的超時時長,默認為1秒,太短了!因此我們一般一定會設置hystrix的超時時長
在上面啟用了Feign的hystrix開關后,配置hystrix超時時長
execution.isolation.thread.timeoutInMilliseconds=10000 //這里設置了10秒
然后看ribbon的超時設置:
ribbon的超時設置無非2個:處理超時和連接超時,默認為1秒和1秒
但是,ribbon是有默認重試的,也是2個:統一實例的重試次數和負載均衡的不同實例的重試次數,默認為1次和0次
也就是說,在同一個實例上建立連接如果失敗可以重試1次,處理請求如果失敗可以重試1次,但是不包括首次調用,即:實際ribbon的超時時間是 1秒×2+1秒×2,即4秒
之后是,但是上面設置了hystrix超時為10秒,因此ribbon超時優先生效
最后是1個是否對所有操作重試的開關,默認為false,這里解釋下什么是所有操作:
即:為false是,GET請求不論是連接失敗還是處理失敗都會重試,而對於非GET請求只對連接失敗進行重試
因此得出結論,在使用了Feign的情況下需先開啟斷路器支持,之后配置hystrix的timeoutInMillisecond大於ribbon的 ( ConnectTimeout + ReadTimeout ) × 2即可
也就是說以后以后的配置中常用的配置項就是
1 開啟Feign的hystrix開關
2 hystrix超時時長
3 配置ribbon的ConnectTimeout時長
4 配置ribbon的ReadTimeout 時長