分散セキリングシステムの構築から電流制限のトリックについて話しましょう

分散セキリングシステムの構築から電流制限のトリックについて話しましょう

序文

諺にあるように、厚さ 3 フィートの氷は一夜にして形成されるものではなく、一滴の水は時間をかけて石を削り取るものであり、ローマは一日にして成らずです。 2週間前、フラッシュセール事件の初期形態が、中国人ユーザー向けのウェブサイト「Mayun」で共有された。同時に、友人たちからもたくさんの提案や苦情をいただきました。配布、クラスタリング、フラッシュセールが大企業の専売特許であるべきだとは決して思いません。今日のインターネット時代では、常に武装していなければなりません。そうすれば、明日あなたの春が来るかもしれません。

フラッシュセールシステムケースの開発過程では、主に共有キュー、キャッシュ、ロック、分散ロック、静的化などを採用しました。キャッシュの目的は、システムアクセス速度を向上させ、システム処理能力を強化することです。分散ロックは、クラスター内のデータのセキュリティと一貫性の問題を解決します。静的化により、キャッシュ層と DB 層への負荷が軽減されることは間違いありません。

[[233265]]

電流制限

しかし、マシンがどれだけ強力であっても、設計がどれだけ最適化されていても、特別なシナリオを特別に処理する必要があります。フラッシュセールを例に挙げてみましょう。買いに駆け込むユーザーは多いかもしれませんが、商品の数はユーザー数よりはるかに少ないです。これらすべてのリクエストがキューまたはクエリ キャッシュに入ると、最終結果には意味がなく、バックグラウンドで大量のデータが増えるだけです。この点では、リソースの無駄を減らし、バックエンドの負荷を軽減するために、フラッシュセールの流れを制限し、一部のユーザーに対してのみ通常のサービスを保証する必要があります。

フラッシュセールインターフェースに関しては、アクセス頻度や同時リクエストが許容範囲を超えた場合、予期しないリクエストによるシステムへの過度の負荷によるシステム麻痺を防ぐために、インターフェースの可用性を確保するために電流制限を考慮する必要があります。通常の戦略は、冗長アクセスを拒否するか、冗長アクセスをサービス用にキューに入れることです。

電流制限アルゴリズム

いかなる電流制限も無意味なものではなく、スイッチで解決できる問題でもありません。一般的に使用される電流制限アルゴリズムには、トークン バケットとリーキー バケットがあります。

トークンバケット

トークン バケット アルゴリズムは、ネットワーク トラフィック シェーピングとレート制限で最も一般的に使用されるアルゴリズムです。通常、トークン バケット アルゴリズムは、ネットワークに送信されるデータの量を制御し、バースト データの送信を許可するために使用されます (Wikipedia)。

フラッシュセールでは、ユーザーのリクエスト率は固定されていません。ここでは 10r/s と仮定します。トークンは 1 秒あたり 5 個の速度でトークン バケットに入れられ、バケットには最大 20 個のトークンを保存できます。よく考えてみてください。破棄されるリクエストも必ず存在します。

漏れやすいバケツ

リーキー バケット アルゴリズムの主な目的は、ネットワークにデータが注入される速度を制御し、ネットワーク上のバースト トラフィックを平滑化することです。リーキー バケット アルゴリズムは、ネットワークに安定したフローを提供するためにバースト トラフィックを ××× できるメカニズムを提供します (百科事典)。

トークン バケットとは、流入速度がどれだけ速くても、事前に決められた速度で処理することを意味します。バケットがいっぱいの場合、サービスは拒否されます。

アプリケーション電流制限

トムキャット

Tomcat コンテナでは、スレッド プールをカスタマイズし、最大接続数、要求処理キュー、その他のパラメータを構成することで、電流制限の目的を達成できます (インターネットからの画像)。

