微服務(wù)中服務(wù)之間的相互依賴性錯(cuò)綜復(fù)雜堂竟,一個(gè)網(wǎng)絡(luò)請(qǐng)求通常需要調(diào)用多個(gè)服務(wù)實(shí)例才能完成徘熔。如果一個(gè)服務(wù)不可用洪唐,如網(wǎng)絡(luò)延遲或故障,會(huì)影響依賴于這個(gè)服務(wù)的其它服務(wù)佛致,最后導(dǎo)致整個(gè)系統(tǒng)處于癱瘓的狀態(tài)贮缕。為解決這種雪崩效應(yīng),引進(jìn)熔斷組件Hystrix俺榆,當(dāng)出現(xiàn)故障后會(huì)自動(dòng)剔除服務(wù)實(shí)列感昼。Hystrix除了一些基本的熔斷器,還能實(shí)現(xiàn)服務(wù)降級(jí)罐脊、服務(wù)限流的功能定嗓,并提供了界面展示健康狀態(tài)的功能。本章講訴如何使用RestTemplate和Feign消費(fèi)服務(wù)是使用Hystrix萍桌,并介紹Hystrix的工作原理宵溅。
Hystrix的設(shè)計(jì)原則
- 防止單個(gè)服務(wù)的故障耗盡整個(gè)服務(wù)的Servlet容器(如Tomcat)的線程池資源。
- 快速失敗機(jī)制上炎,如果某個(gè)服務(wù)出現(xiàn)了故障恃逻,則調(diào)用該服務(wù)的請(qǐng)求快速失敗,而不是線程等待藕施。
- 提供回退方案寇损,在請(qǐng)求發(fā)生故障時(shí),提供設(shè)定好的回退方案铅碍。
- 使用熔斷器機(jī)制润绵,防止故障擴(kuò)散到其他的服務(wù)。
- 提供熔斷器的監(jiān)控組件Hystrix Dashboard胞谈,可以實(shí)時(shí)監(jiān)控熔斷器的狀態(tài)尘盼。
Hystrix的工作機(jī)制
當(dāng)服務(wù)的某個(gè)API接口的失敗次數(shù)在一定時(shí)間內(nèi)小于設(shè)定的閾值時(shí),熔斷器處于關(guān)閉狀態(tài)烦绳,該API接口正常提供服務(wù)卿捎。當(dāng)該API接口處理請(qǐng)求的失敗次數(shù)大于設(shè)定的閾值時(shí),Hystrix判定該API接口出現(xiàn)了故障径密,打開(kāi)熔斷器午阵,這時(shí)該API接口會(huì)執(zhí)行快速失敗的邏輯,不執(zhí)行業(yè)務(wù)邏輯,請(qǐng)求的線程不會(huì)處于阻塞狀態(tài)底桂。處于打開(kāi)狀態(tài)的熔斷器在一定時(shí)間后會(huì)處于半打開(kāi)狀態(tài)植袍,并將一定數(shù)量的請(qǐng)求執(zhí)行正常邏輯,剩余的請(qǐng)求會(huì)執(zhí)行快速失敗籽懦。若執(zhí)行正常邏輯的請(qǐng)求失敗了于个,則熔斷器繼續(xù)打開(kāi),若成功了暮顺,則熔斷器關(guān)閉厅篓。這樣熔斷器就具有了自我修復(fù)的功能。
在RestTemplate上使用熔斷器
本章案例在前面章節(jié)的案例基礎(chǔ)之上進(jìn)行改造捶码。在講述ribbon章節(jié)時(shí)羽氮,eureka-ribbon-client工程中我們使用RestTemplate調(diào)用了eureka-client的“/hi”接口,并用Ribbon做了負(fù)載均衡惫恼,現(xiàn)在在此基礎(chǔ)上加Hystrix熔斷器的功能档押。
- 添加Hystrix的起步依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
- 在啟動(dòng)類上添加@EnableHystrix注解開(kāi)啟Hystrix的熔斷器功能。
@SpringBootApplication
@EnableEurekaClient
@EnableHystrix
@EnableHystrixDashboard
public class EurekaRibbonClientApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaRibbonClientApplication.class, args);
}
}
- 修該RibbonService的代碼尤筐,在方法中加上@HystrixCommand注解汇荐。有了@HystrixCommand方法就用Hystrix熔斷器的功能洞就,其中盆繁,fallbackMethod為處理回退邏輯的方法,在本例中旬蟋,直接返回了一個(gè)字符串油昂。在熔斷器打開(kāi)的狀態(tài)下,會(huì)執(zhí)行回退邏輯倾贰∶岬回退邏輯最好是返回一些靜態(tài)的字符串,不需要處理復(fù)雜的邏輯匆浙,也不需要遠(yuǎn)程調(diào)用其它的服務(wù)安寺,這樣能執(zhí)行快速失敗,釋放線程資源首尼。如果在回退邏輯中一定要調(diào)用遠(yuǎn)程服務(wù)挑庶,最好在遠(yuǎn)程調(diào)度其它的服務(wù)時(shí),也加上熔斷器软能。
public class RibbonServiceHystrix {
@Autowired
private RestTemplate restTemplate;
@HystrixCommand(fallbackMethod = "hiError")
public String hiFromClient() {
return restTemplate.getForObject("http://eureka-client/hi?name=dzy", String.class);
}
public String hiError(){
return "error";
}
}
- 啟動(dòng)eureka-server和eureka-ribbon-client迎捺。此時(shí)沒(méi)有啟動(dòng)eureka-client,所以eureka-ribbon-client肯定是訪問(wèn)不通eureka-client接口的查排。此時(shí)訪問(wèn)http://localhost:8765/hi,瀏覽器會(huì)顯示回退邏輯返回的錯(cuò)誤字符串凳枝。做到了快速失敗,線程不在阻塞跋核。
在Feign上使用熔斷器
- 之前介紹Feign提到本身已經(jīng)集成了熔斷器的功能岖瑰,F(xiàn)eign的起步依賴已經(jīng)引入了Hystrix的依賴叛买,所以不需要在pom文件中添加Hystrix的依賴。只需要在配置文件中開(kāi)啟Hystrix功能即可蹋订。
feign:
hystrix:
enabled: true
- 在聲明式接口中的@FeignClient注解上添加fallback屬性來(lái)配置快速失敗的處理類聪全。該處理類作為Feign熔斷器的邏輯處理類,必須實(shí)現(xiàn)被@FeignClient修飾的接口辅辩,最后需要以Spring Bean的形式注入IoC容器中难礼。
@FeignClient(value = "eureka-client", configuration = FeignClientConfig.class,fallback = HiFailBack.class)
public interface HiFeignClient {
@GetMapping("/hi")
String hi(@RequestParam(value = "name") String name);
}
@Component
public class HiFailBack implements HiFeignClient {
@Override
public String hi(String name) {
return "hystrix error";
}
}
- 啟動(dòng)eureka-server,eureka-feign-client玫锋,此時(shí)沒(méi)有啟動(dòng)eureka-client蛾茉,所以eureka-feign-client接口調(diào)用eureka-client的接口是肯定連接不通的。在瀏覽器訪問(wèn)eureka-feign-client接口撩鹿,瀏覽器會(huì)出現(xiàn)配置的錯(cuò)誤字符串谦炬,說(shuō)明實(shí)現(xiàn)了快速失敗。
使用Hystrix Dashboard監(jiān)控熔斷器的狀態(tài)
Hystrix Dashboard 是監(jiān)控Hystrix的熔斷狀況的一個(gè)組件节沦,提供了數(shù)據(jù)監(jiān)控和友好的圖形化展示界面键思。
在RestTemplate中使用Hystrix Dashboard
在eureka-ribbon-client的基礎(chǔ)上改造。
- 在pom文件中加上Actuator的起步依賴甫贯,Hystrix Dashboard的起步依賴吼鳞。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
</dependency>
- 在啟動(dòng)類上加上@EnableHystrixDashboard開(kāi)啟Hystrix Dashboard的功能。
@SpringBootApplication
@EnableEurekaClient
@EnableHystrix
@EnableHystrixDashboard
public class EurekaRibbonClientApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaRibbonClientApplication.class, args);
}
}
- 依此啟動(dòng)eureka-server叫搁,eureka-client和eureka-ribbon-client(我的端口為8765)赔桌,確定兩個(gè)eureka client已經(jīng)注冊(cè)到了eureka server中。
在瀏覽器訪問(wèn)http://localhost:8765/hystrix,會(huì)出現(xiàn)Hystrix Dashboard的界面渴逻。
在界面中依此填寫(xiě)http://localhost:8765/hystrix.stream疾党,200,forezp(任意填寫(xiě))惨奕,點(diǎn)擊“monitor”雪位,進(jìn)入界面
監(jiān)控圖中用圓點(diǎn)來(lái)表示服務(wù)的健康狀態(tài),健康度從100%-0%分別會(huì)用綠色梨撞、黃色雹洗、橙色、紅色來(lái)表示聋袋。 另外队伟,這個(gè)圓點(diǎn)也會(huì)隨著流量的增多而變大。 監(jiān)控圖中會(huì)用曲線(圓點(diǎn)旁邊)來(lái)表示服務(wù)的流量情況幽勒,通過(guò)這個(gè)曲線可以觀察單個(gè)接口的流量變化/趨勢(shì)嗜侮。對(duì)應(yīng)的指標(biāo)含義如下
在feign中使用Hystrix Dashboard
- 添加Actuator,Hystrix,Hystrix Dashboard的起步依賴。這里需要注意,既然Feign自帶Hystrix,那為什么還需要引入spring-cloud-starter-hystrix?這是因?yàn)镕eign自帶的是Hystrix的依賴不是Hystrix起步依賴锈颗。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
- 在啟動(dòng)類上加上@EnableHystrixDashboard開(kāi)啟Hystrix Dashboard的功能顷霹。
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
@EnableHystrixDashboard
@EnableHystrix
public class EurekaFeignClientApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaFeignClientApplication.class, args);
}
}
只需要上述兩步就可以在Feign中開(kāi)啟Hystrix Dashboard的功能。
使用Turbine聚合監(jiān)控
在使用Hystrix Dashboard組件監(jiān)控服務(wù)的熔斷狀況時(shí)击吱,每個(gè)服務(wù)都有一個(gè)Hystrix Dashboard主頁(yè)淋淀,當(dāng)服務(wù)數(shù)量很多時(shí),監(jiān)控非常不方便覆醇。為了同時(shí)監(jiān)控多個(gè)服務(wù)的熔斷器的狀況朵纷,Netflix開(kāi)源了Hystrix另一個(gè)組件Turbine。Turbine用于聚合多個(gè)Hystrix Dashboard永脓,將多個(gè)Hystrix Dashboard組件的數(shù)據(jù)放在一個(gè)頁(yè)面上展示袍辞,進(jìn)行集中監(jiān)控。
- 新建一個(gè)Module工程常摧,取名為turbine-server搅吁,在pom中添加turbine,actuator,test的起步依賴落午。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-turbine</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
- 在配置文件application加上相關(guān)的配置谎懦。
server:
port: 8770
spring:
application:
name: turbine-server
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
management:
security:
enabled: false
turbine:
app-config: eureka-ribbon-client,eureka-feign-client
cluster-name-expression: new String("default")
aggregator:
clusterConfig: default
其中turbine.app-config配置了需要監(jiān)控的服務(wù)名,turbine.cluster-name-expression默認(rèn)為服務(wù)器的集群溃斋,此時(shí)用默認(rèn)的即可界拦。turbine.aggregator.clusterConfig可以不寫(xiě),因?yàn)槟J(rèn)就是default盐类。
- 啟動(dòng)類上添加@EnableTurbine注解寞奸,啟動(dòng)Turbine功能
@SpringBootApplication
@EnableEurekaClient
@EnableTurbine
public class TurbineServerApplication {
public static void main(String[] args) {
SpringApplication.run(TurbineServerApplication.class, args);
}
}
- 啟動(dòng)eureka-server,eureka-ribbon-client在跳,eureka-feign-client,turbine-server
在瀏覽器訪問(wèn)http://localhost:8765/hystrix,在這個(gè)界面為eureka-ribbon-client的
Hystrix Dashboard界面(用其它服務(wù)的Hystrix Dashboard也可,只要監(jiān)控流為turbine服務(wù)器地址就行隐岛,但在項(xiàng)目中只會(huì)啟用一個(gè)服務(wù)的Hystrix Dashboard)猫妙,在界面中依此輸入監(jiān)控流的Url地址http://localhost:8770/turbine.stream,監(jiān)控時(shí)間間隔為2000毫秒和title聚凹,點(diǎn)擊“monitor”割坠,可以看到如下界面。
可以看到這個(gè)界面同時(shí)聚合了eureka-ribbon-client和eureka-feign-client的Hystrix Dashboard妒牙。
總結(jié)
在這一章學(xué)習(xí)了熔斷器Hystrix彼哼,其中包括什么是Hystrix,Hystrix的工作原理湘今,TestTemplate敢朱、Feign結(jié)合Hystrix的使用。最后介紹使用圖形化監(jiān)控組件Hystrix Dashboard,以及監(jiān)控聚合組件Turbine拴签。在下一章中介紹路由網(wǎng)關(guān)Zuul孝常。
PS:項(xiàng)目github地址:https://github.com/dzydzydzy/spring-cloud-example.git