使用Feign調用接口分兩層,ribbon的調用和hystrix的調用,因此ribbon的超時時間和Hystrix的超時時間的結合就是Feign的超時時間java
ribbon: OkToRetryOnAllOperations: false #對全部操做請求都進行重試,默認false ReadTimeout: 3000 #負載均衡超時時間,默認值5000 ConnectTimeout: 2000 #ribbon請求鏈接的超時時間,默認值2000 MaxAutoRetries: 0 #對當前實例的重試次數,默認0 MaxAutoRetriesNextServer: 0 #對切換實例的重試次數,默認1
hystrix: command: default: #default全局有效,service id指定應用有效 execution: timeout: #是否開啓超時熔斷 enabled: true isolation: thread: timeoutInMilliseconds: 4000 #斷路器超時時間,默認1000ms feign: hystrix: enabled: true
開了一個Eureka服務中心web
開了兩個個服務eureka-client,端口分別爲8762
和8763
,進行負載均衡spring
eureka-client的方法:服務器
package com.example.cloud_client; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.*; /** * @author 莊勇 * @date 2018/12/11 16:27 */ @RestController public class TestController { @Value("${server.port}") String port; @Value("${spring.application.name}") String serviceName; @RequestMapping(value="/test", method = RequestMethod.GET) public String index(@RequestParam("millis") int millis) throws InterruptedException { System.out.println("8762---"+System.currentTimeMillis()); Thread.sleep(millis); return "serviceName=" + serviceName + "-------port=" + port; } }
feignClient網絡
eureka-feign調用client的方法,經過傳參數millis
來控制client線程休眠的時間app
controller負載均衡
package com.example.eurekafeignclient; import com.example.eurekafeignclient.inter.FeignInterface; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; /** * @author 莊勇 * @date 2018/12/12 9:37 */ @RestController public class FeiConsumerController { @Autowired FeignInterface feignInterface; @RequestMapping("eureka-client") public String feignConsumer(@RequestParam int millis) { long start = System.currentTimeMillis(); System.out.println(start); String a = feignInterface.IndexInfo(millis); long end = System.currentTimeMillis(); System.out.println(end); System.out.println("調用eureka-client服務時長" + (end-start) + "ms"); return a; } }
serveiceide
package com.example.eurekafeignclient.inter; import com.example.eurekafeignclient.HelloServiceFallback; 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; /** * @author 莊勇 * @date 2018/12/12 9:35 */ @FeignClient(value="eureka-client",fallback = HelloServiceFallback.class) public interface FeignInterface { @RequestMapping(value="/test", method = RequestMethod.GET) String IndexInfo(@RequestParam(value="millis") int millis); }
熔斷方法fallback測試
package com.example.eurekafeignclient; import com.example.eurekafeignclient.inter.FeignInterface; import org.springframework.stereotype.Component; /** * @author 莊勇 * @date 2018/12/12 10:27 */ @Component public class HelloServiceFallback implements FeignInterface { @Override public String IndexInfo(int millis) { System.out.println("熔斷"); return "熔斷"; } }
主要測試幾種狀況spa
1, ribbon的超時時間和Hystrix的超時時間的關係
2,ribbon的超時時間和Hystrix的超時時間的何時生效
3,重試時候參數配置
4,其餘
全局參數:ribbon和hystrix參數設置沒有重試
OkToRetryOnAllOperations: false MaxAutoRetries: 0 #對當前實例的重試次數,默認0 MaxAutoRetriesNextServer: 0 #對切換實例的重試次數,默認1 ReadTimeout: 3000 #負載均衡超時時間,默認值5000 ConnectTimeout: 1000 #ribbon請求鏈接的超時時間,默認值2000 timeoutInMilliseconds: 5000 #斷路器超時時間,默認1000ms
條件1:Port=8762 Millis=1000ms Port=8763 Millis=1000ms
結果: 打印port=8762----------調用eureka-client服務時長1013ms
打印port=8763----------調用eureka-client服務時長1011ms
條件2:Port=8762 Millis=3500ms Port=8763 Millis=3500ms
打印port=8762----------熔斷1544750879175調用eureka-client服務時長3003ms
打印port=8763----------熔斷 1544750757822 調用eureka-client服務時長3003ms
條件3:Port=8762 Millis=5500ms Port=8763 Millis=5500ms
打印port=8762----------熔斷1544750879175調用eureka-client服務時長3005ms
打印port=8763----------熔斷1544750879175調用eureka-client服務時長3007ms
如下修改了參數ReadTimeout和timeoutInMilliseconds進行測試
OkToRetryOnAllOperations: false MaxAutoRetries: 0 #對當前實例的重試次數,默認0 MaxAutoRetriesNextServer: 0 #對切換實例的重試次數,默認1 ReadTimeout: 5000 #負載均衡超時時間,默認值5000 ConnectTimeout: 1000 #ribbon請求鏈接的超時時間,默認值2000 timeoutInMilliseconds: 3000 #斷路器超時時間,默認1000ms
條件4:Port=8762 Millis=5500ms Port=8763 Millis=5500ms
打印port=8762----------熔斷1544750879175調用eureka-client服務時長3364ms
打印port=8763----------熔斷1544750879175調用eureka-client服務時長3005ms
條件5:Port=8762 Millis=3500ms Port=8763 Millis=3500ms
打印port=8762----------熔斷1544750879175調用eureka-client服務時長3004ms
打印port=8763----------熔斷1544750879175調用eureka-client服務時長3003ms
條件6:Port=8762 Millis=1000ms Port=8763 Millis=1000ms
打印port=8762----------調用eureka-client服務時長1010ms
打印port=8763----------調用eureka-client服務時長1003ms
停掉8762和8763服務
條件7:Port=8762 Millis=1000ms Port=8763 Millis=1000ms
打印----------熔斷1544754831161調用eureka-client服務時長1007ms
條件8:Port=8762 Millis=3500ms Port=8763 Millis=3500ms
打印----------熔斷1544754945541調用eureka-client服務時長1007ms
條件9:Port=8762 Millis=5500ms Port=8763 Millis=5500ms
打印----------熔斷1544755009533調用eureka-client服務時長1006ms
無重試的時候,超時時間與ReadTimeout和timeoutInMilliseconds最小值相關,此時誰的值小誰生效
停掉服務時,客戶服務中止時,超時時間採用的是timeoutInMilliseconds的默認時間1000ms???
OkToRetryOnAllOperations: false MaxAutoRetries: 1 #對當前實例的重試次數,默認0 MaxAutoRetriesNextServer: 0 #對切換實例的重試次數,默認1 ReadTimeout: 3000 #負載均衡超時時間,默認值5000 ConnectTimeout: 1000 #ribbon請求鏈接的超時時間,默認值2000 timeoutInMilliseconds: 5000 #斷路器超時時間,默認1000ms
重試次數=(MaxAutoRetries+MaxAutoRetriesNextServer+MaxAutoRetriesNextServer*MaxAutoRetries) 測試中可驗證
條件10:Port=8762 Millis=1000ms Port=8763 Millis=1000ms
打印----------1544756976651調用eureka-client服務時長1955ms
條件11:Port=8762 Millis=3500ms Port=8763 Millis=3500ms
打印8762----------熔斷1544757079644調用eureka-client服務時長5017ms
打印8763----------熔斷1544757189984調用eureka-client服務時長5004ms
此時出現了重試 修改參數
OkToRetryOnAllOperations: false MaxAutoRetries: 1 #對當前實例的重試次數,默認0 MaxAutoRetriesNextServer: 0 #對切換實例的重試次數,默認1 ReadTimeout: 3000 #負載均衡超時時間,默認值5000 ConnectTimeout: 1000 #ribbon請求鏈接的超時時間,默認值2000 timeoutInMilliseconds: 10000 #斷路器超時時間,默認1000ms
條件12:Port=8762 Millis=3500ms Port=8763 Millis=3500ms
打印8762----------熔斷1544757421610調用eureka-client服務時長6009ms
打印8762----------熔斷1544757542162調用eureka-client服務時長6009ms
打印8762----------熔斷1544757546794調用eureka-client服務時長6010ms
此時修改參數MaxAutoRetriesNextServer: 1 #對切換實例的重試次數,默認1
OkToRetryOnAllOperations: false MaxAutoRetries: 1 #對當前實例的重試次數,默認0 MaxAutoRetriesNextServer: 1 #對切換實例的重試次數,默認1 ReadTimeout: 3000 #負載均衡超時時間,默認值5000 ConnectTimeout: 1000 #ribbon請求鏈接的超時時間,默認值2000 timeoutInMilliseconds: 10000 #斷路器超時時間,默認1000ms
條件13:Port=8762 Millis=3500ms Port=8763 Millis=3500ms
結果:打印
熔斷1544757776401調用eureka-client服務時長12098ms
熔斷1544757776401調用eureka-client服務時長12552ms
熔斷1544757776401調用eureka-client服務時長12707ms
熔斷1544757776401調用eureka-client服務時長12403ms
熔斷1544757776401調用eureka-client服務時長12763ms
熔斷1544757776466調用eureka-client服務時長12008ms
OkToRetryOnAllOperations: false MaxAutoRetries: 1 #對當前實例的重試次數,默認0 MaxAutoRetriesNextServer: 1 #對切換實例的重試次數,默認1 ReadTimeout: 3000 #負載均衡超時時間,默認值5000 ConnectTimeout: 1000 #ribbon請求鏈接的超時時間,默認值2000 timeoutInMilliseconds: 5000 #斷路器超時時間,默認1000ms
條件13:Port=8762 Millis=3500ms Port=8763 Millis=3500ms
結果:打印
熔斷1544759011132調用eureka-client服務時長5003ms
於此同時 8762服務器打印了
8763服務器打印了
說明重試並無結束
重試次數=(MaxAutoRetries+MaxAutoRetriesNextServer+MaxAutoRetriesNextServer*MaxAutoRetries)
重試時間=(MaxAutoRetries+MaxAutoRetriesNextServer+MaxAutoRetriesNextServer*MaxAutoRetries)*ReadTimeout+網絡響應時間
而且因爲重試應爲執行熔斷後而中止重試,從而形成沒必要要的狀況發生,所以熔斷時間應該在重試時間以後,
(MaxAutoRetries+MaxAutoRetriesNextServer+MaxAutoRetriesNextServer*MaxAutoRetries)*ReadTimeout+網絡響應時間+ReadTimeout<timeoutInMilliseconds