akishin999の日記

調べた事などを書いて行きます。

ngx_small_light で動的に画像リサイズ

この前インストールした mod_small_light の Nginx 版、ngx_small_light をインストールしてみました。

cubicdaiya/ngx_small_light
https://github.com/cubicdaiya/ngx_small_light

このモジュールを使うと Nginx でも Apache + mod_small_light と同じ感じで画像の自動リサイズなどが行えるようになります。

検証したのは以下の環境になります。

今回は ImageMagickOpenMP が有効なものを使用しました。

インストール準備

まずは依存ライブラリをインストールします。

# yum install -y pcre-devel zlib-devel openssl-devel gd-devel

imlib2 を EPEL からインストール。

# yum install http://dl.fedoraproject.org/pub/epel/6/x86_64/imlib2-1.4.2-5.el6.x86_64.rpm \
              http://dl.fedoraproject.org/pub/epel/6/x86_64/imlib2-devel-1.4.2-5.el6.x86_64.rpm

ImageMagick をインストール。

# yum install ImageMagick-6.8.5-10.x86_64.rpm \
              ImageMagick-devel-6.8.5-10.x86_64.rpm

Nginx のユーザとグループも作成しておきます。

# groupadd nginx
# useradd -g nginx -c 'nginx HTTP and reverse proxy server' -d /var/empty/nginx -s /sbin/nologin nginx

インストール

Nginx は Apache の DSO のような動的モジュールに対応していないので、モジュールの設定を行った後に本体をビルドして静的に組み込む必要があります。

というわけで ngx_small_light を clone して setup を実行し、config ファイルを生成します。

# cd /usr/local/src/
# git clone git://github.com/cubicdaiya/ngx_small_light.git
# cd ngx_small_light/
# ./setup --with-imlib2 --with-gd

Nginx 本体のソースコードをダウンロードして展開します。

# cd /usr/local/src/
# wget http://nginx.org/download/nginx-1.5.1.tar.gz
# tar xzf nginx-1.5.1.tar.gz
# cd nginx-1.5.1

「--add-module」に先ほど ngx_small_light を clone したディレクトリのパスを指定して configure を実行します。
その他のオプションは用途に合わせてお好みで指定してください。

# ./configure --prefix=/usr/local/nginx-1.5.1 \
              --user=nginx \
              --group=nginx \
              --with-pcre \
              --with-http_ssl_module \
              --with-http_realip_module \
              --with-http_stub_status_module \
              --add-module=/usr/local/src/ngx_small_light

configure 後に表示される「Configuration summary」の内容を確認し、問題なければ make してインストールします。
ソースコードから入れるので make install は Paco 経由で行いました。

# make
# paco -D make install

以下で configure 時のオプションを表示すると ngx_small_light が組み込まれていることが確認できます。

# /usr/local/nginx-1.5.1/sbin/nginx -V
nginx version: nginx/1.5.1
built by gcc 4.4.7 20120313 (Red Hat 4.4.7-3) (GCC)
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx-1.5.1 --user=nginx --group=nginx --with-pcre --with-http_ssl_module --with-http_realip_module --with-http_stub_status_module --add-module=/usr/local/src/ngx_small_light

起動スクリプトの設定

最後に起動スクリプトから Nginx を起動するための設定をいくつか行っておきます。
シンボリックリンクを作成します。

# ln -s /usr/local/nginx-1.5.1 /usr/local/nginx

起動スクリプトをインストール。

# wget -O /etc/init.d/nginx 'http://wiki.nginx.org/index.php?title=RedHatNginxInitScript&action=raw&anchor=nginx'
# chmod +x /etc/init.d/nginx

スクリプト内容を環境に合わせて編集します。

# vi /etc/init.d/nginx

ここでは 22 行目の Nginx 本体のパスと 25 行目の設定ファイルのパスを以下のように書き換えました。

