分布式系统中的限流与熔断
在應對秒殺、大促、雙 11、618 等高性能壓力的場景時,限流已經成為了標配技術解決方案,為保證系統的平穩運行起到了關鍵性的作用。不管應用場景是哪種,限流無非就是針對超過預期的流量,通過預先設定的限流規則選擇性的對某些請求進行限流“熔斷”。
1. 限流
1.1 單機限流
a>>限制并發量
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Semaphore;public class SemaphoreTest {private static final int THREAD_COUNT = 30;private static ExecutorService threadPool = Executors.newFixedThreadPool(THREAD_COUNT);private static Semaphore s = new Semaphore(10);public static void main(String[] args) {for (int i = 0; i < THREAD_COUNT; i++) {threadPool.execute(new Runnable() {@Overridepublic void run() {try {s.acquire();System.out.println(Thread.currentThread().getName());Thread.sleep(5000);System.out.println("--------------");s.release();} catch (InterruptedException e) {}}});}threadPool.shutdown();} }b>>計數器,以CountDownLatch為例
import java.util.concurrent.CountDownLatch;public class CountDownLatchTest2 {public static void main(String[] args) {// 創建計數器,初始化為2final CountDownLatch latch = new CountDownLatch(2);new Thread(() -> {try {System.out.println("子線程"+Thread.currentThread().getName()+"正在執行");Thread.sleep(3000);System.out.println("子線程"+Thread.currentThread().getName()+"執行完畢");latch.countDown();// 減一} catch (InterruptedException e) {e.printStackTrace();}}).start();new Thread(() -> {try {System.out.println("子線程"+Thread.currentThread().getName()+"正在執行");Thread.sleep(3000);System.out.println("子線程"+Thread.currentThread().getName()+"執行完畢");latch.countDown();} catch (InterruptedException e) {e.printStackTrace();}}).start();try {System.out.println("等待2個子線程執行完畢...");// 阻塞 latch.await();System.out.println("2個子線程已經執行完畢");System.out.println("繼續執行主線程");} catch (InterruptedException e) {e.printStackTrace();}} }? ? ? ?c>>guava RateLimiter?
public void test() {/*** 創建一個限流器,設置每秒放置的令牌數:2個。速率是每秒可以2個的消息。* 返回的RateLimiter對象可以保證1秒內不會給超過2個令牌,并且是固定速率的放置。達到平滑輸出的效果*/RateLimiter r = RateLimiter.create(2);while (true){/*** acquire()獲取一個令牌,并且返回這個獲取這個令牌所需要的時間。如果桶里沒有令牌則等待,直到有令牌。* acquire(N)可以獲取多個令牌。*/System.out.println(r.acquire());} }?
1.2 分布式限流
? ? ? a>> nginx
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=2r/s; server { location / { limit_req zone=mylimit; } }? ? b>>api-gateway+redis限流
? ? ? https://github.com/wangzheng0822/ratelimiter4j
2. 熔斷對比
功能對比
?
| 隔離策略 | 信號量隔離(并發線程數限流) | 線程池隔離/信號量隔離 | 信號量隔離 |
| 熔斷降級策略 | 基于響應時間、異常比率、異常數 | 基于異常比率 | 基于異常比率、響應時間 |
| 實時統計實現 | 滑動窗口(LeapArray) | 滑動窗口(基于 RxJava) | Ring Bit Buffer |
| 動態規則配置 | 支持多種數據源 | 支持多種數據源 | 有限支持 |
| 擴展性 | 多個擴展點 | 插件的形式 | 接口的形式 |
| 基于注解的支持 | 支持 | 支持 | 支持 |
| 限流 | 基于 QPS,支持基于調用關系的限流 | 有限的支持 | Rate Limiter |
| 流量整形 | 支持預熱模式、勻速器模式、預熱排隊模式 | 不支持 | 簡單的 Rate Limiter 模式 |
| 系統自適應保護 | 支持 | 不支持 | 不支持 |
| 控制臺 | 提供開箱即用的控制臺,可配置規則、查看秒級監控、機器發現等 | 簡單的監控查看 | 不提供控制臺,可對接其它監控系統 |
?
參考文獻:
【1】https://mp.weixin.qq.com/s?__biz=MjM5MDE0Mjc4MA==&mid=2651008444&idx=1&sn=a579c3ceb143ea30930bd4c6d4a8d7e2&chksm=bdbed5ef8ac95cf93e71c5393f08e3b97a7e19e8232ce3872231f2cae74f7a19ab15501aeb44&scene=27#wechat_redirect
【2】https://mp.weixin.qq.com/s?__biz=MzIwMzY1OTU1NQ==&mid=2247484306&idx=1&sn=b6c1b7b9d7c57bbb9f82ec451bcda867&chksm=96cd43dea1bacac8a24cde429146f69dba8bb15c5c9c3fe9adfe858d9a4349cc127fbfa84a8c&scene=27#wechat_redirect
【3】https://github.com/alibaba/Sentinel/wiki/Guideline:-%E4%BB%8E-Hystrix-%E8%BF%81%E7%A7%BB%E5%88%B0-Sentinel
轉載于:https://www.cnblogs.com/davidwang456/p/10196191.html
總結
以上是生活随笔為你收集整理的分布式系统中的限流与熔断的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数据库新秀 postgresql vs
- 下一篇: 库存系统难破题?京东到家来分享