Tomcat はデフォルトで独自の接続プールを使用します。ここで実装をカスタマイズすることもできます。 /conf/server.xml ファイルを開き、コネクタの前にスレッド プールを構成します。

  1. <エグゼキュータ= "tomcatThreadPool"  
  2. 名前プレフィックス = "tomcatThreadPool-"  
  3. 最大スレッド数 = "1000"  
  4. 最大アイドル時間 = "300000"  
  5. 最小スペアスレッド数 = "200" />
  • name: 共有スレッド プールの名前。これは、コネクタがスレッド プールを共有するために参照する名前です。この名前は一意である必要があります。デフォルト値: なし;
  • namePrefix: JVM では、実行中の各スレッドに名前文字列を設定できます。このプロパティは、スレッド プール内の各スレッドの名前文字列のプレフィックスを設定し、Tomcat はこのプレフィックスの末尾にスレッド番号を追加します。デフォルト値: tomcat-exec-;
  • maxThreads: スレッド プールが収容できるスレッドの最大数。デフォルト値: 200
  • maxIdleTime: Tomcat がスレッドを閉じるまでアイドル スレッドが継続できる時間 (ミリ秒単位)。アイドル スレッドは、現在アクティブなスレッドの数が minSpareThread の値より大きい場合にのみ閉じられます。デフォルト値: 60000 (1 分)。
  • minSpareThreads: Tomcat が常に開いている必要がある非アクティブ スレッドの最小数。デフォルト値: 25。

コネクタの設定

  1. <コネクタ executor= "tomcatThreadPool"  
  2. ポート = "8080"プロトコル = "HTTP/1.1"  
  3. 接続タイムアウト = "20000"  
  4. リダイレクトポート = "8443"  
  5. 最小プロセッサ数 = "5"  
  6. 最大プロセッサ数 = "75"  
  7. 受け入れ回数 = "1000" />
  • executor: パラメータ値に対応するスレッド プールを示します。
  • minProcessors: サーバーがリクエストの処理を開始するときに作成されるスレッドの数。
  • maxProcessors: ***リクエストを処理するために作成できるスレッドの数。
  • acceptCount: リクエストの処理に使用可能なすべてのスレッドが使用された場合に、処理キューに配置できるリクエストの数を指定します。この数を超えるリクエストは処理されません。

API電流制限

フラッシュセール中は、インターフェースへのリクエスト数が通常の数百倍、あるいは数千倍にまで増加し、インターフェースが利用できなくなり、連鎖反応が引き起こされてシステム全体がクラッシュし、他のサービスにも影響が及ぶ可能性があります。

では、このような突然の出来事にどう対処すればよいのでしょうか?ここでは、オープンソース ツールキット guava によって提供されるレート制限ツール クラス RateLimiter を使用して、API フローを制限します。このクラスは「トークン バケット アルゴリズム」に基づいており、すぐに使用できます。

  1. /**
  2. * カスタム注釈電流制限
  3. */
  4. @Target({ElementType.PARAMETER, ElementType.METHOD})
  5. @保持(保持ポリシー.RUNTIME)
  6. @文書化済み
  7. パブリック@interface ServiceLimit {
  8. 文字列の説明()デフォルト  "" ;
  9. }

カスタムの側面

  1. /**
  2. * 電流制限AOP
  3. */
  4. @成分
  5. @範囲
  6. @側面
  7. パブリッククラスLimitAspect {
  8. // 1 秒あたり 100 トークンのみが発行されます。これは、単一プロセス サービスの現在の制限です。トークンポーキングアルゴリズムは内部で使用されます。
  9. プライベート静的RateLimiter rateLimiter = RateLimiter.作成(100.0);
  10.  
  11. //サービス層カットポイント電流制限
  12. @ポイントカット( "@annotation(com.itstyle.seckill.common.aop.ServiceLimit)" )
  13. パブリックvoid ServiceAspect() {
  14.  
  15. }
  16.  
  17. @Around( "ServiceAspect()" )
  18. パブリックオブジェクトaround(ProceedingJoinPoint joinPoint) {
  19. ブールフラグ = rateLimiter.tryAcquire();
  20. オブジェクト obj = null ;
  21. 試す {
  22. if(フラグ){
  23. obj = joinPoint.proceed();
  24. }
  25. } キャッチ (Throwable e) {
  26. e.printStackTrace();
  27. }
  28. objを返します
  29. }
  30. }

