Nginx+unicorn-introduction

【nginx+unicorn導入メモ】2013/06/02~

Railsアプリにおいて静的資源をnginxに、rackサーバ上で動作する動的資源についてはunicornに担当させる構成について とりあえず導入まで。最適化に関しては別稿に譲る


■nginx導入

○nginx導入前準備

2013/06/02時点において、aptitudeでのnginxパッケージの既定バージョンは0.7.67と古いため、nginx公式サイトをリポジトリに登録し、aptitudeでstable最新版をインストールできるようにする

1. まずパッケージの公開鍵をダウンロードしてapt-keyで追加する

1
2
$ wget "http://nginx.org/keys/nginx_signing.key"
$ sudo apt-key add nginx_signing.key

2. 次にnginx公式サイトをリポジトリに追加する

次のファイルに追加する

1
$ sudo vim /etc/apt/sources.list
1
2
deb http://nginx.org/packages/debian/ squeeze nginx
deb-src http://nginx.org/packages/debian/ squeeze nginx

3. リポジトリの追加を反映する

1
$ sudo aptitude update

インストール可能なバージョンが更新されているか確認する

1
$ aptitude show nginx

2013/06/02時点でイントール可能なバージョンは、「1.4.1-1~squeeze」である

○nginx導入

aptitudeコマンドにてnginxをインストールする

1
$ sudo aptitude install nginx

以下のコマンドで正常にインストールできたか確認する

1
$ aptitude show nginx
1
2
3
4
5
6
7
8
9
10
11
12
13
パッケージ: nginx
状態: インストール済み
自動的にインストールされた: no
バージョン: 1.4.1-1~squeeze
優先度: 任意
セクション: httpd
メンテナ: Sergey Budnevitch <sb@nginx.com>
展開サイズ: 1,102 k
依存: libc6 (>= 2.10), libpcre3 (>= 7.7), libssl0.9.8 (>= 0.9.8m-1), zlib1g (>= 1:1.1.4), lsb-base, adduser
提供: httpd
説明: HTTP and reverse proxy server, as well as a mail proxy server
 written by Igor Sysoev
ホームページ: http://nginx.org

バージョン確認

1
2
3
$ /usr/sbin/nginx -v

nginx version: nginx/1.4.1

■nginx起動/停止

○起動
1
$ sudo /etc/init.d/nginx start

http://192.168.56.1/ 等、起動したサーバへアクセスし、「Welcome to nginx!」と表示されるか確認する

○停止
1
$ sudo /etc/init.d/nginx stop

※ 以下のエラーが出る場合には、何らかのプログラムが80番ポートを塞いでいる可能性があるので、そのプログラムを停止しておく

1
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)

例) 80番ポートを塞いでいるプログラムを探し、停止する

1
2
3
4
5
6
$ sudo lsof -i:80

COMMAND  PID     USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
apache2 1768     root    5u  IPv6   4665      0t0  TCP *:www (LISTEN)

$ sudo /etc/init.d/apache2 stop

■nginx設定

1
/etc/nginx/conf.d/default.conf

default.confを元に編集した 元となったdefault.confは、default.conf.backupとして保存した

○設定のポイント
  1. ソケットファイルのパスをunicornで設定するそれ(後述)と一致させること
  2. ポート番号に留意すること
  3. プロキシパスを設定すること

注)コメントアウトされている箇所については割愛した

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
upstream unicorn.railsapp {
    server unix:/home/philippos/coxcomb/tmp/sockets/unicorn.sock;
}

server {
    listen       80;
    server_name  localhost;

    location / {
        root   /home/philippos/coxcomb/public;
        index  index.html index.htm;

        proxy_pass http://unicorn.railsapp;
    }

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

■unicorn導入

  • Railsアプリディレクトリ以下のGemfileにunicornを追加する
  • bundle install した後、configフォルダに設定ファイルとして、unicorn_config.rbを作成する
  • 内容は後述
○起動確認
  • -Dオプションを追加することでデーモンとして起動する
  • デーモンを停止させるにはpsコマンドで該当プロセルを探し、kill -9 コマンドでpidを指定して停止させる
■起動
1
$ unicorn_rails -c config/unicorn_config.rb -E production -D
■停止

起動中のプロセスを検索し、unicornのマスタープロセスのみ停止させる。

1
2
3
4
5
6
7
8
9
10
11
$ ps aux | grep unicorn

133:1000      9174  0.1 16.9 736356 64496 ?        Sl   06:52   0:01 unicorn_rails master -c config/unicorn_config.rb -E production -D                                                                                                                    
134:1000      9180  0.0 18.3 746884 69880 ?        Sl   06:52   0:00 unicorn_rails worker[0] -c config/unicorn_config.rb -E production -D                                                                                                                 
135:1000      9183  0.0 18.5 747356 70280 ?        Sl   06:52   0:00 unicorn_rails worker[1] -c config/unicorn_config.rb -E production -D                                                                                                                 
136:1000      9186  0.0 16.4 738984 62556 ?        Sl   06:52   0:00 unicorn_rails worker[2] -c config/unicorn_config.rb -E production -D                                                                                                                 
137:1000      9189  0.0 18.0 745620 68404 ?        Sl   06:52   0:00 unicorn_rails worker[3] -c config/unicorn_config.rb -E production -D                                                                                                                 
141:1000      9428  0.1  1.1  36220  4204 pts/1    S+   07:01   0:00 vim source/_posts/2013-07-07-nginx-plus-unicorn-introduction.markdown
143:1000      9452  0.0  0.2  11328   936 pts/0    S+   07:04   0:00 grep -n unicorn

$ kill -9 9174

■unicorn設定

  • Railsアプリディレクトリ以下connfig/unicorn_config.rb
  • ソケットファイルのパス、ポート番号、ログ出力先等に留意する
  • それらをnginxの設定と同一にする必要がある

例)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# coding:utf-8
# unicron.rb
worker_processes  4
working_directory '/home/philippos/coxcomb'

listen '/home/philippos/coxcomb/tmp/pids/unicorn.sock', :backlog => 1
listen 4422, :tcp_nopush => true

pid '/home/philippos/coxcomb/tmp/sockets/unicorn.pid'

timeout 10

stdout_path '/home/philippos/coxcomb/log/unicorn.stdout.log'
stderr_path '/home/philippos/coxcomb/log/unicorn.stderr.log'

preload_app true
GC.respond_to?(:copy_on_write_friendly=) and GC.copy_on_write_friendly = true

before_fork do |server, worker|
defined?(ActiveRecord::Base) and ActiveRecord::Base.connection.disconnect!

old_pid = "#{server.config[:pid]}.oldbin"

if old_pid != server.pid
  begin
    sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU
    Process.kill(sig, File.read(old_pid).to_i)
  rescue Errno::ENOENT, Errno::ESRCH
  end
end

sleep 1
end

after_fork do |server, worker|
  defined?(ActiveRecord::Base) and ActiveRecord::Base.establish_connection
end

■その他

abコマンド:サイトが1秒間に何アクセス捌けるか確認するコマンド

1
$ ab -c 10 -n 100 http://example.com/

○thinサーバの場合……

1
Requests per second:    11.22 [#/sec] (mean)

○nginx + unicornの場合……

1
Requests per second:    105.77 [#/sec] (mean)
■rails設定

config/environments/production.rb内の設定は、以下のようにすること。

  • 静的ファイルの扱いを rails 本体ではなく、nginx に移譲する。

config.serve_static_assets = false

  • アセットパイプラインのライブコンパイルを有効にする。

config.assets.compile = true

以上