keisyuのブログ

最近めっきりエンジニアリングしなくなった厄年のおじさんがIT技術をリハビリするブログ。

nginxとリバースプロキシでモダンなシステム構成

nginx

今日は今どき?(といっても世間では既に主流な構成な感はありますが)nginx&リバースプロキシを用いたシステム構成を実験で作ってみたいと思います。
nginx はイベント駆動型のウエブーサーバでありApacheでいうところのMPM Prefork/workerとは異なる構成なのでメモリ使用量が少なく動作することと一つの処理が低コストな場合において同時接続数が多くても安定して動作することが期待できるウエブサーバです

Apacheをフロントに設置してシステムを構成する場合、一昔前はなどと3層のシステム構成(もしくはAPIを外した2層)にすることが主流でした。A

User <====> Apache <----> API <----> DB

C10K問題*1に直面するケースは少ないにしろ比較的大規模なサービスにおいて同時接続をサポートするとフロント(ユーザがアクセスするサーバ)を並列に並べる必要がでてきます.この問題を解決するためにフロントエンドにnginxを配置してユーザの接続を受け付け処理はバックエンドのサーバに流す(リバースプロキシ)の構成が流行っているようです。

User <====> nginx <----> WebServer <----> DB
  • 静的コンテンツはnginx 側で配信
  • 動的なコンテンツはリバースプロキシでバックエンドに配置されたウエブサーバに振り分ける
  • nginx自体がロードバランサの役目も持っている

インストール

epel のリポジトリに少々古いですが(1.0.15-5.el6) パッケージがあるようなので yum でインストールしてみます。

$ sudo yum install nginx
$ /usr/sbin/nginx -V
nginx version: nginx/1.0.15
built by gcc 4.4.7 20120313 (Red Hat 4.4.7-3) (GCC) 
TLS SNI support enabled
configure arguments: --prefix=/usr/share/nginx --sbin-path=...

nginxはapacheのDSOのような動的なモジュールの組み込みができず、コンパイルやり直しが必要らしいです。今の時点でのモジュールの組み込み具合は -V のオプションを付けて起動すると確認できます。とりあえずは何も考えずに起動 ( $ sudo /sbin/services nginx start )すると以下のような画面が立ち上がります。
f:id:keisyu:20140221143438j:plain:w300
詳しく見ていきます。設定ファイルは /etc/nginx/nginx.conf と、そこからincludeされる /etc/nginx/conf.d/*.confが主な設定ファイルです

$ ls  /etc/nginx/conf.d/
default.conf  ssl.conf  virtual.conf

記載されている nginx.conf で設定のフォーマットとしては以下のように記述するようです。

coreモジュールの設定
events {
    eventモジュールの設定
}
http {
    httpモジュールの設定
}
server {
    virtual serverの設定 (conf.d/default.conf or virtial.conf)
}

主要な設定

worker_processes core nginxのworkerプロセスの数, CPUの個数と同じにするのが効果的(それ以上にしても意味がない)
worker_connections event 一つのworkerプロセスが同時に処理できる最大コネクション数を設定

リバースプロキシの設定

せっかくなのでリバースプロキシの設定をやってみます。nginxを起動したサーバがゲストOSのCentOSでありバックエンドに相当するウエブサーバを
Amon2を使ったアプリ開発 (その2) - keisyuのブログ でつくったシンプルな掲示板と想定しますすなわち以下のようなややこしい感じです。

User(ホストPC) <----> nginx (CentOS:VirtualBox) <---> Server (ホストPC)

以下のようにconf.d/default.conf を編集します

upstream bbs_server {
    ip_hash;
    server 192.168.56.1:5000;
}
server {
    ...
    ...
    location / {
        proxy_pass http://bbs_server/;
    }
    ...

これで一応はリバースプロキシとして動作します。nginxのPort80 "/" にアクセスすると 192.168.56.1:5000 で起動する plackup されたWebサーバにアクアクセスしてコンテンツが応答されます。その他リバースプロキシの設定はたくさんあるので必要に応じて調べてみる(X-Forwarded-For とか)

最新版の利用

最新の安定版は1.4.5らしいです。これを利用するために本家からダウンロードしてコンパイルしてみます。configure で epel でインストールした版の -V で確認したオプションと同じものを定義してみることにします。

$ sudo rpm -e nginx  # yum で入れたのを消しとく
$ curl -LO http://nginx.org/download/nginx-1.4.5.tar.gz
$ tar zxvf nginx-1.4.5.tar.gz
$ cd nginx-1.4.5
$ ./configure --prefix=/usr/share/nginx ... #(epel版の -V で出てきたのをそのまま使う)
$ sudo make install

configure で色々モジュールが足りないと言われて結局いかのものをyumでインストールした

pcre-devel, openssl-devel, libxslt-devel, gd-devel, perl-ExtUtils-Embed, GeoIP-devel

インストール完了すると

$ /usr/sbin/nginx -V
nginx version: nginx/1.4.5
built by gcc 4.4.7 20120313 (Red Hat 4.4.7-4) (GCC) 
TLS SNI support enabled
configure arguments: --prefix=/usr/share/nginx --sbin-path=...

最新安定バージョンで動作します。/etc/init.d/nginx がrpm -e で消えて install で生成されないけどググれば見つかる。
f:id:keisyu:20140221162823j:plain:w300