本文節選自《瘋狂Spring Cloud微服務架構實戰》
京東購買位址::https://item.jd.com/12256011.html
當當網購買位址::http://product.dangdang.com/25201393.html
Spring Cloud教學視訊:http://blog.csdn.net/boxiong86/article/details/78399104
Spring Cloud電子書:http://blog.csdn.net/boxiong86/article/details/78488226
Feign與Hystrix整合
Feign對Hystrix提供了支援,為“服務調用者”加入以下Feign依賴:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
在application.yml中打開Feign的Hystrix開關,請見以下配置:
feign:
hystrix:
enabled: true
在應用啟動類裡面,加入開Feign的開關,本小節的“服務調用者”應用啟動類,所使用的注解如下:
@SpringBootApplication
@EnableDiscoveryClient
@EnableCircuitBreaker
@ServletComponentScan
@EnableFeignClients
建立Feign接口,調用“服務提供者(spring-hystrix-provider)”的“/hello”服務,請見代碼清單6-24。
代碼清單6-24:
codes\06\6.4\spring-hystrix-invoker\src\main\java\org\crazyit\cloud\feign\HelloClient.java
@FeignClient(name = "spring-hystrix-provider", fallback = HelloClientFallback.class)
public interface HelloClient {
@RequestMapping(method = RequestMethod.GET, value = "/hello")
public String hello();
@Component
static class HelloClientFallback implements HelloClient {
public String hello() {
System.out.println("hello方法的回退");
return "error hello";
}
}
}
與普通的Feign用戶端無異,僅僅設定了處理回退的類,回退類實作了用戶端接口。為了能測試效果,修改伺服器端的“/hello”服務,讓其有800毫秒的延時。根據前面章節可知,預設情況下,Hystrix的逾時時間為1秒,是以,還需要修改配置逾時配置。代碼清單6-25,在application.yml中修改指令配置。
代碼清單6-25:codes\06\6.4\spring-hystrix-invoker\src\main\resources\application.yml
hystrix:
command:
HelloClient#hello():
execution:
isolation:
thread:
timeoutInMilliseconds: 500
circuitBreaker:
requestVolumeThreshold: 3
注意,如果是針對全局配置,則使用與下面類似的配置片斷:
hystrix.command.default.circuitBreaker.requestVolumeThreshold // 預設時間段内發生的請求數
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds // 逾時時間
如果針對某個用戶端,如使用下面的配置片斷:
hystrix.command.CommandKey.circuitBreaker.requestVolumeThreshold
Feign與Hystrix整合使用時,會自動幫我們生成CommandKey,格式為:“Feign用戶端接口名#方法名()”。例如本例中的用戶端為HelloClient,方法為hello,生成的CommandKey為“HelloClient#hello()”。而預設情況下,生成的GroupKey為@FeignClient注解的name屬性。
以上的配置中,我們針對了hello方法,設定了逾時時間為500毫秒,而“/hello”服務逾時時間為800毫秒,換言之,hello方法總會逾時。另外,如果請求超過3次并且失敗率超過50%,斷路器将被打開。編寫控制器,調用hello服務,并檢視斷路器的情況,請見代碼清單6-26。
代碼清單6-26:
codes\06\6.4\spring-hystrix-invoker\src\main\java\org\crazyit\cloud\feign\HelloController.java
@RestController
public class HelloController {
@Autowired
HelloClient helloClient;
@RequestMapping(value = "/feign/hello", method = RequestMethod.GET)
public String feignHello() {
// hello方法會逾時
String helloResult = helloClient.hello();
//擷取斷路器
HystrixCircuitBreaker breaker = HystrixCircuitBreaker.Factory
.getInstance(HystrixCommandKey.Factory
.asKey("HelloClient#hello()"));
System.out.println("斷路器狀态:" + breaker.isOpen());
return helloResult;
}
}
控制器的方法中,擷取了hello方法的斷路器,并輸出其狀态。接下來,編寫一個測試用戶端,多線程通路:http://localhost:9000/feign/hello/{index},也就是控制器的feignHello方法,用戶端請見代碼清單6-27。
代碼清單6-27:
06\6.4\spring-hystrix-invoker\src\main\java\org\crazyit\cloud\feign\TestFeignClient.java
public class TestFeignClient {
public static void main(String[] args) throws Exception {
//建立預設的HttpClient
final CloseableHttpClient httpclient = HttpClients.createDefault();
//調用多次服務并輸出結果
for(int i = 0; i < 6; i++) {
//建立線程通路接口
Thread t = new Thread() {
public void run() {
try {
String url = "http://localhost:9000/feign/hello";
//調用GET方法請求服務
HttpGet httpget = new HttpGet(url);
//擷取響應
HttpResponse response = httpclient.execute(httpget);
//根據 響應解析出字元串
System.out.println(EntityUtils.toString(response.getEntity()));
} catch (Exception e) {
e.printStackTrace();
}
}
};
t.start();
}
//等待完成
Thread.sleep(15000);
}
}
完成後,依次啟動Eureka伺服器、服務提供者、服務調用者,運作代碼清單6-27,可看到“服務計用者”的控制台輸出如下:
斷路器狀态:false
斷路器狀态:false
斷路器狀态:false
斷路器狀态:false
斷路器狀态:true
斷路器狀态:true
根據輸出可知,斷路器已經被打開。
本文節選自《瘋狂Spring Cloud微服務架構實戰》
Spring Cloud教學視訊:http://blog.csdn.net/boxiong86/article/details/78399104
Spring Cloud電子書:http://blog.csdn.net/boxiong86/article/details/78488226
本書代碼共享位址:https://gitee.com/yangenxiong/SpringCloud
