BLOG | NGINX

NGINX Plusのキーバリューストアを使用した動的な帯域幅制限

NGINX-Part-of-F5-horiz-black-type-RGB
Published February 22, 2018

キーバリューストア機能は、NGINX Plusリリース13でHTTP用に導入され、リリース14でTCPとUDPに拡張されました。キーバリューストアを使用すると、設定をリロードしたりNGINX Plusを再起動したりすることなく、NGINX Plusがトラフィックを処理する方法をあらゆる条件に基づいてカスタマイズできます。

エディタ - NGINX Plus R16以降では、クラスタ内のすべてのNGINX Plusインスタンス間でキーバリュー・ストアを同期できます。(クラスタ内の状態共有は他のNGINX Plus機能でも利用可能です)。詳細については、ブログおよび『NGINX Plus Admin Guide』を参照してください。

以前のブログ投稿では、IPアドレスの拒否リストA/Bテストのためにキーバリューストアを使用する方法について説明しました。このブログ投稿では、アプリケーションのパフォーマンス目標をサポートするために、異なるカテゴリのユーザーに異なる帯域幅制限を課すために、キーバリューストアを使用する方法について説明します。この実践は、しばしばクラス・オブ・サービスと呼ばれるものを実装する1つの方法です。

帯域幅のスロットル

ウェブアプリケーションで帯域幅を制限する理由はたくさんあります。たとえば、eコマースサイトでは、カジュアルなユーザー向けの帯域幅を制限することで、購入を予定しているユーザーのユーザーエクスペリエンスを向上させることができます。これはまた、サイトのパフォーマンスを低下させようとする悪意のあるユーザーから、すべての正当なユーザーを保護することにもなります。

この例では、ログインしていないユーザーには最低の帯域幅制限を設定し、ログインしているユーザーには高い制限を設定し、優先ユーザーにはさらに高い制限を設定し、ログインしていてカートに商品を入れているユーザーにはすべての制限の中で最も高い制限を設定しています。

The NGINX Plus API and key-value store can be used to set dynamic bandwidth limits on website visitors based on their class of service

ユーザーカテゴリごとに帯域幅を調整するために作成するツールは、動的帯域幅リミッタと呼ばれます。これを動作させるには、NGINX Plusの2つの主な機能を使用します:

  • 1つ目は、NGINXとNGINX Plusのコア機能である、応答速度を制限する機能です。limit_rate ディレクティブまたは $limit_rate 変数を使用して、最大スループットを指定します。この変数の利点は、この例で行っているように、異なる条件に対して異なるレートを設定できることです。
  • 2つ目の機能は新しいもので、NGINX Plusのキーバリューストアです。NGINX Plusのキーバリューストアは、任意のJSON形式のキーと値を格納できます。

ダイナミック帯域幅リミッターの設定

動的な帯域幅リミッターを作成するために、NGINX Plusの設定で、最もカジュアルなユーザー(ログインしていないユーザー)に適した値のデフォルトの制限を設定します。帯域幅の制限は、徐々に価値の高いユーザーに対してより寛大になり、外部アプリケーションがキーバリューストアのサービスクラスへの顧客の割り当てを行います。

以下の例では、keyval_zoneディレクティブが、ratezoneという名前のキー・バリュー・ストアに1MBの共有メモリを割り当てています。keyvalディレクティブでは、最初のパラメータは、クッキーに記録された顧客IDをキー・バリュー・ストアの検索用のキーとして定義し、2番目のパラメータは、$bwlimit 変数がキーに関連付けられた値(その顧客のサービスのクラス)に設定されることを指定します。

cookie_CUSTOMERID変数はCUSTOMERIDという名前のクッキーを表します。これはユーザを一意に識別するための単純な仕組みで、通常ユーザがログインするときにアプリケーションによって設定されます。これは通常、ユーザがログインするときにアプリケーションによって設定されます。最もよく使われるのは、ユーザがサイト内を移動するのを追跡して、セッションの永続性を提供するためです。

