zoukankan      html  css  js  c++  java
  • 从修身齐家治国平天下谈分布式系统中的限流与熔断

    “古之欲明明德于天下者,先治其国;欲治其国者,先齐其家;欲齐其家者,先修其身;欲修其身者,先正其心;欲正其心者,先诚其意;欲诚其意者,先致其知,致知在格物。物格而后知至,知至而后意诚,意诚而后心正,心正而后身修,身修而后家齐,家齐而后国治,国治而后天下平。”--《礼记·大学》

    在应对秒杀、大促、双 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() {
     @Override
     public 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) {
     // 创建计数器,初始化为2
     final 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

    1.3 大流程限流(治国平天下)

    可以从防火墙,cdn,路由器,api网关等做限流

                                  治国平天下

    2. 熔断对比

    熔断处理逻辑类似,可以利用一些现成的框架,如Sentinel、Hystrix、resilience4j等。

    功能对比

    熔断对比

    参考文献:

    【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

  • 相关阅读:
    线程阶段性总结——APM,ThreadPool,Task,TaskScheduler ,CancellationTokenSource
    研究BackgroundWorker后发现:AsyncOperation和SynchronizationContext的差异真的很大!
    线程同步——优势、劣势
    APM异步编程模型的优势
    DataGridView的VirtualMode,在大容量数据加载时特别有用
    【C】——C语言的位运算的优势
    【linux】——Linux tar打包命令
    【C】用文件和链表实现学生信息管理
    【C】——回调函数的好处
    【C】strcpy()需谨慎使用;
  • 原文地址:https://www.cnblogs.com/davidwang456/p/11363211.html
Copyright © 2011-2022 走看看