事業実施:

  1. @オーバーライド
  2. @サービス制限
  3. @トランザクション
  4. パブリック結果startSeckill(longseckillId, longuserId) {
  5. //一部のビジネスコードは省略します。詳細については、2 番目の販売ソース コードを参照してください。
  6. }

分散電流制限

エンギンクス

  1. #httpドメインで均一に設定する
  2. #リクエストの制限
  3. limit_req_zone $binary_remote_addr $uri ゾーン=api_read:20m レート=50r/s;
  4. #IPで接続ゾーンを設定する
  5. limit_conn_zone $binary_remote_addr ゾーン=perip_conn:10m;
  6. #サーバーに応じて接続ゾーンを設定する
  7. limit_conn_zone $server_name ゾーン=perserver_conn:100m;
  8. サーバー{
  9. 聞く 80;
  10. サーバー名 seckill.52itstyle.com;
  11. 索引 インデックス.jsp;
  12. 位置 / {
  13. #バースト通過の現在の制限キューを要求します。デフォルトは 0 です。
  14. limit_req ゾーン=api_read バースト=5;
  15. #接続制限、各IP同時リクエストは2
  16. 制限接続 ペリプ接続 2;
  17. #サービスによって制限される接続数(つまり、サーバーへの同時接続数が制限される)
  18. limit_conn パーサーバー接続 1000;
  19. #接続速度制限
  20. 制限レート 100k;
  21. proxy_pass http://seckill;
  22. }
  23. }
  24. 上流セキル {
  25. 公平;
  26. サーバー 172.16.1.120:8080 重み=1 max_fails=2 fail_timeout=30s;
  27. サーバー 172.16.1.130:8080 重み=1 max_fails=2 fail_timeout=30s;
  28. }

設定手順

  1. 参加する

セッションステータスを保存するためのコンテナが IP ごとに定義されます。この例では、100 MB のコンテナが定義されており、32 バイト/セッションで 3,200,000 セッションを処理できます。

  1. 制限レート 300k;

各接続の速度を 300k に制限します。これは接続速度の制限であり、IP 速度の制限ではないことに注意してください。 IP が 2 つの同時接続を許可する場合、この IP のレート制限は limit_rate×2 になります。

  1. バースト=5;

これはバケットのサイズに相当します。リクエストがシステムの処理速度を超えた場合、リクエストはバケットに配置され、処理を待機します。バケットがいっぱいの場合、残念ながらリクエストは直接 503 を返し、クライアントはサーバーがビジーであるという応答を受け取ります。システムがリクエストをゆっくりと処理する場合、バケット内のリクエストは永久にそこに留まることはできません。一定の時間を超えると、サーバーがビジー状態であるという応答が直接返されます。

オープンレスティ

後ろ姿は見覚えがありますか?はい、これは直接「理解万歳」と叫んだ羅永浩です。 2015年、Luo Yonghao氏はSmartisan Technology T2発表カンファレンスのチケット収益をOpenRestyに寄付しました。私も羅永浩は感情を持った太った男だと信じています。

ここでは、OpenResty のオープンソースの電流制限ソリューションを使用します。テストケースでは、lua-resty-limit-traffic モジュールとケースが付属する OpenResty1.13.6.1*** バージョンを使用しているため、実装が容易になります。

同時インターフェース/リクエストの総数を制限する

フラッシュセール中は、突然のトラフィックの急増によりシステム全体の安定性に影響が及び、クラッシュが発生する可能性があります。この場合、フラッシュセール インターフェースの合計同時実行数/リクエスト数を制限する必要があります。

ここでは、lua-resty-limit-traffic の resty.limit.count モジュールを使用します。記事が長いため、具体的なコードについてはソースコード openresty/lua/limit_count.lua を参照してください。

インターフェース時間ウィンドウ要求の数を制限する

フラッシュセールのシナリオでは、必ずしも人間のマウスが使用されるとは限りません。たとえば、12306 のチケット取得ソフトウェアは、人間のマウスよりもはるかに高速にチケットをスワイプできます。この時点で、チケットブラッシングが蔓延しないように、クライアント上の単位時間あたりのリクエスト数を制限する必要があります。もちろん、解決策は常に存在します。チケットを盗むソフトウェアは、常に防御を回避する方法を見つけます。一方で、技術の進歩も促進します。

