SpringCloud斷路器Hystrix原理及用法解析
這篇文章主要介紹了SpringCloud斷路器Hystrix原理及用法解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
在分布式環(huán)境中,許多服務(wù)依賴項(xiàng)中的一些必然會(huì)失敗。Hystrix是一個(gè)庫(kù),通過(guò)添加延遲容忍和容錯(cuò)邏輯,幫助你控制這些分布式服務(wù)之間的交互。Hystrix通過(guò)隔離服務(wù)之間的訪問(wèn)點(diǎn)、停止級(jí)聯(lián)失敗和提供回退選項(xiàng)來(lái)實(shí)現(xiàn)這一點(diǎn),所有這些都可以提高系統(tǒng)的整體彈性
兩個(gè)比較重要的類
- HystrixCommand
- HystrixObservableCommand
注解@HystrixCommand(fallbackMethods="methods")methods中可以添加降級(jí)策略
除了提供服務(wù)降級(jí)
還提供了請(qǐng)求緩存
- @CacheResult
- @CacheRemve
不過(guò)添加CacheResult的時(shí)候,說(shuō)
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.
在同一用戶請(qǐng)求的上下文中,相同依賴服務(wù)的返回?cái)?shù)據(jù)始終保持一致。在當(dāng)次請(qǐng)求內(nèi)對(duì)同一個(gè)依賴進(jìn)行重復(fù)調(diào)用,只會(huì)真實(shí)調(diào)用一次。在當(dāng)次請(qǐng)求內(nèi)數(shù)據(jù)可以保證一致性。
初始化是在filter中進(jìn)行(官方建議),但是每一次請(qǐng)求都會(huì)進(jìn)行初始化 。所以說(shuō)和一般的緩存還是有去別的,可以解決高并發(fā),保證的資源的線程安全。在某些場(chǎng)景很有用。
請(qǐng)求合并
/** * 建議: 服務(wù)提供方有較高的延遲??梢钥紤]使用請(qǐng)求合并 * HystrixCollapser 合并請(qǐng)求的時(shí)候會(huì)創(chuàng)建一個(gè)請(qǐng)求處理器。如果每次合并的請(qǐng)求量不大,只有很少的請(qǐng)求還要合并,會(huì)造成合并時(shí)間窗 * 并發(fā)量增大,時(shí)間窗的創(chuàng)建和消耗增大。所以只有在時(shí)間窗內(nèi)有很大的并發(fā)量,推薦請(qǐng)求合并。 * * batchMethod 請(qǐng)求合并后的替換方法com.gitee.munan56.cloud.hystrixconsumer.AService#findALl(java.util.List) 注意客戶端要有這個(gè)方法 *HystrixProperty 一個(gè)屬性合并時(shí)間窗100s 這個(gè)時(shí)間結(jié)束后會(huì)發(fā)起請(qǐng)求,也就是指這個(gè)時(shí)間是合并處理的時(shí)間 * @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 請(qǐng)求緩存(針對(duì)request的緩存),官方建議在serverlet filter 中初始化HystrixRequestContext * 在同一用戶請(qǐng)求的上下文中緩存在統(tǒng)一請(qǐng)求的上下文環(huán)境中有效。 * @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(); } /** * 建議: 服務(wù)提供方有較高的延遲??梢钥紤]使用請(qǐng)求合并 * HystrixCollapser 合并請(qǐng)求的時(shí)候會(huì)創(chuàng)建一個(gè)請(qǐng)求處理器。如果每次合并的請(qǐng)求量不大,只有很少的請(qǐng)求還要合并,會(huì)造成合并時(shí)間窗 * 并發(fā)量增大,時(shí)間窗的創(chuàng)建和消耗增大。所以只有在時(shí)間窗內(nèi)有很大的并發(fā)量,推薦請(qǐng)求合并。 * * batchMethod 請(qǐng)求合并后的替換方法com.gitee.munan56.cloud.hystrixconsumer.AService#findALl(java.util.List) 注意客戶端要有這個(gè)方法 *HystrixProperty 一個(gè)屬性合并時(shí)間窗100s 這個(gè)時(shí)間結(jié)束后會(huì)發(fā)起請(qǐng)求,也就是指這個(gè)時(shí)間是合并處理的時(shí)間 * @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(); } @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(); } /** * 服務(wù)降級(jí) * 指定調(diào)用服務(wù)出錯(cuò)的回調(diào)方法 * @return */ public String error(Throwable e){ return "do provider error this is default result" + "the error is " + e.getMessage(); } /** * 服務(wù)降級(jí) * 指定調(diào)用服務(wù)出錯(cuò)的回調(diào)方法 * @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; } }
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
java實(shí)現(xiàn)簡(jiǎn)單租車系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)簡(jiǎn)單租車系統(tǒng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-01-01java實(shí)現(xiàn)簡(jiǎn)單貪吃蛇小游戲
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)簡(jiǎn)單貪吃蛇小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-05-05Spring MVC全局異常處理和單元測(cè)試_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
本篇文章主要介紹了Spring MVC全局異常處理和單元測(cè)試,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08SpringBoot?模板模式實(shí)現(xiàn)優(yōu)惠券邏輯的示例代碼
這篇文章主要介紹了SpringBoot?模板模式實(shí)現(xiàn)優(yōu)惠券邏輯,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-08-08Mybatis使用@Select注解sql中使用in問(wèn)題
這篇文章主要介紹了Mybatis使用@Select注解sql中使用in問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-05-05