キーバリュー・ストアはNGINX Plus APIに依存しており、/apiロケーションにapiディレクティブをwrite=onパラメータで含めることで読み書きアクセスが可能になります。(他のロケーションディレクティブは、組み込みのNGINX Plusライブアクティビティ監視ダッシュボードを有効にし、これもNGINX Plus APIを使用します)。

:このスニペットはAPIへのアクセスを制限しませんが、特に本番環境では制限することを強くお勧めします。詳細については、『NGINX Plus Admin Guide』を参照してください。

keyval_zone zone=ratezone:1M;keyval $cookie_CUSTOMERID $bwlimit zone=ratezone;

server {
    listen 8080;

    location = /dashboard.html {
        root /usr/share/nginx/html;
    }

    location /api {
        api write=on;
    }
#...
}

次に、マップブロックを使用して、各サービスクラスの帯域幅制限を定義する。keyvalディレクティブによって設定されたように、$bwlimit変数は、 外部アプリケーションによってキーバリューストアに設定された顧客のサービスクラスを 取得する:ログインユーザーにはブロンズ、優先ユーザーにはシルバー、ショッピングカートに商品を入れたユーザーにはゴールドを贈呈。

マップブロックは、ログインしていない、またはキーバリューストアにエント リがないユーザーに、デフォルトの帯域幅制限256Kbpsを割り当てる。サービスクラスの制限は、ブロンズが512Kbps、シルバーが1Mbps、ゴールドが帯域幅無制限(0を示す)である。(アプリのパフォーマンスの経験によっては、ショッピングカートのユーザーにも制限を設定したくなるかもしれません)。変数 $ratelimit は帯域幅の制限を表します。

サーバーブロックのsetディレクティブは、組み込みの$limit_rate変数を mapブロックで設定された$ratelimitの値に設定することで、帯域幅制限を実装する。

map $bwlimit $ratelimit {    bronze 512k;
    silver 1m;
    gold 0;
    default 256k;
}

server {
    #...
    set $limit_rate $ratelimit;
    #... 
}

NGINX Plus APIを使用したキーバリューストアの更新

NGINX Plus APIのHTTP GET、POST、およびPATCHメソッドは、キーバリューストアへのアクセスと管理に使用されます。前述のように、この例では外部アプリケーションがキーバリューストアを管理します。説明のために、ここでは可能な操作を示すためにcurlコマンドを使用します。

まず、GETメソッドを使用して、ratezoneキー・バリュー・ストアが空であることを確認する。2番目のcurlコマンドは、HTTP Cookieヘッダーの値として顧客IDを渡すために-bオプションを使用して、ファイルbrownie.jpgを要求します。oオプションは、ファイルを/dev/nullに書き込む(事実上破棄する)。

キー・バリュー・ストアは空であるため、顧客のキーは存在せず、デフォルトの速度制限である256Kbpsを取得すると予想される。これは、「現在の速度」列で報告された276Kbpsのレートによって確認される。

root# curl -X GET localhost:8080/api/1/http/keyvals/ratezone{}

root# curl -b "CUSTOMERID=CPE1704TKS" -o /dev/null localhost/brownie.jpg
  % Total    % Received % Xferd  Average Speed   Time    Time     Time     Current
                                 Dload  Upload   Total   Spent    Left     Speed
100 1893k  100    1893k 0     0   269k       0  0:00:07 0:00:07 --:--:--     276k

ここで、HTTP POSTメソッドを使用して、顧客CPE1704TKSをサービスのブロンズ・クラスに割り当てるエントリをキーバリューストアに作成します。2番目のコマンドは新しいエントリが存在することを確認し、最後のコマンドはダウンロード速度が626Kbpsに増加していることを示します。

root# curl -X POST -d '{"CPE1704TKS":"bronze"}' localhost:8080/api/1/http/keyvals/ratezone
root# curl -X GET localhost:8080/api/1/http/keyvals/ratezone
{"CPE1704TKS":"bronze"}

