UnicornでSO_REUSEPORTを使う


はじめに

Dockerでホットデプロイをする際にコンテナの入れ替えを単一サーバで実現したい。
SO_REUSEPORTを使うことで簡単に実現できそうです。

動作環境

Linuxカーネル: 3.9以上
Unicorn: 4.7.0以上

SO_REUSEPORTに対応したバージョンは以上となっています。

WEBアプリ構成

+ app
  - Gemfile
  - config.ru
  - unicorn.ru
Gemfile
source "https://rubygems.org"

gem 'sinatra'
gem 'unicorn'
config.ru
require 'sinatra/base'

class SampleApp < Sinatra::Base
  get '/' do
    "hello\n"
  end
end
run SampleApp

Sinatraアプリの作成。識別用にhelloというメッセージが表示されるようにしときます。

dir = File.expand_path(".")

worker_processes 2
working_directory dir

listen 3000, :reuseport => true

ポートの待受にreuseportオプションが使えるので指定します。

WEBアプリの起動

$ unicorn -c unicorn.rb

次にWEBアプリの内容を変更して、別アプリとして起動します。

config.ru
require 'sinatra/base'

class SampleApp < Sinatra::Base
  get '/' do
-    "hello\n"
+    "hello world\n"
  end
end
run SampleApp

起動します。

$ unicorn -c unicorn.rb

動作確認

$ curl http://localhost:3000/
hello
$ curl http://localhost:3000/
hello world

同じポートで起動したアプリにそれぞれアクセスできています。