Help us understand the problem. What is going on with this article?

NginxでリバースプロキシをKeepAliveしたときの性能検証

More than 5 years have passed since last update.

Nginx + Luaを用いた、ハイパフォーマンスで動的なプロキシサーバを考察中です。
そのための施策の一つとして
上流サーバへのアクセスをKeepAliveする という方法がありますが
その際、プロキシサーバにどの程度性能に変化があるのかを調査してみました。

リバースプロキシのkeepalive設定

前提条件として Nginx > 1.1.4 が必要。

upstreamに keepalive というattributeがあるのでそれを設定します。
それと同時に、プロキシヘッダーにHTTP/1.1設定などを行いましょう。

ちなみにproxy_passだけだとkeepaliveできないようです。upstream必須。

あと、もちろんバックエンドサーバ側もkeepalive設定しておきます。

upstream http_backend {
    server oreore.micro.service;

    # keepalive <connection> [single]
    #  connection: 持続する最大コネクション数
    #  single: 指定すると、複数ホスト時でも単一ホストとして扱う?
    keepalive 128;
}

server {
    ...

    location /http/ {
        proxy_pass http://http_backend;

        # HTTP 1.1を指定
        proxy_http_version 1.1;
        # Connectionヘッダーを指定
        proxy_set_header Connection "";
        ...
    }
}

性能検証

サーバ構成(EC2)

ロール インスタンスタイプ
ベンチマークサーバ t2.micro
プロキシサーバ t2.micro
バックエンドサーバ(ダミーレスポンスを返すだけ) t2.micro

OS/ミドルウェアなど

- -
OS AmazonLinux 2014.09
プロキシサーバ OpenResty 1.7.4.1

ざっくり構成

バックエンドサーバは外部ELB経由で、Webサーバへアクセスしています。

スクリーンショット 2014-10-16 23.58.09.png

ベンチマークコマンド

# clients:100 requests:50000 keepalive
# クライアントは常にhttp
weighttp -c 100 -n 50000 -k http://xx.xx.xx.xx/

プロキシサーバのNginxコンフィグ

こんな感じ(イメージです)。

    #user  nobody;
    worker_processes  1;
    worker_rlimit_nofile 10000;

    #error_log  logs/error.log;
    #error_log  logs/error.log  notice;
    #error_log  logs/error.log  info;

    #pid        logs/nginx.pid;

    events {
      use epoll;
      worker_connections  10000;
      multi_accept on;
    }

    http {
        include       mime.types;
        default_type  application/octet-stream;

        server_tokens off;

        #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
        #                  '$status $body_bytes_sent "$http_referer" '
        #                  '"$http_user_agent" "$http_x_forwarded_for"';

        #access_log  logs/access.log  main;

        keepalive_timeout      60;

        # upstream
        upstream http_backend {
            server oreore.micro.service;
        }
        upstream http_keepalive_backend {
            server oreore.micro.service;
            keepalive 128;
        }
        upstream https_backend {
            server oreore.micro.service:443;
        }
        upstream https_keepalive_backend {
            server oreore.micro.service:443;
            keepalive 128;
        }

        server {
            listen 80;
            server_name 0.0.0.0;

            #  match test(external http elb)
            location ~ /ex-elb-http/(\w+)/ {
              proxy_pass http://http_backend/?$args;
            }

            #  match test(external elb https)
            location ~ /ex-elb-https/(\w+)/ {
              proxy_pass https://https_backend/?$args;
            }

            #  match test(external http elb keepalive on)
            location ~ /ex-elb-http-keepalive/(\w+)/ {
              proxy_pass http://http_keepalive_backend/?$args;
              proxy_http_version 1.1;
              proxy_set_header Connection "";
            }

            #  match test(external https elb keepalive on)
            location ~ /ex-elb-https-keepalive/(\w+)/ {
              proxy_pass https://https_keepalive_backend/?$args;
              proxy_http_version 1.1;
              proxy_set_header Connection "";
            }

            # ...
        }

    }

評価軸

  • a) リバースプロキシ配下のバックエンドサーバがhttpでkeepaliveなし
  • b) リバースプロキシ配下のバックエンドサーバがhttpでkeepaliveあり
  • c) リバースプロキシ配下のバックエンドサーバがhttpsでkeepaliveなし
  • d) リバースプロキシ配下のバックエンドサーバがhttpsでkeepaliveあり

結果

評価軸 プロキシサーバ:CPU利用率 ベンチマーク結果:req/s CPU1%辺りで捌けるreq/s
a) http + off 22% 3400 154.54
b) http + on 38% 8060 212.11
c) https + off 41% 1746 42
d) https + on 45% 6375 141.67

※プロキシサーバのCPUを使い切れていないのはベンチマーククライアント限界です。
そのため、CPU1%辺りに捌いた数も表に入れています(ざっくり数値になってしまいますが)

まとめ

予想通り、keepalive時、特にhttps時のプロキシ負荷効率がだいぶ良くなりました。
プロキシサーバとバックエンドサーバ、双方の負荷軽減に
効果がありそうですね。


おまけ

upstreamでhttpsをバックエンドに置く場合、ポート指定を忘れずに!!!
Nginxでupstreamにhttpsなホストを設定する時の注意点

参考

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away