ここでは、lua-resty-limit-traffic の resty.limit.conn モジュールを使用します。具体的なコードについては、ソースコード openresty/lua/limit_conn.lua を参照してください。

インターフェースリクエストの数をスムーズに制限する

以前のフロー制限方法ではバースト トラフィックが許可されていましたが、これは瞬間的なトラフィックが許可されることを意味します。突然のトラフィックを制限しないと、システム全体の安定性に影響を及ぼします。したがって、フラッシュ セールのシナリオでは、リクエスト レートは平均レート ×××、つまり 20r/s で処理される必要があります。

ここでは、lua-resty-limit-traffic の resty.limit.req モジュールを使用して、リーキー バケット電流制限とトークン バケット電流制限を実装します。

実際、リーキー バケットとトークン バケットの根本的な違いは、リクエスト レートを超えるリクエストをどのように処理するかにあります。リーキー バケットは、平均速度で処理されるのを待つためにリクエストをキューに入れ、キューがいっぱいになるとサービスを拒否します。トークン バケットは、バケット容量が許せば、これらのバースト要求を直接処理します。

漏れやすいバケツ

バケット容量がゼロより大きく、遅延モードになっています。バケットがいっぱいでない場合、リクエストはリクエスト キューに入り、一定の速度で処理を待機します。いっぱいの場合は、リクエストは拒否されます。

トークンバケット

バケット容量はゼロより大きく、非遅延モードです。バケット内にトークンが存在する場合はバーストが許可され、存在しない場合は要求は拒否されます。

ストレステスト

上記の構成効果をテストするために、AB ストレス テストを使用します。 Linux で次のコマンドを実行します。

  1. # インストール
  2. yum -y httpd-toolsをインストールします
  3. # ab バージョンを表示
  4. アブ-v
  5. # ヘルプを表示
  6. ab --ヘルプ 

テストコマンド:

  1. ab -n 1000 -c 100 http://127.0.0.1/

