前景回顧:
《基于計數(shù)器的服務接口限流實例》
《基于RateLimiter的服務接口限流實例》
一设塔、Semaphore信號量的介紹
Semaphore是一種在多線程環(huán)境下使用的設(shè)施,該設(shè)施負責協(xié)調(diào)各個線程杆融,以保證它們能夠正確燃乍、合理的使用公共資源的設(shè)施唆樊,也是操作系統(tǒng)中用于控制進程同步互斥的量。
我們通常使用Semaphore來確保系統(tǒng)中的最大線程并發(fā)數(shù)量刻蟹。
二逗旁、使用信號量的acquire和release
我們在以下實例中,設(shè)置getUserMail
這個URL最多只能同時被兩個請求訪問舆瘪,其它請求要想訪問該URL片效,必須等待前面的請求釋放信號量才行。
@Slf4j
@RestController
public class UserMailRest {
/**
* 同一時刻最多只允許有兩個并發(fā)
*/
private Semaphore semaphore = new Semaphore(2);
@GetMapping("/getUserMail")
public String getUserMail() {
try {
// 獲取信號量的請求立即得到執(zhí)行英古,未獲取到信號量的請求需要等待
semaphore.acquire();
Thread.sleep(2000);
log.info("請求得到服務淀衣!");
return "OK";
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
// 請求結(jié)束后將信號量釋放供其它請求使用
semaphore.release();
}
return "fail";
}
}
我們使用Jmeter模擬10個用戶在1秒內(nèi)的并發(fā)請求該URL得到的結(jié)果如下:
2019-12-24 20:59:04.862: 請求得到服務!
2019-12-24 20:59:04.862: 請求得到服務召调!
2019-12-24 20:59:06.864: 請求得到服務膨桥!
2019-12-24 20:59:06.864: 請求得到服務!
2019-12-24 20:59:08.865: 請求得到服務某残!
2019-12-24 20:59:08.865: 請求得到服務国撵!
2019-12-24 20:59:10.867: 請求得到服務陵吸!
2019-12-24 20:59:10.867: 請求得到服務玻墅!
2019-12-24 20:59:12.869: 請求得到服務!
2019-12-24 20:59:12.869: 請求得到服務壮虫!
可以看出澳厢,該URL確實在同一時間最多只能供兩個請求訪問环础。
三、使用信號量的tryAcquire
和前面文章中提到的RateLimiter類似剩拢,Semaphore也有tryAcquire方法线得,用來拒絕單位時間內(nèi)超出的并發(fā)請求。
@Slf4j
@RestController
public class UserMailRest {
/**
* 同一時刻最多只允許有兩個并發(fā)
*/
private Semaphore semaphore = new Semaphore(2);
@GetMapping("/getUserMail")
public String getUserMail() {
if(!semaphore.tryAcquire()){
log.warn("調(diào)用太頻繁了徐伐,拒絕服務贯钩!");
return "調(diào)用太頻繁了,拒絕服務办素!";
}
try {
log.info("接受服務角雷!");
Thread.sleep(2000);
return "ok";
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
semaphore.release();
}
return "fail";
}
}
運行結(jié)果如下:
2019-12-24 21:15:16.034 : 接受服務!
2019-12-24 21:15:16.034 : 接受服務性穿!
2019-12-24 21:15:16.050 : 調(diào)用太頻繁了勺三,拒絕服務!
2019-12-24 21:15:16.149 : 調(diào)用太頻繁了需曾,拒絕服務吗坚!
2019-12-24 21:15:16.259 : 調(diào)用太頻繁了,拒絕服務呆万!
2019-12-24 21:15:16.352 : 調(diào)用太頻繁了商源,拒絕服務!
2019-12-24 21:15:16.455 : 調(diào)用太頻繁了谋减,拒絕服務炊汹!
2019-12-24 21:15:16.552 : 調(diào)用太頻繁了,拒絕服務逃顶!
2019-12-24 21:15:16.658 : 調(diào)用太頻繁了讨便,拒絕服務!
2019-12-24 21:15:16.754 : 調(diào)用太頻繁了以政,拒絕服務霸褒!
可以看出,與acquire的區(qū)別是盈蛮,超出的8個請求全部直接被拒絕了废菱,而不是一直等待信號量的釋放。
四抖誉、總結(jié)
Semaphore是比較常用的服務接口限流方案殊轴,它與計數(shù)器和RateLimiter比較最大的優(yōu)點是,能限制住接口的最大并發(fā)數(shù)袒炉,哪怕每一個請求都是Long Call旁理,也都不用害怕累計的并發(fā)線程會將服務器壓垮的問題了。
全文完我磁。