【Spring Cloud】Hystrix 斷路器

前言

     分佈式應用程序面臨着一些問題,會出現服務雪崩。多個微服務間調用的時候,假設微服務A調用微服務B,微服務B調用微服務C,即扇出。如果扇出的鏈路上某個微服務的調用響應時間過長或不可用,對微服務A的調用就會佔用越來越多的系統資源,進而引起系統的崩潰,即雪崩效應。

    而Spring Cloud Hystrix的出現便可以解決這種情況,Hystrix是一個用於處理分佈式系統的延遲和容錯的開源庫,在分佈式系統中,許多依賴不可避免調用失敗,如超時、異常等,Hystrix能夠保證在一個依賴出問題的情況下,不會導致整體服務失敗,避免級聯鼓掌,以提高分佈式系統的彈性。

Hystrix主要功能   

 一、Hystrix 斷路器

     一種開關裝置,當某個服務單元發生鼓掌後,通過斷路器的故障監控(類似熔斷保險絲),向調用方返回一個符合預期的、可處理的備選響應(FallBack),而不是長時間的等待或拋出無法處理的異常,這樣就保證了服務調用方的線程不會長時間、不必要佔用,從而避免了故障在分佈式系統中的蔓延,乃至雪崩。

二、服務熔斷

   一般是某個服務故障或者異常引起,類似現實世界中的保險絲,當某個異常條件被觸發,直接熔斷整個服務,而不是一直等到此服務超時。

三、服務降級

    降級,一般是從整體負荷考慮,當某個服務熔斷之後,服務器將不再被調用,此時客戶端可以自己準備一個本地的fallback回調,返回一個缺省值。

四、服務限流

    服務限流依賴於服務熔斷,當系統資源不夠,不足以應對大量請求,即系統資源與訪問量出現矛盾的時候,我們爲了保證優先的資源能夠正常服務,因此對系統按照預設的規則進行流量限制或功能限制。

    推薦文章 架構設計之「服務限流」

五、接近實時監控

     除了隔離依賴服務的調用以外,Hystrix還提供了準實時的調用監控(Hystrix DashBoard),Hystrix會持續地記錄所有通過Hystrix發起的請求的執行信息,並以統計報表和圖形的形式展現給用戶。如每秒執行多少請求,多少成功,多少失敗等。

搭建Hystrix項目模塊

一、創建服務提供者的Hystrix 模塊 -- microservicecloud-provider-dept-hystrix-8001

在之前 服務提供者模塊的基礎上,繼續添加Hystrix模塊。

1.引入pom.xml的依賴

<!-- hystrix -->
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>

 2.修改配置文件application.yml

 將instance-id的值修改了。

eureka:
  client: #客戶端註冊進eureka服務列表內
    service-url: 
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
  instance:
    instance-id: microservicecloud-dept8001-hystrix   #自定義hystrix相關的服務名稱信息
    prefer-ip-address: true     #訪問路徑可以顯示IP地址
    lease-renewal-interval-in-seconds: 5 # 租約續訂間隔時間(默認30秒),如下所示每間隔 5s 向服務端發送一次心跳,證明自己依然"存活"
    lease-expiration-duration-in-seconds: 10 # 租約到期時間(默認90秒),如下所示,告訴服務端如果我 10s 之內沒有給你發心跳,就代表我"死"了,將我踢出掉

3.修改 提供者模塊的controller 接口,並添加對應註解

@HystrixCommand 以及出現服務不可用的情況下,會調用自定義的方法processHystrix_Get

@RestController
public class DeptController
{
	@Autowired
	private DeptService service = null;

	@RequestMapping(value = "/dept/get/{id}", method = RequestMethod.GET)
	//一旦調用服務方法失敗並拋出了錯誤信息後,會自動調用@HystrixCommand標註好的fallbackMethod調用類中的指定方法
	@HystrixCommand(fallbackMethod = "processHystrix_Get")
	public Dept get(@PathVariable("id") Long id)
	{

		Dept dept = this.service.get(id);
		
		if (null == dept) {
			throw new RuntimeException("該ID:" + id + "沒有沒有對應的信息");
		}
		
		return dept;
	}

	public Dept processHystrix_Get(@PathVariable("id") Long id)
	{
		return new Dept().setDeptno(id).setDname("該ID:" + id + "沒有沒有對應的信息,null--@HystrixCommand")
				.setDb_source("no this database in MySQL");
	}
}

 4.效果演示

 輸入不存在的id

二、服務調用失敗處理--修改API層代碼 

1.添加一個實現了FallbackFactory接口的類DeptClientServiceFallbackFactory

 處理消費者調用提供者失敗的情況。

@Component // 不要忘記添加,不要忘記添加
public class DeptClientServiceFallbackFactory implements FallbackFactory<DeptClientService>
{
	@Override
	public DeptClientService create(Throwable throwable)
	{
		return new DeptClientService() {
			@Override
			public Dept get(long id)
			{
				return new Dept().setDeptno(id).setDname("該ID:" + id + "沒有沒有對應的信息,Consumer客戶端提供的降級信息,此刻服務Provider已經關閉")
						.setDb_source("no this database in MySQL");
			}

			@Override
			public List<Dept> list()
			{
				return null;
			}

			@Override
			public boolean add(Dept dept)
			{
				return false;
			}
		};
	}
}

2. 修改已經有的DeptClientService接口註解

   添加服務調用失敗,錯誤處理類DeptClientServiceFallbackFactory

//@FeignClient(value = "MICROSERVICECLOUD-DEPT")
@FeignClient(value = "MICROSERVICECLOUD-DEPT",fallbackFactory=DeptClientServiceFallbackFactory.class)
public interface DeptClientService
{
	@RequestMapping(value = "/dept/get/{id}", method = RequestMethod.GET)
	public Dept get(@PathVariable("id") long id);
}

3.修改消費者服務-microservicecloud-consumer-dept-feign的配置文件application.yml

 如果消費者服務不添加這個配置屬性,無法走服務熔斷的功能。

feign: 
  hystrix: 
    enabled: true

4. 演示效果

(1)消費端調用提供者服務,處理未查詢到的結果

(2)停掉提供者服務,消費端調用提供者服務時,服務出現熔斷,降級,調用指定的方法

小結

     服務降級,使用AOP織入,熔斷解耦,整體資源快不夠了,忍痛將某些服務先關掉,待度過難關,再開啓回來。服務降級處理是在客戶端實現完成的,與服務端沒有關係。

                                                                           感謝您的訪問!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章