ホームページ >バックエンド開発 >Golang >golang でフローを制限するにはどうすればよいですか?アルゴリズムの詳しい説明

golang でフローを制限するにはどうすればよいですか?アルゴリズムの詳しい説明

PHPz
PHPzオリジナル
2023-04-11 10:39:401229ブラウズ

インターネット テクノロジーの継続的な発展に伴い、高い同時実行性と大規模なトラフィックの需要がますます一般的になり、電流制限テクノロジーの重要性がますます高まっています。高速かつ効率的な言語である golang は、現在の制限においてそのアプリケーションを無視することはできません。それでは、golang が電流の流れをどのように制限するかを具体的に見てみましょう。

1. ファンネル アルゴリズム

ファンネル アルゴリズムは、一般的に使用される電流制限アルゴリズムです。その中心となるアイデアは、固定容量のファンネルを維持し、一定の値でファンネルに水を追加することです。ファンネルが最大容量に達すると、その後ろの水が溢れます。ファンネルに入るリクエストの場合、ファンネル内の水を消費する必要があります。ファンネル内の水が不十分な場合、リクエストは実行できないことを意味します現時点で処理されています。

golang では、「rate」パッケージを使用して、次のコードのように、電流制限のためのファネル アルゴリズムを実装できます:

import (
     "golang.org/x/time/rate"
     "net/http"
)

// 创建一个每秒钟只允许1个请求的漏斗
r := rate.NewLimiter(1, 1)
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
     if r.Method != "GET" {
          http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
          return
     }
     if !r.Limiter.CanAllow() {
          http.Error(w, "Too Many Requests", http.StatusTooManyRequests)
          return
     }
     // 处理业务逻辑
})

2. トークン バケット アルゴリズム

トークン バケット このアルゴリズムは、一般的な電流制限アルゴリズムでもあります。その中心的な考え方は、固定容量のバケットを維持し、一定のレートでトークンをバケットに継続的に投入することです。バケットに入るリクエストについては、バケット内のトークンを消費する必要があります。バケット内のトークンが不十分な場合、現時点ではリクエストを処理できません。

golang では、「golang.org/x/time/rate」パッケージを使用して、次のコードのように、電流制限のためのトークン バケット アルゴリズムを実装できます:

import (
     "golang.org/x/time/rate"
     "net/http"
)

// 创建一个每秒钟只允许1个请求的令牌桶
r := rate.NewLimiter(1, 1)
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
     if r.Method != "GET" {
          http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
          return
     }
     if !r.Wait(r.Context()) {
          http.Error(w, "Too Many Requests", http.StatusTooManyRequests)
          return
     }
     // 处理业务逻辑
})

3。スライディング ウィンドウ アルゴリズム

スライディング ウィンドウ アルゴリズムは、一般的に使用される電流制限アルゴリズムでもあります。その中心的な考え方は、1 秒を複数の固定サイズの期間に分割し、各期間で固定サイズの期間を維持することです。 .Counterは、リクエストが入力されるたびに、対応する期間のカウンタが1つ増加し、カウンタに入力されたリクエストの数が上限に達すると、リクエストを処理できなくなります。

golang では、「github.com/uber-go/ratelimit」パッケージを使用して、コード

import (
     "github.com/uber-go/ratelimit"
     "net/http"
)

// 创建一个每秒最多只允许1个请求的滑动窗口
rl := ratelimit.New(10) // 表示在一个时间段内最多允许处理10个请求
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
     if r.Method != "GET" {
          http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
          return
     }
     if !rl.TakeAvailable(1) { // 表示当前请求需要消耗1个计数
          http.Error(w, "Too Many Requests", http.StatusTooManyRequests)
          return
     }
     // 处理业务逻辑
})

4 など、電流制限のためのスライディング ウィンドウ アルゴリズムを実装できます。トークン バケットとリーキー バケット アルゴリズムの比較

トークン バケット アルゴリズムとファネル アルゴリズムは両方とも電流制限に使用できますが、アプリケーション シナリオ、アルゴリズムの複雑さ、実装の難易度、効果の点で依然として異なります。具体的には:

  • アプリケーション シナリオ: トークン バケット アルゴリズムは平均トラフィックを制限し、リクエストを安定した速度で処理するのに適していますが、ファネル アルゴリズムはピーク トラフィックを制限してシステムの障害を防ぐのに適しています。瞬時にリクエストに圧倒されることがなくなり、崩壊します。
  • アルゴリズムの複雑さ: ファネル アルゴリズムは複雑さが低く、int 型カウンターとタイムスタンプを維持するだけで済みますが、トークン バケット アルゴリズムはトークン バケットの容量を維持し、トークンの速度とより多くのパラメーターを配置する必要があります。
  • 実装の難しさ: ファネル アルゴリズムの実装は比較的単純です。for ループを使用して水の追加と消費のプロセスをシミュレートできますが、トークン バケット アルゴリズムではマルチスレッド セキュリティ、トークンを考慮する必要があります。有効期限およびその他詳細です。

一般に、さまざまな電流制限アルゴリズムにはそれぞれ固有のアプリケーション シナリオ、長所と短所があり、実際のニーズに応じて電流制限に適切なアルゴリズムを選択できます。

以上がgolang でフローを制限するにはどうすればよいですか?アルゴリズムの詳しい説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。