root# curl -b "CUSTOMERID=CPE1704TKS" -o /dev/null localhost/brownie.jpg
  % Total    % Received % Xferd  Average Speed   Time    Time     Time     Current
                                 Dload  Upload   Total   Spent    Left     Speed
100 1893k  100    1893k 0     0     626k     0  0:00:03 0:00:03  --:--:--     626k

その後、PATCHメソッドを使用して、顧客をシルバークラスのサービスに昇格させ、ダウンロード率が再び上昇したことを確認します。

root# curl -X PATCH -d '{"CPE1704TKS":"silver"}' localhost:8080/api/1/http/keyvals/ratezone
root# curl -X GET localhost:8080/api/1/http/keyvals/ratezone
{"CPE1704TKS":"silver"}

root# curl -b "CUSTOMERID=CPE1704TKS" -o /dev/null localhost/brownie.jpg
  % Total    % Received % Xferd  Average Speed   Time    Time     Time     Current
                                 Dload  Upload   Total   Spent    Left     Speed
100 1893k  100    1893k 0     0   1876k      0  0:00:01 0:00:01  --:--:--    1877k

最後に、再びPATCHメソッドを使用して、顧客をゴールドクラスのサービスに昇格させ、帯域幅の制限が課されない場合にダウンロード速度が劇的に向上することを確認します。

root# curl -X PATCH -d '{"CPE1704TKS":"gold"}' localhost:8080/api/1/http/keyvals/ratezone
root# curl -X GET localhost:8080/api/1/http/keyvals/ratezone
{"CPE1704TKS":"gold"}

root# curl -b "CUSTOMERID=CPE1704TKS" -o /dev/null localhost/brownie.jpg
  % Total    % Received % Xferd  Average Speed   Time    Time     Time     Current
                                 Dload  Upload   Total   Spent    Left     Speed
100 1893k  100    1893k 0     0    192M      0 --:--:-- --:--:-- --:--:--     205M

キー・バリュー・ストアを関連するユース・ケースに使う

この例では、Customer ID Cookie ($cookie_CUSTOMERID)を使用して各ユーザを識別し、class-of-service カテゴリを割り当てる方法を示します。しかし、このロジックは NGINX 変数($remote_ip、$jwt_claim_sub など)に取り込まれたほぼすべての値に適用できます。アプリケーションやユースケースによって、他の変数よりも意味のある変数もあります。また、キーバリューストアを使用してコネクションレートを制限することもできます。これは、カジュアルなユーザーや悪意のあるユーザーが他のユーザー、特にアクティブな購入者やアプリケーションのパフォーマンス全般に悪影響を与えないようにするために非常に便利です。

NGINX設定の完全なサンプル

keyval_zone zone=ratezone:1M;keyval $cookie_CUSTOMERID $bwlimit zone=ratezone;

map $bwlimit $ratelimit {
    bronze 512k;
    silver 1m;
    gold 0;
    default 256k;
}

upstream backend1 {
    zone backend1 64k;
    server 192.168.1.100:443;
}

server {
    listen 8080;

    location = /dashboard.html {
        root /usr/share/nginx/html;
    }

    location /api {
        api write=on;
    }

    location / {
        return 301 /dashboard.html;
    }
}

server {
    listen 80;
    set $limit_rate $ratelimit;

    location /favicon.ico {
        alias /usr/share/nginx/html/nginx-favicon.png;
    }
	
    location = /brownie.jpg {
        root /usr/share/nginx/html;
    }

    location / {
        proxy_set_header Host $host;
        proxy_pass https://backend1;
    }	
}

NGINX PlusのKey-Valueストアを実際にお試しいただくには、今すぐ30日間の無料トライアルを開始するか、ユースケースについてご相談ください。


"This blog post may reference products that are no longer available and/or no longer supported. For the most current information about available F5 NGINX products and solutions, explore our NGINX product family. NGINX is now part of F5. All previous NGINX.com links will redirect to similar NGINX content on F5.com."