成都創(chuàng)新互聯(lián)從2013年成立,先為尼開(kāi)遠(yuǎn)等服務(wù)建站,尼開(kāi)遠(yuǎn)等地企業(yè),進(jìn)行企業(yè)商務(wù)咨詢服務(wù)。為尼開(kāi)遠(yuǎn)企業(yè)網(wǎng)站制作PC+手機(jī)+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問(wèn)題。
//構(gòu)造setter
HystrixCommandGroupKey groupKey = HystrixCommandGroupKey.Factory.asKey(group);
HystrixThreadPoolKey threadPoolKey = HystrixThreadPoolKey.Factory.asKey(group);
HystrixCommandKey commandKey = HystrixCommandKey.Factory.asKey(service);
HystrixCommandProperties.Setter commandPropertiesDefaults = HystrixCommandProperties.Setter()
.withExecutionTimeoutInMilliseconds(100)
.withCircuitBreakerForceOpen(true);
HystrixThreadPoolProperties.Setter threadPoolPropertiesDefaults = HystrixThreadPoolProperties.Setter()
.withCoreSize(10)
.withQueueSizeRejectionThreshold(10);
HytrixCommand.Setter setter = HytrixCommand.Setter.withGroupKey(groupKey)
.andCommandKey(commandKey)
.andThreadPoolKey(threadPoolKey);
.andCommandPropertiesDefaults(commandPropertiesDefaults)
.andThreadPoolPropertiesDefaults(threadPoolPropertiesDefaults);
//構(gòu)造command
HystrixCommand
protected String run() throws Exception {
logger.info("##################### in hystrix thread");
Thread.sleep(time);
if(isException)
throw new RuntimeException("exception in run");
return service+ ":return";
}
@Override
protected String getFallback() {
logger.info("##################### in request thread");
return service+":fallback";
}
};
1 HystrixCommandKey
Hystrix使用單例模式存儲(chǔ)HystrixCommand,熔斷機(jī)制就是根據(jù)單實(shí)例上的調(diào)用情況統(tǒng)計(jì)實(shí)現(xiàn)的,所以每個(gè)HystrixCommand要有自己的名字,用于區(qū)分,同時(shí)用于依賴調(diào)用的隔離。HystrixCommandKey就是用于定義這個(gè)名字,如果沒(méi)有定義這個(gè)名字,Hystrix會(huì)使用其類(lèi)名作為其名字,可以使用HystrixCommandKey.Factory.asKey(String name)方法定義一個(gè)名稱。
2 HystrixThreadPoolKey
HystrixThreadPoolKey是HystrixCommand所在的線程池,如果該參數(shù)不設(shè)置則使用HystrixCommandGroupKey作為HystrixThreadPoolKey,這種情況下同一個(gè)HystrixCommandGroupKey下的依賴調(diào)用共用同一個(gè)線程池內(nèi),如果不想共用同一個(gè)線程池,則需要設(shè)置該參數(shù)。可以使用HystrixThreadPoolKey.Factory.asKey(String name)方法設(shè)置。
3 HystrixCommandGroupKey
Hystrix需要對(duì)HystrixCommand進(jìn)行分組,便于統(tǒng)計(jì)、管理,所以需要一個(gè)分組名稱,HystrixCommandGroupKey就是用于定義分組名稱,可以使用HystrixCommandGroupKey.Factory.asKey(String name)方法定義一個(gè)分組名。每個(gè)HystrixCommand必須要配置一個(gè)分組名,一個(gè)是用于分組,還有如果沒(méi)有配置HystrixThreadPoolKey,這個(gè)分組名將會(huì)用于線程池名。
4 HystrixThreadPoolProperties
從名稱上可以看出這是線程池的屬性配置,可以通過(guò)它設(shè)置核心線程數(shù)大小、最大線程數(shù)、任務(wù)隊(duì)列大小等,當(dāng)然它也又一些默認(rèn)的配置參數(shù)。
5 HystrixCommandProperties
這個(gè)就是HystrixCommand的屬性配置,它可以設(shè)置熔斷器是否可用、熔斷器熔斷的錯(cuò)誤百分比、依賴調(diào)用超時(shí)時(shí)間等,它有一些默認(rèn)的配置參數(shù),如熔斷器熔斷的錯(cuò)誤百分比默認(rèn)值是50%、依賴調(diào)用超時(shí)時(shí)間默認(rèn)值是1000毫秒。
這里只講注解的使用方式以及比較重要的部分,如果需要了解全部查看:https://github.com/Netflix/Hystrix/wiki/How-To-Use
public class UserService { ... @HystrixCommand public User getUserById(String id) { return userResource.getUserById(id); } } |
public class UserService { ... @HystrixCommand public Future final String id) { return new AsyncResult @Override public User invoke() { return userResource.getUserById(id); } }; } } |
@HystrixCommand public Observable final String id) { return Observable.create( new Observable.OnSubscribe @Override public void call(Subscriber super User> observer) { try { if (!observer.isUnsubscribed()) { observer.onNext( userResource.getUserById(id)); observer.onCompleted(); } } catch (Exception e) { observer.onError(e); } } }); } } |
同步執(zhí)行:當(dāng)執(zhí)行到注解方法時(shí),程序會(huì)順序執(zhí)行。
異步執(zhí)行:當(dāng)執(zhí)行到注解方法時(shí),會(huì)并發(fā)異步執(zhí)行,返回一個(gè)Future對(duì)象,后面使用.get()方法來(lái)阻塞拿到結(jié)果。如果有多個(gè)方法時(shí),執(zhí)行時(shí)間就是其中最長(zhǎng)的一個(gè)服務(wù)的執(zhí)行時(shí)間。
反應(yīng)執(zhí)行:當(dāng)執(zhí)行到注解方法時(shí),返回一個(gè)觀察者。支持EAGER和LAZY模式。和同步異步執(zhí)行的區(qū)別是,當(dāng)對(duì)多個(gè)方法之間的返回結(jié)果不需要做合并而是希望當(dāng)多個(gè)方法返回時(shí)觸發(fā)一些事件時(shí)比較適合使用該模式。
反應(yīng)執(zhí)行沒(méi)太明白,如果需要了解可以先參考下這個(gè)https://mcxiaoke.gitbooks.io/rxdocs/content/Intro.html
@HystrixCommand (fallbackMethod = "fallback1" ) User getUserById(String id) { throw new RuntimeException( "getUserById command failed" ); } @HystrixCommand (fallbackMethod = "fallback2" ) User fallback1(String id, Throwable e) { assert "getUserById command failed" .equals(e.getMessage()); throw new RuntimeException( "fallback1 failed" ); } @HystrixCommand (fallbackMethod = "fallback3" ) User fallback2(String id) { throw new RuntimeException( "fallback2 failed" ); } |
注意點(diǎn):
fallback應(yīng)該和注解方法在同一類(lèi)下
fallback的返回值和參數(shù)列表應(yīng)該和注解方法一致,如果需要異常,則在末尾添加Throwable參數(shù),對(duì)訪問(wèn)修飾符無(wú)要求
fallback方法上可以繼續(xù)添加fallback
command和fallback只支持以下幾種組合:
sync command, sync fallback
async command, sync fallback
async command, async fallback
@HystrixCommand (ignoreExceptions = {BadRequestException. class }) public User getUserById(String id) { return userResource.getUserById(id); } |
當(dāng)遇到BadRequestException時(shí)不會(huì)進(jìn)入fallback,而是直接拋出異常
@HystrixCommand (groupKey= "UserGroup" , commandKey = "GetUserByIdCommand" , commandProperties = { @HystrixProperty (name = "execution.isolation.thread.timeoutInMilliseconds" , value = "500" ) }, threadPoolProperties = { @HystrixProperty (name = "coreSize" , value = "30" ), @HystrixProperty (name = "maxQueueSize" , value = "101" ), @HystrixProperty (name = "keepAliveTimeMinutes" , value = "2" ), @HystrixProperty (name = "queueSizeRejectionThreshold" , value = "15" ), @HystrixProperty (name = "metrics.rollingStats.numBuckets" , value = "12" ), @HystrixProperty (name = "metrics.rollingStats.timeInMilliseconds" , value = "1440" ) }) |
參數(shù) | 作用 | 備注 |
---|---|---|
groupKey | 表示所屬的group,一個(gè)group共用線程池 | 默認(rèn)值:getClass().getSimpleName(); |
commandKey | 默認(rèn)值:當(dāng)前執(zhí)行方法名 | |
execution.isolation.strategy | 隔離策略,有THREAD和SEMAPHORE | 默認(rèn)使用THREAD模式,以下幾種可以使用SEMAPHORE模式:
|
execution.isolation.thread.timeoutInMilliseconds
| 超時(shí)時(shí)間 | 默認(rèn)值:1000 在THREAD模式下,達(dá)到超時(shí)時(shí)間,可以中斷 在SEMAPHORE模式下,會(huì)等待執(zhí)行完成后,再去判斷是否超時(shí) 設(shè)置標(biāo)準(zhǔn): 有retry,99meantime+avg meantime 沒(méi)有retry,99.5meantime |
execution.timeout.enabled | 是否打開(kāi)超時(shí) | |
execution.isolation.thread.interruptOnTimeout | 是否打開(kāi)超時(shí)線程中斷 | THREAD模式有效 |
execution.isolation.semaphore.maxConcurrentRequests | 信號(hào)量最大并發(fā)度 | SEMAPHORE模式有效,默認(rèn)值:10 |
fallback.isolation.semaphore.maxConcurrentRequests | fallback最大并發(fā)度 | 默認(rèn)值:10 |
circuitBreaker.requestVolumeThreshold | 熔斷觸發(fā)的最小個(gè)數(shù)/10s | 默認(rèn)值:20 |
circuitBreaker.sleepWindowInMilliseconds | 熔斷多少秒后去嘗試請(qǐng)求 | 默認(rèn)值:5000 |
circuitBreaker.errorThresholdPercentage | 失敗率達(dá)到多少百分比后熔斷 | 默認(rèn)值:50 主要根據(jù)依賴重要性進(jìn)行調(diào)整 |
circuitBreaker.forceClosed | 是否強(qiáng)制關(guān)閉熔斷 | 如果是強(qiáng)依賴,應(yīng)該設(shè)置為true |
coreSize | 線程池coreSize | 默認(rèn)值:10 設(shè)置標(biāo)準(zhǔn):qps*99meantime+breathing room |
maxQueueSize | 請(qǐng)求等待隊(duì)列 | 默認(rèn)值:-1 如果使用正數(shù),隊(duì)列將從SynchronizeQueue改為L(zhǎng)inkedBlockingQueue |