SpringCloud斷路器Hystrix原理及用法解析
阿新 • • 發佈:2020-01-17
這篇文章主要介紹了SpringCloud斷路器Hystrix原理及用法解析,文中通過示例程式碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
在分散式環境中,許多服務依賴項中的一些必然會失敗。Hystrix是一個庫,通過新增延遲容忍和容錯邏輯,幫助你控制這些分散式服務之間的互動。Hystrix通過隔離服務之間的訪問點、停止級聯失敗和提供回退選項來實現這一點,所有這些都可以提高系統的整體彈性
兩個比較重要的類
- HystrixCommand
- HystrixObservableCommand
註解@HystrixCommand(fallbackMethods="methods")methods中可以新增降級策略
除了提供服務降級
還提供了請求快取
- @CacheResult
- @CacheRemve
不過新增CacheResult的時候,說
HystrixRequestContext未初始化。
2020-01-13 16:12:10.273 ERROR 15348 --- [nio-8083-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.reflect.UndeclaredThrowableException] with root cause java.lang.IllegalStateException: Request caching is not available. Maybe you need to initialize the HystrixRequestContext? at com.netflix.hystrix.HystrixRequestCache.get(HystrixRequestCache.java:104) ~[hystrix-core-1.5.18.jar:1.5.18] at com.netflix.hystrix.AbstractCommand$7.call(AbstractCommand.java:478) ~[hystrix-core-1.5.18.jar:1.5.18] at com.netflix.hystrix.AbstractCommand$7.call(AbstractCommand.java:454) ~[hystrix-core-1.5.18.jar:1.5.18] at rx.internal.operators.OnSubscribeDefer.call(OnSubscribeDefer.java:46) ~[rxjava-1.3.8.jar:1.3.8] at rx.internal.operators.OnSubscribeDefer.call(OnSubscribeDefer.java:35) ~[rxjava-1.3.8.jar:1.3.8]
檢視官方文件https://github.com/Netflix/Hystrix/wiki/How-To-Use
Typically this context will be initialized and shut down via a ServletFilter that wraps a user request or some other lifecycle hook.
在同一使用者請求的上下文中,相同依賴服務的返回資料始終保持一致。在當次請求內對同一個依賴進行重複呼叫,只會真實呼叫一次。在當次請求內資料可以保證一致性。
初始化是在filter中進行(官方建議),但是每一次請求都會進行初始化 。所以說和一般的快取還是有去別的,可以解決高併發,保證的資源的執行緒安全。在某些場景很有用。
請求合併
/** * 建議: 服務提供方有較高的延遲。可以考慮使用請求合併 * HystrixCollapser 合併請求的時候會建立一個請求處理器。如果每次合併的請求量不大,只有很少的請求還要合併,會造成合並時間窗 * 併發量增大,時間窗的建立和消耗增大。所以只有在時間窗內有很大的併發量,推薦請求合併。 * * batchMethod 請求合併後的替換方法com.gitee.munan56.cloud.hystrixconsumer.AService#findALl(java.util.List) 注意客戶端要有這個方法 *HystrixProperty 一個屬性合併時間窗100s 這個時間結束後會發起請求,也就是指這個時間是合併處理的時間 * @param id * @return */ @HystrixCollapser(batchMethod = "findALl",collapserProperties = @HystrixProperty(name = "timerDelayInMilliseconds",value = "100")) public String doBFindOne(String id){ System.out.println("begin do provider service"); return restTemplate.getForEntity("http://service-provider:8081/api/v1/provider/do",String.class).getBody(); }
全部程式碼
package com.gitee.munan56.cloud.hystrixconsumer; import com.netflix.hystrix.contrib.javanica.annotation.HystrixCollapser; import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty; import com.netflix.hystrix.contrib.javanica.cache.annotation.CacheResult; import com.netflix.hystrix.strategy.concurrency.HystrixRequestContext; import com.netflix.ribbon.proxy.annotation.Hystrix; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; import java.util.List; /** * @author munan * @version 1.0 * @date 2020/1/13 10:41 */ @Service public class AService { @Autowired private RestTemplate restTemplate; public String doAService(){ return "A Service is run"; } // @Hystrix(fallbackHandler = ) @HystrixCommand(fallbackMethod = "error") public String doBServiceOne(){ System.out.println("begin do provider service"); return restTemplate.getForEntity("http://service-provider:8081/api/v1/provider/do",String.class).getBody(); } /** * CacheResult 請求快取(針對request的快取),官方建議在serverlet filter 中初始化HystrixRequestContext * 在同一使用者請求的上下文中快取在統一請求的上下文環境中有效。 * @param id * @return */ @CacheResult(cacheKeyMethod = "getKey") @HystrixCommand(fallbackMethod = "error") public String doBServiceTwo(String id){ System.out.println("begin do provider service"); return restTemplate.getForEntity("http://service-provider:8081/api/v1/provider/do",String.class).getBody(); } /** * 建議: 服務提供方有較高的延遲。可以考慮使用請求合併 * HystrixCollapser 合併請求的時候會建立一個請求處理器。如果每次合併的請求量不大,只有很少的請求還要合併,會造成合並時間窗 * 併發量增大,時間窗的建立和消耗增大。所以只有在時間窗內有很大的併發量,推薦請求合併。 * * batchMethod 請求合併後的替換方法com.gitee.munan56.cloud.hystrixconsumer.AService#findALl(java.util.List) 注意客戶端要有這個方法 *HystrixProperty 一個屬性合併時間窗100s 這個時間結束後會發起請求,也就是指這個時間是合併處理的時間 * @param id * @return */ @HystrixCollapser(batchMethod = "findALl",String.class).getBody(); } @HystrixCommand() public String findALl(List<String> ids){ System.out.println("begin do provider service"); return restTemplate.getForEntity("http://service-provider:8081/api/v1/provider/do",String.class).getBody(); } /** * 服務降級 * 指定呼叫服務出錯的回撥方法 * @return */ public String error(Throwable e){ return "do provider error this is default result" + "the error is " + e.getMessage(); } /** * 服務降級 * 指定呼叫服務出錯的回撥方法 * @return */ public String error(String id,Throwable e){ return "do provider error this is default result" + "the error is " + e.getMessage(); } public String getKey(String id){ return id; } }
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。