spring cloud: Hystrix(二):簡單使用@HystrixCommand的commandProperties配置@HistrixProperty隔離策略

spring cloud: Hystrix(二):簡單使用@HystrixCommand的commandProperties配置@HistrixProperty隔離策略spring

某電子商務網站在一個黑色星期五發生過載.過多的併發請求,致使用戶支付的請求延遲好久沒有響應,在等待很長時間後最終失敗。支付失敗又致使用戶從新刷新頁面並再次嘗試支付,進一步增長了服務器的負載,最終整個系統都崩潰了。服務器

 

斷路器模式
一個遠程調用對應着一個線程/進程。若是響應太慢,這個線程/進程就得不到釋放。資源就會被耗盡,最終致使服務不可用。
斷路器能夠理解爲對容易致使錯誤的操做的代理。這種代理可以統計一段時間內調用失敗的次數,並決定是正常請求依賴的服務仍是直接返回。
斷路器能夠實現快速失敗,當它在一段時間內檢測到許多相似的錯誤(例如超時),就會在以後的一段時間內,強迫對該服務的調用快速失敗,即再也不請求所依賴的服務。這樣,應用程序就不須浪費CPU時間去等待長時間的超時。
斷路器也能夠自動診斷依賴的服務是否已經恢復正常。網絡

正常狀況下斷路器關閉,可正常請求依賴的服務。
當一段時間內,請求失敗率達到必定閾值,斷路器就會打開。此時,不會再去請求依賴的服務。
斷路器打開一段時間後,會自動進入‘半開’狀態。此時,斷路器可容許一個請求訪問依賴的服務。若是請求可以調用成功,則關閉斷路器;不然繼續保持打開狀態。

  

Hystrix線程隔離策略與傳播上下文

Hystrix的隔離策略兩種: 分別是線程隔離和信號量隔離。併發

THREAD(線程隔離):使用該方式,HystrixCommand將會在單獨的線程上執行,併發請求受線程池中線程數量的限制。
SEMAPHORE(信號量隔離):使用該方式,HystrixCommand將會在調用線程上執行,開銷相對較小,併發請求受到信號量個數的限制。
Hystrix中默認而且推薦使用線程隔離(THREAD),由於這種方式有一個除網絡超時之外的額外保護。
通常來講,只有當調用負載異常高時(例如每一個實例每秒調用數百次)才須要信號量隔離,由於這種場景下使用THREAD開銷會比較高。信號量隔離通常僅適用於非網絡調用的隔離。
可使用execution.isolation.strategy屬性指定隔離策略。
正常狀況下,默認爲線程隔離, 保持默認便可。
若是發生找不到上下文運行時異常,可考慮將隔離策略設置爲SEMAPHORE。app

Feign使用Hystrix
前面講的是使用註解@HystrixCommand的fallbackMethod屬性實現回退的。然而,Feign是以接口形式工做的,它沒有方法體。

spring-boot

q請看例文網站

@RestController
public class MovieController {

	@Autowired
	private RestTemplate restTemplate;	
	
	
	@GetMapping("/movie/{id}")
	@HystrixCommand(fallbackMethod = "notfindback", commandProperties=@HystrixProperty(name="execution.isolation.strategy", value="SEMAPHORE") )
	public User findById(@PathVariable Long id)
	{
		//http://localhost:7900/simple/
		return restTemplate.getForObject("http://spring-boot-user/simple/" + id, User.class);
	}
	
	public User notfindback(Long id)
	{
		User user = new User();
		user.setId(0L);
		return user;
		
	}
	
}

  

這一段代碼:spa

@GetMapping("/movie/{id}")
	@HystrixCommand(fallbackMethod = "notfindback", commandProperties=@HystrixProperty(name="execution.isolation.strategy", value="SEMAPHORE") )
	public User findById(@PathVariable Long id)
	{
		//http://localhost:7900/simple/
		return restTemplate.getForObject("http://spring-boot-user/simple/" + id, User.class);
	}

  

若是不加@HystrixCommand的commandProperties=@HystrixProperty註解配置,那麼:restTemplate.getForObject()請求是一個線程;@HystrixCommand()是一個隔離線程。線程

加上@HystrixCommand的commandProperties=@HystrixProperty註解配置後,將2個線程合併到一個線程裏。代理

相關文章
相關標籤/搜索