テスト結果:

  1. サーバーソフトウェア: openresty/1.13.6.1 #サーバーソフトウェア
  2. サーバーホスト名: 127.0.0.1 #IP
  3. サーバーポート: 80 #リクエストポート番号
  4.  
  5. ドキュメントパス: / #ファイルパス
  6. ドキュメントの長さ: 12 バイト #ページ内のバイト数
  7.  
  8. 同時実行レベル: 100 #同時リクエスト数
  9. テストかかった時間: 4.999 秒
  10. 完了したリクエスト: 1000 #合計リクエストツリー
  11. 失敗したリクエスト: 0 #失敗したリクエストの数
  12. 書き込みエラー: 0
  13. 転送合計: 140000 バイト #要求されたデータの合計サイズ
  14. 転送された HTML: 12000 バイト #HTML ページの実際の合計バイト数
  15. 1秒あたりのリクエスト数: 200.06 [#/秒] (平均) #1秒あたりのリクエスト数。これはサーバーのスループットを表す非常に重要なパラメータ値です。
  16. リクエストあたりの時間: 499.857 [ms] (平均) #ユーザーリクエストの平均待機時間
  17. リクエストあたりの時間: 4.999 [ms] (平均、すべての同時リクエスト全体) # 平均サーバー処理時間。サーバースループットの逆数です。
  18. 転送速度: 27.35 [Kbytes/sec] 受信 #1秒あたりに受信されるデータ長
  19.  
  20. 接続時間 (ミリ秒)
  21. 最小平均[+/- 標準偏差] 中央値最大値 
  22. 接続: 0 0 0.8 0 4
  23. 処理: 5 474 89.1 500 501
  24. 待機中: 2 474 89.2 500 501
  25. 合計: 9 475 88.4 500 501
  26.  
  27. 一定時間内に処理されたリクエスト割合(ミリ秒)
  28. 50% 500
  29. 66% 500
  30. 75% 500
  31. 80% 500
  32. 90% 501
  33. 95% 501
  34. 98% 501
  35. 99% 501
  36. 100% 501 (最長リクエスト)

要約する

上記のフロー制御ソリューションは、このフラッシュセールの事例の簡単な概要にすぎません。良い解決策と悪い解決策を意図的に区別しないでください。ビジネスシナリオに適している限り、それは最高です。

参照する

https://github.com/openresty/lua-resty-limit-traffic

https://blog.52itstyle.com/archives/1764/

https://blog.52itstyle.com/archives/775/

共有することは喜びであり、個人の成長の過程を目撃するものでもあります。記事のほとんどは職務経験と日々の学習の蓄積をまとめたものです。私自身の認識に何らかの欠陥があることは避けられません。私を正して一緒に進歩させてください。

この記事の著作権は著者に帰属します。転載は歓迎しますが、この声明は著者の同意なしに保持され、記事ページの目立つ位置に記載される必要があります。ご不明な点がございましたら、メール([email protected])にてご相談ください。

<<:  クラウドコンピューティングは「暴走馬」にはならない、と専門家は語る:人工知能はクラウドデータのセキュリティレベルを向上させることができる

>>:  UCloudのコアセキュリティ製品は公安省から販売ライセンスを取得しました

推薦する

Xiake Station Group System V3の無料版の経験とWORDPRESSプラットフォームの実践的な経験

最近、サイトグループで遊びたくなって、朝A5を開いて、Xiakeサイトグループシステムの無料版がある...

Vultr: 韓国のクラウドサーバー、SKデータセンター、迂回せずに中国本土に直接接続

クラウドサーバー業者の Vultr は、すでにバックエンドに韓国のデータセンターを持ち、韓国のクラウ...

再度更新:最も安いVPS、10年間の経験を共有し、海外の安いVPSに関する情報をまとめました

私は多くの安価な VPS を使用しましたが、その中にはかつて「最も安い VPS」と考えられていたもの...

返信を可視化することで、ウェブサイトのアクティビティとユーザー エクスペリエンスを向上させましょう。 !

私たちのウェブマスターと一般のネットユーザーの両方がこの問題に遭遇すると思います。ユーザーがBaid...

新しいメディア運営者はプロモーションチャネルをどのように選択するのでしょうか?

最近、新しいメディア運営の分野で非常に考えさせられる質問を目にしました。新しいメディア運営者はプロモ...

MetWeb: ウェブサイトをオープンソース化するとはどういう意味ですか?

2018年最もホットなプロジェクト:テレマーケティングロボットがあなたの参加を待っていますソース コ...

2017年ゲーム購入に関する年次白書:ユーザー当たりのコストが300人民元を超える

2017年はゲーム業界の競争が激化した年でした。広告主は大きなプレッシャーを感じており、ユーザー獲得...

20 を超える Kubernetes クラスターと 400 台のマシンを管理する秘訣は何ですか?

この記事は公開アカウント「Reading Core Technique」(ID: AI_Discov...

AWS が新しい機械学習サービスを発表、世界初のディープラーニングカメラを開発者に提供

[51CTO.com からのオリジナル記事] 本日開催された AWS Re:Invent カンファレ...

プライベート DLT かパブリック ブロックチェーンか?

許可型分散型台帳技術(DLT)はオープンブロックチェーンの問題に合わせて調整されているため、オープン...

テンセントの新メディアを統合してブランド効果を最大限に高める方法

テンセントの新メディアは私の生活を完全に占領していると言わざるを得ません。何もすることがないときは、...

20社以上のP2Pオンライン融資会社が倒産し、業界の慢性的な問題が警告を発し始めている。

10月以降、20以上のオンライン融資プラットフォームが資金調達チェーンに問題を抱えており、そのリスト...

2020年は自動化がクラウドガバナンスを推進する

2020 年を迎えるにあたり、クラウド ガバナンスの世界における将来の発展について考えることが重要で...

INIZ - 年間 14 ドル / メモリ 256 MB / ハードディスク 20 GB / トラフィック 500 GB / ニューヨーク / ロサンゼルス

INIZは中国人を嫌っています。私は1年以上アカウントを持っていましたが、結局削除されました。でも、...

企業がクラウドネイティブ分散データベースを検討すべき3つの理由

1. クラウドネイティブ「クラウド ネイティブ」の概念の創始者である Matt Stine 氏は、2...