NGINX(エンジンエックス)|日本公式サイト

NGINXはF5ファミリーの一員となりました。新体制の詳細はこちらを御覧ください。

お客様にご満足いただき、インフラストラクチャーを最適化するうえで鍵となるのが、すべてのサーバー、クライアント、プロキシにネットワークトラフィックを均等に分散することです。NGINX Plusの高性能なロードバランシング機能を使えば、スケールアウトを実行し、冗長性を確保できます。またグローバルサーバーロードバランシング(GSLB)、セッションパーシステンス、アクティブヘルスチェックが可能になり、再起動を伴わずに、インフラストラクチャーを動的に再設定できます。NGINX PlusはHTTPトラフィックだけでなく、TCPとUDPの負荷もあわせて分散します。

NGINX and NGINX Plus are full-featured load balancers for HTTP, TCP, and UDP
NGINXとNGINX Plusロードバランシング機能によりアプリケーションをスケールアウト

HTTPロードバランシング

HTTPトラフィックのロードバランシングでは、NGINX Plusは各HTTP接続を終端し、それぞれの要件を個別に処理します。SSL/TLS暗号化を取り除き、要求の検査と操作を行い、レート制限を使って要求をキューに入れたうえで、ロードバランシングポリシーを選択できます。

パフォーマンスの向上のために、NGINX PlusはHTTPプロトコルのアップグレード、キープアライブ最適化、およびコンテンツ圧縮やレスポンスキャッシングなどの変換を含む多種多様な最適化をHTTPトランザクションに対し自動で適用します。

NGINX Plusを使えば、HTTPトラフィックのロードバランシングが容易に行えます。

http {
    upstream my_upstream {
        server server1.example.com;
        server server2.example.com;
    }

    server {
        listen 80;
        location / {
            proxy_set_header Host $host;
            proxy_pass http://my_upstream;
        }
    }
}

最初に、serverディレクティブを使って仮想サーバーを指定し、次にトラフィックをlistenするポートを指定します。locationブロックを使ってクライアント要求のURLを照合し、proxy_set_headerディレクティブによりHostヘッダーを設定します。さらに、アップストリームグループに要求を転送するために、proxy_passディレクティブを加えます(upstreamブロックは、NGINX Plusがどのサーバーにトラフィックの負荷を分散するのかを定義します)。

詳しくは、こちらのNGINXとNGINX Plusを使ったロードバランシング入門を参照してください。

TCPとUDPのロードバランシング

NGINX Plusは、MySQLなどのTCPアプリケーション、およびDNSやRADIUSなどのUDPアプリケーションの負荷分散にも対応します。TCPアプリケーションに対して、NGINX PlusはTCP接続を終端し、バックエンドへの新たな接続を生成します。

stream {
    upstream my_upstream {
        server server1.example.com:1234;
        server server2.example.com:2345;
    }

    server {
        listen 1123 [udp];
        proxy_pass my_upstream;
    }
}

設定はHTTPの場合と同様であり、serverディレクティブを使って仮想サーバーを指定して、ポートのトラフィックをlistenし、要求をupstreamグループにproxy_passします。

TCPとUDPのロードバランシングの詳細については、「NGINX Plus管理者ガイド」を参照してください。

ロードバランシング方式

