同時三剣客の限流方案の総括


前言


高同時性のシステムでは、キャッシュ、ダウングレード、ストリーム制限の3つの利器がシステムを保護します.ストリーム制限でよく見られるアプリケーションシーンは、秒殺、注文、コメントなどの突発的な同時問題です.
  • キャッシュの目的は、システムアクセス速度とシステムスループットを向上させることです.
  • のダウングレードは、サービスに問題が発生したり、コアプロセスのパフォーマンスに影響を与えたりした場合、一時的に遮断し、ピークまたは問題が解決してから開く必要があります.
  • 一部のシーンでは、希少なリソース(秒殺、買い占め)、書き込みサービス(コメント、注文など)、頻繁な複雑なクエリー(最新のコメント)など、キャッシュおよびダウングレードで解決できない場合があります.したがって、これらのシーンの同時/要求量、すなわちストリーム制限を制限する手段が必要である.

  • 本文


    限流の目的


    ストリーム制限の目的は、同時アクセス/要求を制限すること、または時間ウィンドウ内の要求を制限することによってシステムを保護することであり、制限速度に達すると、サービス(エラー・ページに移動したり、リソースがなくなったことを通知したり)、列に並んだり、待機したり(秒殺、コメント、注文)、ダウングレード(商品詳細ページ在庫のデフォルト在庫品などの基板データまたはデフォルトデータに戻る)を拒否することができます.

    げんりゅうほうしき

  • データベース接続プール、スレッドプールなどの合計同時実行数を制限する
  • .
  • 瞬時同時接続数を制限nginxlimit_connモジュールのような瞬時同時接続数を制限する
  • .
  • は、時間ウィンドウ内の平均レート(例えば、GuavaRateLimiternginxlimit_reqモジュール、毎秒の平均レートを制限)
  • を制限する.
  • リモートインタフェース呼び出し速度
  • を制限する.
  • MQの消費率
  • を制限する.
  • は、ネットワーク接続数、ネットワークトラフィック、CPUまたはメモリ負荷等に応じる、ストリーム
  • を制限することができる.

    げんりゅうアルゴリズム


    1.トークンバケツ


    2.バケツ漏れ


    3.カウンタ


    カウンタを使用してストリーム制限を行うこともできます.主に、データベース接続プール、スレッドプール、秒殺の同時数などの総同時数を制限するために使用されます.グローバル総要求数または一定期間の総要求数で設定されたバルブ値によりストリームを制限する.これは平均速度制限流ではなく,単純で乱暴な制限流方式である.

    トークンバケツvsドレインバケツ


    トークンバケツは、平均流入速度を制限し、バースト要求を許可し、ある程度のバースト流量を許可する.
    ドレインバケツは、定量的流出速度を制限し、バースト流入速度を平滑化する.

    レベル制限フローの適用


    1.ストリーム制限総リソース数


    プール化テクノロジーを使用して、接続プール、スレッドプールの合計リソース数を制限できます.例えば、各アプリケーションに割り当てられたデータベース接続が100である場合、本アプリケーションは最大100個のリソースを使用することができ、待機または異常放出を超えることができる.

    2.ストリーム制限合計同時/接続/要求数

    Tomcatを使用した場合、Connectorのいずれかの構成には次のパラメータがあります.
  • maxThreads:Tomcatは、要求を処理するための最大スレッド数を開始することができ、要求処理量が最大スレッド数よりはるかに大きい場合、硬直する可能性があります.
  • maxConnections:瞬時最大接続数、超過すると待ち行列ができます.
  • acceptCount:Tomcatのスレッドが応答に忙しい場合、新しく来た接続はキューに入り、キューサイズを超えると接続を拒否します.

  • 3.ストリーム制限インタフェースの合計同時/要求数

    JavaAtomicLongを使用して、コードを示します.
    try{
        if(atomic.incrementAndGet() >  ) {
            // 
        } else {
            // 
        }
    } finally {
        atomic.decrementAndGet();
    }

    4.あるインタフェースのタイムウィンドウ要求数を制限する

    GuavaCacheを使用して、コードを示します.
    LoadingCache counter = CacheBuilder.newBuilder()
        .expireAfterWrite(2, TimeUnit.SECONDS)
        .build(newCacheLoader() {
            @Override
            public AtomicLong load(Long seconds) throws Exception {
                return newAtomicLong(0);
            }
        });
    
    longlimit =1000;
    while(true) {
        //  
        long currentSeconds = System.currentTimeMillis() /1000;
        if(counter.get(currentSeconds).incrementAndGet() > limit) {
            System.out.println(" : " + currentSeconds);
            continue;
        }
        //  
    }

    5.平滑ストリームのあるインタフェースの要求数


    従来のストリーム制限方式では、バースト要求にうまく対応できなかった.すなわち、瞬間要求が許可され、いくつかの問題を引き起こす可能性がある.そのため、一部のシーンでは、バーストリクエストを改造し、平均レートリクエスト処理に改造する必要がある.Guava RateLimiterはトークンバケツアルゴリズム実装を提供する.
  • 平滑バースト限流(SmoothBursty)
  • 平滑予熱限流(SmoothWarmingUp)
  • を実現する.

    スムーズバーストリミット(SmoothBursty)

    RateLimiter limiter = RateLimiter.create(5);
    System.out.println(limiter.acquire());
    System.out.println(limiter.acquire());
    System.out.println(limiter.acquire());
    System.out.println(limiter.acquire());
    System.out.println(limiter.acquire());
    System.out.println(limiter.acquire());

    次のような出力が得られます.
    0.0
    0.198239
    0.196083
    0.200609
    0.199599
    0.19961

    スムースウォームリミット(SmoothWarmingUp)

    RateLimiter limiter = RateLimiter.create(5, 1000,  TimeUnit.MILLISECONDS);
    for(inti = 1; i < 5; i++) {
        System.out.println(limiter.acquire());
    }
    
    Thread.sleep(1000L);
    for(inti = 1; i < 5; i++) {
        System.out.println(limiter.acquire());
    }

    次のような出力が得られます.
    0.0
    0.51767
    0.357814
    0.219992
    0.199984
    0.0
    0.360826
    0.220166
    0.199723
    0.199555
    SmoothWarmingUpの作成方法:
    RateLimiter.create(doublepermitsPerSecond, long warmupPeriod, TimeUnit unit);
  • permitsPerSecond:1秒あたりの新規トークン数を示す
  • warmupPeriod:冷間始動速度から平均速度に移行する時間間隔
  • を示す.
    速度は台形の上昇速度であり、つまり冷却起動時に比較的大きな速度で平均速度に徐々に到達する.次いで平均速度(台形が平均速度に低下する)に傾く.warmupPeriodパラメータを調整することによって、最初から平滑固定速度を実現することができる.

    ぶんぷしきげんりゅう


    分散型ストリーム制限は、ストリーム制限サービスを原子化することが最も重要であり、解決策はredis + luaまたはnginx + lua技術を用いて実現することができる.

    アクセス層限流


    アクセス層は、通常、トラフィックを要求する入口を指し、その主な目的は以下のとおりである.
  • 負荷等化
  • 不正要求フィルタ
  • 要求集約
  • キャッシュ、ダウングレード、ストリーム制限
  • A/Bテスト
  • サービス品質監視
  • Nginxアクセス層ストリーム制限について、Nginxを使用して、2つのモジュールを備えることができる:接続数ストリーム制限モジュールngx_http_limit_conn_moduleとドレインバケツアルゴリズムによって実現される要求ストリーム制限モジュールngx_http_limit_req_module.より複雑なストリーム制限シナリオは、OpenRestyによって提供されるLuaストリーム制限モジュールlua-resty-limit-trafficを使用して行うこともできる.
  • limit_conn:あるKEYに対応する総ネットワーク接続数を制限するために使用され、例えばIP、ドメイン名次元に従って制限することができる.
  • limit_req:あるKEYに対応する要求の平均レートを制限するために使用され、平滑モード(delay)と許可バーストモード(nodelay)の2つの方法がある.
  • OpenRestyによって提供されるLuaストリーム制限モジュールlua-resty-limit-trafficは、より複雑なストリーム制限シナリオを行うことができる.
    技術公衆番号へようこそ:零壹技術スタック
    このアカウントでは、仮想マシンの基礎、マルチスレッドプログラミング、高性能フレームワーク、非同期、キャッシュ、メッセージミドルウェア、分散型およびマイクロサービス、アーキテクチャ学習、階層化などの学習資料と文章を含むバックエンド技術の乾物を共有し続けます.