・・・
22 nginx="/usr/local/nginx/sbin/nginx"
・・・
25 NGINX_CONF_FILE="/usr/local/nginx/conf/nginx.conf"

サービスとして登録しておきます。

# chkconfig --add nginx
# chkconfig --list nginx
nginx           0:off   1:off   2:off   3:off   4:off   5:off   6:off

これでインストールは完了です。

OMP_NUM_THREADS の設定

ImageMagickOpenMP が有効な場合、そのまま Web サーバから呼び出しているとサーバが高負荷になってしまう問題があります。
この問題を回避するため、環境変数 OMP_NUM_THREADS に 1 を設定した状態で Nginx を起動するようにします。

Nginx 起動時に設定する環境変数などを指定するために、 /etc/sysconfig/nginx というファイルを作成します。

# vi /etc/sysconfig/nginx

このファイルは先ほど配置した起動スクリプトから読み込まれるようになっています。

以下を記述します。

export OMP_NUM_THREADS=1

これで OpenMP が使用するコア数が 1 に制限され、OpenMP が有効の ImageMagick でもサーバが高負荷になることは避けられます。

ちなみに、Apache と異なり、Nginx の場合、プロセスの環境変数を確認するために /proc/$pid/environ を確認してみても何故か値が表示されません。

# strings /proc/`pgrep nginx | head -1`/environ

ただ、ab で実際に負荷をかけて調べてみたところ、どうやらちゃんと設定は有効になっているようでした。

使ってみる

まずは適当な画像を用意します。
前回同様、大きめの画像を「/var/images」以下に配置しました。

# mkdir /var/images
# 適当に大きめの画像を配置しておく
# mv ~/oshiruko.jpg /var/images/

nginx の設定ファイルを編集します。

# vi /usr/local/nginx/conf/nginx.conf

デフォルトの server ディレクティブ内に以下のような small_light の設定を追加してみます。

small_light on;
small_light_pattern_define ssize dw=150,dh=150,da=l,q=95,e=imlib2,jpeghint=y;
location ~ small_light[^/]*/(.+)$ {
   set $file $1;
   rewrite ^ /$file;
}

location /images/ {
  alias /var/images/;
}

パターンのパラメータの詳細についてはこちら
変更を保存したら、文法チェックをして nginx を起動します。

# service nginx configtest
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
# service nginx start

これで「http://サーバ名/small_light(p=ssize)/images/画像ファイル名.jpg」でアクセスすると画像が縮小して表示されるはずです。

普通にアクセスすると以下のような感じでオリジナルの画像が表示されます。

同じ画像に対して URL に /small_light(p=ssize)/ を付けてアクセスするとこんな感じ。

ちゃんと縮小されていますね。

次は Apache 版と同じく、URL で画像サイズを指定できるようにしてみます。

nginx.conf に先ほど追加した設定を以下のように変更します。

small_light on;
location ~ ^/resize/w/(.+)/h/(.+)/(.+)$ {
  set $width $1;
  set $height $2;
  set $file $3;
  proxy_pass http://127.0.0.1/small_light(dw=$width,dh=$height)/images/$file;
}

location ~ small_light[^/]*/(.+)$ {
   set $file $1;
   rewrite ^ /$file;
}

location /images/ {
  alias /var/images/;
}

変更したら設定ファイルをリロードします。

# service nginx reload

これで「http://サーバ名/resize/w/画像の幅/h/画像の高さ/image01.jpg」でアクセスすれば指定したサイズに画像を縮小できるようになりました。

  • 500x500


  • 150x150


変換ルールもシンプルに書けるし、機能も豊富なので、Nginx を使用している環境なら Image Filter よりこちらの方が良さそうですね。
Apache 版と同じ感覚で使えるのもいい感じです。


ちなみに本文とは関係ないですが、写真の猫は実家で飼っている愛猫のおしるこです。
人見知りですが、とても穏やかな性格で他の猫達とも仲良しないい子です。