NGINX Plusは、HTTP、TCP、UDPのロードバランシング用に多数のアプリケーションロードバランシング方式をサポートしています。いずれの方式も、各アップストリームサーバーにオプションで割り当てることのできる重みを考慮に入れたものとなっています。

  • ラウンドロビン(デフォルト) – アップストリームサーバーに順番に要求を分散します。
  • 最小接続数 – アクティブな接続の数がもっとも少ないサーバーに要求を転送します。
  • 最小時間 – レスポンスタイムとアクティブな接続の数を組み合わせた計算に基づき、もっとも負荷の少ないサーバーに要求を転送します。この方式をサポートしているのはNGINX Plusだけです。
  • ハッシュ – クライアントIPアドレスや要求URLといった指定された鍵に基づき、要求を分散します。NGINX Plusでは、アップストリームサーバー群に変更があった場合に負荷の再分散を最小限に抑えるために、一貫したハッシュを適用できるようになっています(オプション)。
  • IPハッシュ(HTTPのみ) – クライアントIPアドレスの最初の3つのオクテットに基づき、要求を分散します。
  • ランダム(二者択一) – 2台のサーバーを無作為に選び、アクティブな接続の数が少ない方に要求を転送します(最小接続数方式)。NGINX Plusでは、最小時間方式の利用も可能です。

    NGINX Plusによる接続制限

    NGINX PlusがアップストリームHTTPサーバーやTCPサーバーとの間に確立する接続の数や、UDPサーバーとのセッションの数を制限することができます。サーバーとの接続やセッションの数が決められた制限を越えた時点で、NGINX Plusは新規の確立を停止します。

    以下に抜粋した設定では、webserver1の接続制限が250、webserver2の接続制限が150となっています。queueディレクティブは、最長30秒ごとにNGINX Plusがオペレーティングシステムのリッスンキューに入れる超過接続の最大数を指定するものであり、余分な超過要求は破棄されます。

    upstream backend {
        zone backends 64k;
        queue 750 timeout=30s;
    
        server webserver1 max_conns=250;
        server webserver2 max_conns=150;
    }

    サーバーのアクティブな接続の数が制限を下回った時点で、NGINX Plusはキューから接続を転送します。接続を制限することで、たとえトラフィックスパイクの発生時であっても、一貫性のある予測可能な方法でクライアント要求に対応できます。

    セッションパーシステンス

    ユーザーセッションを特定し、1つのセッション内のすべての要求を同じアップストリームサーバーへ送信するようにNGINX Plusを設定できます。アプリサーバーがステートをローカルに保存する場合は、このことがきわめて重要になってきます。なぜなら、進行中のユーザーセッションに対する要求が別のサーバーに送られると、致命的なエラーが発生するためです。セッションパーシステンスには、アプリケーションがクラスター全体で情報を共有する場合にパフォーマンスを向上させる効果もあります。

    NGINX Open Sourceがサポートするハッシュベースのセッションパーシステンス(ハッシュおよびIPハッシュを使ったロードバランシング手法)に加え、NGINX Plusではsticky cookieを含むCookieベースのセッションパーシステンスにも対応しています。NGINX Plusは、アップストリームグループから任意のクライアントへの最初の応答にセッションCookieを追加することで、応答を行ったサーバーを確実に特定します。続くクライアント要求にはそのCookieが含まれ、NGINX Plusはそれを使って同じアップストリームサーバーに要求をルーティングします。

    upstream backend {
        server webserver1;
        server webserver2;
    
        sticky cookie srv_id expires=1h domain=.example.com path=/;
    }

    上の例では、NGINX Plusは最初のクライアント応答にsrv_idというCookieを挿入することで、要求を処理したサーバーを識別しています。次の要求にそのCookieが含まれる場合、NGINX Plusは同じサーバーに要求を転送します。

    NGINX Plusは、sticky learnとsticky routeのパーシステンス手法もあわせてサポートしています。

    注:CookieベースのセッションパーシステンスはNGINX Plusでのみ提供される機能です。

    アクティブヘルスチェック

    デフォルトでは、NGINXはアップストリームサーバーからの応答に対し基本的なチェックを実行し、可能な場合は失敗した要求を再試行します。NGINX Plusはアウトオブバンドのアプリケーションヘルスチェック(「合成トランザクション」とも呼ばれます)と、スロースタート機能を追加することで、負荷分散されたグループに新しいサーバーや復旧したサーバーをスムースに追加します。

    これらの機能により、はるかに多様な問題を検出し、それらに対処できるようになり、HTTPおよびTCP/UDPアプリケーションの信頼性が大きく向上します。

    upstream my_upstream {
    	zone my_upstream 64k;
    	server server1.example.com slow_start=30s;
    }
    
    server {
        # ...
        location /health {
            internal;
            health_check interval=5s uri=/test.php match=statusok;
            proxy_set_header Host www.example.com;
            proxy_pass http://my_upstream
        }
    }
    
    match statusok {
        # Used for /test.php health check
        status 200;
        header Content-Type = text/html;
        body ~ "Server[0-9]+ is alive";
    }

    上の例では、NGINX Plusは5秒おきに/test.phpの要求を送信しています。matchブロックで、200 OKのstatusコードと、ServerN is aliveというテキストが含まれる応答本文という、そのアップストリームサーバーが健全であると見なされるための必要条件を定義しています。

    注: アクティブヘルスチェックはNGINX Plusでのみ提供される機能です。

    DNSを利用したサービスディスカバリー

    デフォルトでは、NGINX Plusサーバーは起動時にDNS名を解決し、解決値を永続的にキャッシュします。example.comなどのドメイン名を使って、serverディレクティブとresolveパラメーターによりアップストリームサーバーのグループを識別する場合、NGINX Plusは定期的にドメイン名を再解決します。関連するIPアドレスリストが変更された場合、NGINX Plusは更新されたサーバーグループに対し、ロードバランシングを即時に開始します。

    DNS SRVレコードを使用するようにNGINX Plusを設定するには、以下に示すように、serverディレクティブにservice=httpパラメーターと共にresolverディレクティブを加えます。

    resolver 127.0.0.11 valid=10s;
    
    upstream service1 {
        zone service1 64k;
        server service1 service=http resolve;
    }

    上の例では、NGINX Plusはドメイン名service1を再解決するために、10秒おきに127.0.0.11(組み込みDocker DNSサーバー)に問い合わせを行っています。

    注: DNSを利用したサービスディスカバリーはNGINX Plusでのみ提供される機能です。

    NGINX Plus API

    NGINX Plusには、単一のAPIエンドポイントと共にRESTful APIが含まれます。NGINX Plus APIを利用して、ダウンタイムを伴うことなく、アップストリーム設定とキーバリューストアをオンザフライで更新できます。

    以下に抜粋した設定には、/apiエンドポイントへのリードライトアクセスを可能にするapiディレクティブが含まれます。

    upstream backend {
        zone backends 64k;
        server 10.10.10.2:220 max_conns=250;
        server 10.10.10.4:220 max_conns=150;
    }
    
    server {
        listen 80;
        server_name www.example.org;
    
        location /api {
            api write=on;
        }
    }

    上の例のようにAPIが有効になっていれば、以下のcurlコマンドを利用して、既存のアップストリームグループに新しいサーバーを追加できます。POSTメソッドとJSONエンコーディングを利用してサーバーのIPアドレスを192.168.78.66に、重みを200に、最大同時接続数を150に設定します(versionには、リファレンスドキュメンテーションにあるAPIの現在のバージョン数が入ります)。

    $ curl -iX POST -d '{"server":"192.168.78.66:80","weight":"200","max_conns":"150"}' http://localhost:80/api/version/http/upstreams/backend/servers/

    すべてのbackendアップストリームサーバーの全設定をJSON形式で表示するには、以下のコマンドを実行します。

    $ curl -s http://localhost:80/api/version/http/upstreams/backend/servers/ | python -m json.tool
    	{
          "backup": false,
          "down": false,
          "fail_timeout": "10s",
          "id": 0,
          "max_conns": 250,
          "max_fails": 1,
          "route": "",
          "server": "10.10.10.2:220",
          "slow_start": "0s",
          "weight": 1
          },
          {
          "backup": false,
          "down": false,
          "fail_timeout": "10s",
          "id": 1,
          "max_conns": 150,
          "max_fails": 1,
          "route": "",
          "server": "10.10.10.4:220",
          "slow_start": "0s",
          "weight": 1
          },
          {
          "backup": false,
          "down": false,
          "fail_timeout": "10s",
          "id": 2,
          "max_conns": 200,
          "max_fails": 1,
          "route": "",
          "server": "192.168.78.66:80",
          "slow_start": "0s",
          "weight": 200
          }

    既存のアップストリームサーバーの設定を変更するには、上記の出力のidフィールドにある内部IDによりサーバーを識別します。以下のコマンドでは、PATCHメソッドを利用してID 2のサーバーを再設定し、IPアドレスとリスニングポートを192.168.78.55:80に、重みを500に、接続制限を350に設定しています。

    $ curl -iX PATCH -d '{"server":"192.168.78.55:80","weight":"500","max_conns":"350"}' http://localhost:80/api/version/http/upstreams/backend/servers/2

    https://demo.nginx.com/swagger-ui/から、NGINX Plus APIのSwagger(OpenAPI仕様)ドキュメンテーションの完全版にアクセスできます。

    注:NGINX Plus APIはNGINX Plusでのみ提供される機能です。