上一篇 <<<后端服務(wù)的雪崩效應(yīng)及解決思路
下一篇 >>>服務(wù)限流之計(jì)數(shù)器方式
1.服務(wù)隔離、降級和熔斷的產(chǎn)生背景
tomcat底層都會共享一個線程池(自己創(chuàng)建的例外),當(dāng)某個方法(服務(wù))訪問非常慢造成響應(yīng)延遲,會造成大多數(shù)線程阻塞冯勉,導(dǎo)致整個線程池被占用甚至拖垮澈蚌。
線程名定義:線程池名稱+線程ID
2.服務(wù)隔離解決思路
2.1 線程池隔離
不同的http服務(wù)使用不同的線程池,當(dāng)自己的資源用完灼狰,直接返回失敗而不是占用別人的資源
優(yōu)點(diǎn):可提高并發(fā)性
缺點(diǎn):增加CPU調(diào)度開銷
使用場景:第三方應(yīng)用或接口宛瞄;并發(fā)量大
2.2 信號量隔離
原子計(jì)數(shù)器方式記錄當(dāng)前運(yùn)行的線程數(shù),超過則拒絕交胚,不超過則+1份汗,返回則-1
使用場景:內(nèi)部應(yīng)用或中間件;并發(fā)需求不大
區(qū)別:信號量可動態(tài)調(diào)整蝴簇,但線程池不可以調(diào)整
3.服務(wù)降級
當(dāng)服務(wù)不可用(服務(wù)正在等待杯活、鏈接超時、網(wǎng)絡(luò)延遲熬词、服務(wù)器響應(yīng)慢等)旁钧,客戶端一直等待時,調(diào)用fallback方法給客戶端返回一個錯誤提示互拾,不讓客戶端繼續(xù)等待歪今。
目的:提高用戶體驗(yàn),防止雪崩效應(yīng)颜矿。
4.服務(wù)熔斷
熔斷和保險絲一樣寄猩,當(dāng)訪問請求過多的時候,達(dá)到一個閾值(自己設(shè)置)就直接拒絕訪問骑疆,可以保護(hù)當(dāng)前服務(wù)田篇,讓服務(wù)不會被掛掉,需要和服務(wù)降級一起使用封断。
<dependencies>
<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-metrics-event-stream</artifactId>
<version>1.5.12</version>
</dependency>
<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-javanica</artifactId>
<version>1.5.12</version>
</dependency>
</dependencies>
public class OrderHystrixCommand extends HystrixCommand<JSONObject> {
@Autowired
private MemberService memberService;
public OrderHystrixCommand(MemberService memberService) {
super(setter());
this.memberService = memberService;
}
@Override
protected JSONObject run() throws Exception {
JSONObject member = memberService.getMember();
System.out.println("當(dāng)前線程名稱:" + Thread.currentThread().getName() + ",訂單服務(wù)調(diào)用會員服務(wù):member:" + member);
return member;
}
/**
* 使用線程池方式解決隔離
* @return
*/
private static Setter setter() {
// 服務(wù)分組
HystrixCommandGroupKey groupKey = HystrixCommandGroupKey.Factory.asKey("members");
// 服務(wù)標(biāo)識
HystrixCommandKey commandKey = HystrixCommandKey.Factory.asKey("member");
// 線程池名稱
HystrixThreadPoolKey threadPoolKey = HystrixThreadPoolKey.Factory.asKey("member-pool");
// #####################################################
// 線程池配置 線程池大小為10,線程存活時間15秒 隊(duì)列等待的閾值為100,超過100執(zhí)行拒絕策略
HystrixThreadPoolProperties.Setter threadPoolProperties = HystrixThreadPoolProperties.Setter().withCoreSize(10)
.withKeepAliveTimeMinutes(15).withQueueSizeRejectionThreshold(100);
// ########################################################
// 命令屬性配置Hystrix 開啟超時
HystrixCommandProperties.Setter commandProperties = HystrixCommandProperties.Setter()
// 采用線程池方式實(shí)現(xiàn)服務(wù)隔離
.withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.THREAD)
// 禁止
.withExecutionTimeoutEnabled(false);
return HystrixCommand.Setter.withGroupKey(groupKey).andCommandKey(commandKey).andThreadPoolKey(threadPoolKey)
.andThreadPoolPropertiesDefaults(threadPoolProperties).andCommandPropertiesDefaults(commandProperties);
}
/**
* 服務(wù)降級
* @return
*/
@Override
protected JSONObject getFallback() {
// 如果Hystrix發(fā)生熔斷斯辰,當(dāng)前服務(wù)不可用,直接執(zhí)行Fallback方法
System.out.println("系統(tǒng)錯誤!");
JSONObject jsonObject = new JSONObject();
jsonObject.put("code", 500);
jsonObject.put("msg", "系統(tǒng)錯誤坡疼!");
return jsonObject;
}
}
使用:
/**
* 線程池方式解決
* @return
* @throws InterruptedException
*/
@RequestMapping("/orderIndexHystrix")
public Object orderIndexHystrix() throws InterruptedException {
return new OrderHystrixCommand(memberService).execute();
}
信號量方式 和線程池方式也就setter方法不一致彬呻,其他的均一致
/**
* 使用信號量解決隔離
* @return
*/
private static Setter setter() {
// 服務(wù)分組
HystrixCommandGroupKey groupKey = HystrixCommandGroupKey.Factory.asKey("members");
// 命令屬性配置 采用信號量模式
HystrixCommandProperties.Setter commandProperties = HystrixCommandProperties.Setter()
.withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.SEMAPHORE)
// 使用一個原子計(jì)數(shù)器(或信號量)來記錄當(dāng)前有多少個線程在運(yùn)行,當(dāng)請求進(jìn)來時先判斷計(jì)數(shù)
// 器的數(shù)值柄瑰,若超過設(shè)置的最大線程個數(shù)則拒絕該請求闸氮,若不超過則通行,這時候計(jì)數(shù)器+1教沾,請求返 回成功后計(jì)數(shù)器-1蒲跨。
.withExecutionIsolationSemaphoreMaxConcurrentRequests(50);
return HystrixCommand.Setter.withGroupKey(groupKey).andCommandPropertiesDefaults(commandProperties);
}
推薦閱讀:
<<<高并發(fā)架構(gòu)的整體思路
<<<一個網(wǎng)站訪問慢的真正原因
<<<高并發(fā)情況下,接口的代碼會存在哪些問題
<<<壓縮靜態(tài)資源減少帶寬傳輸?shù)姆绞?/a>
<<<動靜分離架構(gòu)模式
<<<緩存策略匯總
<<<后端服務(wù)的雪崩效應(yīng)及解決思路
<<<服務(wù)限流之計(jì)數(shù)器方式
<<<服務(wù)限流之滑動窗口計(jì)數(shù)
<<<服務(wù)限流之令牌桶算法
<<<服務(wù)限流之漏桶算法
<<<漏桶算法和令牌桶算法的區(qū)別
<<<自定義封裝限流算法
<<<應(yīng)用級限流
<<<接入層限流