designetwork

ネットワークを軸としたIT技術メモ

Docker RedmineのSMTPメール送信を非同期にして遅延を解消する

f:id:daichi703n:20180420234858p:plain

Dockerで稼働させているRedmineでのチケット作成・更新時のレスポンスが悪くなり、原因調査・対応実施して問題解消したため手順メモ。

結論としては、SMTPによるメール通知をAsync(非同期)にすることで、メール送信の完了を待たずにチケットの画面が遷移するようになり、快適な動作となった。いくつかの参考記事はあるがDocker環境での情報が見つからなかったのでメモする。

前提環境

Redmine Docker Image: sameersbn/docker-redmine

github.com

こちらのdocker-compose-ymlで各パラメータを設定している。

docker-redmine/docker-compose.yml at master · sameersbn/docker-redmine · GitHub

問題動作及び状況

今回問題と感じた動作概要・状況は以下の通り。

  • チケット作成に時間がかかる(30秒程度ブラウザのタブがくるくるマーク)
  • チケット更新に時間がかかる(30秒程度ブラウザのタブがくるくるマーク)
  • 遅いときと遅くないときがある
  • プロジェクト設定更新などの動作は全く問題ない
  • サーバ負荷は全く問題ない

類似事例がいくつかあり

Redmine チケット更新 遅い」とググるとこちらなどの情報が見つかった。

mussyu1204.myhome.cx

たしかに動作に問題がない動作はメール通知がないケースだったため、本件に該当すると推定した。config/configration.ymldelivery_method: :async_smtpと設定すればよいとのことだが、問題はDocker環境での設定方法。

Docker RedmineでのSMTP設定

先述のDocker Imageでは、基本的にdocker-compose.yml環境変数を定義することにより、Redmineの各種設定が可能となっている。SMTPに関する部分の設定例は以下の通り。(抜粋)

version: '2'

services:
  redmine:
    image: sameersbn/redmine:3.4.4-2
    depends_on:
    - postgresql
    environment:
    #<snip>
    - SMTP_ENABLED=false
    - SMTP_METHOD=smtp
    - SMTP_DOMAIN=www.example.com
    - SMTP_HOST=smtp.gmail.com
    - SMTP_PORT=587
    - SMTP_USER=mailer@example.com
    - SMTP_PASS=password
    - SMTP_STARTTLS=true
    - SMTP_AUTHENTICATION=:login
    #<snip>

sameersbn/redmineのサンプルではSMTP_METHODとしては通常のsmtpが指定されている。この場合、メール送信の完了を同期処理で待つため、メール送信のシーケンスに引きずられてRedmineのチケット更新画面の応答が遅くなることがある。

これをasync_smtpに変更する。

version: '2'

services:
  redmine:
    image: sameersbn/redmine:3.4.4-2
    depends_on:
    - postgresql
    environment:
    #<snip>
    - SMTP_ENABLED=false
-   - SMTP_METHOD=smtp
+   - SMTP_METHOD=async_smtp
    - SMTP_DOMAIN=www.example.com
    - SMTP_HOST=smtp.gmail.com
    - SMTP_PORT=587
    - SMTP_USER=mailer@example.com
    - SMTP_PASS=password
    - SMTP_STARTTLS=true
    - SMTP_AUTHENTICATION=:login
    #<snip>

これにより、環境変数が展開されて期待通りにコンテナ内のconfig/configration.ymlasync_smtpの設定がされる。(分かりやすいようにasync変更による差分-/+を記載しています)

$ docker exec -it redmine /bin/bash

root@xxx:/home/redmine/redmine# cat ./config/configuration.yml
# = Redmine configuration file
<snip>
options:
  # http://guides.rubyonrails.org/action_mailer_basics.html#action-mailer-configuration
  email_delivery:
-   delivery_method: :smtp
+   delivery_method: :async_smtp
-   smtp_settings:
+   async_smtp_settings:
      enable_starttls_auto: true
      address: "smtp.gmail.com"
      port: 587
      domain: "www.example.com"
      authentication: :login
      user_name: "mailer@example.com"
      password: "password"
      tls: false

Redmineの動作遅延が解消された

上記の通りasync_smtpに変更したところ、Redmineのチケット作成・更新等のメール送信を伴う操作の応答が遅い問題が解消された。ただし、設定の通り、メール受信には若干(数秒〜数分)のタイムラグが発生するようになった。しかし、チケット操作の遅延のストレスに比べたら全く問題ない。(リアルタイム性が問われる場合はこの限りでないが...)

まとめ - Docker RedmineSMTPメール送信を非同期にして遅延を解消する

Dockerで動作させているRedmineについて、SMTPメール通知をAsync(非同期)とすることで、チケット作成・更新時に応答が遅い問題に対処することができた。