プロジェクト

全般

プロフィール

RedmineでNginxのX-Accel-Redirectを使ってダウンロードの効率化

大きなファイルをRedmineからダウンロードする際の問題

Nginx + Unicornでの問題と解決方法

Redmineに添付したファイルを取得するリクエストを受けると、Unicornのワーカープロセスでファイルを読み込んでNginxに転送する処理が動きます。
この処理はダウンロードが完了するまでの間、ワーカープロセスは使用中となる((リクエスト元のブラウザでダウンロードが完了するまでの模様。Nginxに渡しておしまいではないらしい))ので、例えばワーカープロセス3つのサイトで大きなファイルのダウンロードが3つリクエストされると、以降のリクエストが待たされてしまいます。

添付ファイルのサイズを1秒以内で終わるような小さなサイズに制限しても差し支えない運用であればいいのですが、ソフトウェア開発プロジェクトでは往々に大きな容量のファイルを添付することが必要になります。

Ruby on Railsでは、X-Sendfileの設定をするとファイルの転送を自身で処理せずに外部に委ねることができるので、それをNgins側に任せてUnicornのワーカープロセスはさっさと次のリクエストの待機に回ります。参考文献によると、Railsは通常はファイル本体を読み込みながらResponse Bodyとして送信しますが、X-Sendfile設定では代わりにファイルのパスをHTTPヘッダーに付与してResponse Bodyを空で終わらせ、Nginx側でHTTPヘッダーのファイルパスを読み込みファイルを送信します。

Nginx使用時のX-Accel-Redirect設定

Redmine(Rails)の設定1

Redmineインストールディレクトリ下のconfig/additional_environment.rbに以下を記述します。
デフォルトではadditional_environment.rbは存在せず、additional_environment.rb.exampleが存在するので、リネームして使用します。

config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect'

Nginxの設定ファイルに追記します。
例)/etc/nginx/conf.d/redmine.conf


-- redmine.conf.1      2014-08-23 23:27:23.323532819 +0900
+++ redmine.conf.2      2015-09-06 22:00:47.826560256 +0900
@@ -17,6 +17,18 @@

     try_files $uri/index.html $uri.html $uri @app;
+
+    location /attachments {
+        proxy_redirect off;
+        proxy_set_header X-Sendfile-Type X-Accel-Redirect;
+        proxy_set_header X-Accel-Mapping /var/lib/redmine-3.1.0/files=/files;
+        proxy_pass http://unicorn-redmine;
+    }
+
+    location /files {
+        root /var/lib/redmine/;
+        internal;
+    }

     location @app {
         proxy_set_header X-Real-IP $remote_addr;
  • proxy_set_header X-Accel-Mapping において、シンボリックリンクのパス(/var/lib/redmine/files)を指定したところ、エラーとなってしまいましたので、実パスで記述しています。Redmineバージョンアップ時は忘れずにこちらを修正する必要があります。

Redmine(Rails)の設定2

先の設定では、チケットへ添付した画像ファイルのサムネイル表示、thumbnailマクロによるサムネイル表示がうまくいきません。
チケットの添付画像のサムネイル表示はURLが/attachments/<添付ファイルID>/<ファイル名>となっており、また、thumbnailマクロはURLが/attachments/thumbnail/<添付ファイルID>/<サイズ指定値>となっています。
これらは、動的に生成されるコンテンツですので、X-Accel-Redirectされてはならなかったのです。

-    location /attachments {
+    location /attachments/download {

と設定を変更することで回避します。

1 添付ファイルのサムネイル画像を表示する設定を有効にしているとき、サムネイル画像が表示されません(リンクエラー状態)

2 サムネイル表示の不具合回避設定

参考文献

クリップボードから画像を追加 (サイズの上限: 1 GB)