在Phoenix使用SO_REUSEPORT

时间:2017-01-27 00:36:07

标签: network-programming erlang elixir phoenix-framework

我对零停机部署系统感兴趣,该系统不使用Elixir / Erlang热升级(由于代码运行时数据迁移的复杂性)。

我听说在将服务器绑定到适配器时,我可以使用SO_REUSEPORT选项,这样我就可以运行绑定到同一地址和端口的同一应用程序的两个实例。我的意图是在与运行版本1相同的服务器上部署版本2,启动版本2,然后优雅地停止版本1,这应该允许传入连接自然地开始专门连接到版本2.

无论这是否与我的计划完全一致 - 我的意图是测试此配置,因为它知道它在不同的操作系统上的行为不同 - 我想知道配置Phoenix执行此操作所需的具体步骤,因为这似乎是:gen_tcp中的较低级别配置。

或者,如果有一种方法可以配置操作系统或Erlang VM以默认启用此选项的所有连接,那就更好了。

1 个答案:

答案 0 :(得分:0)

您应为套接字指定原始SO_REUSEPORT标志,格式为{:raw, protocol, option_num, value_bin} gen_tcp option/raw并将其传递给基础传输。

请注意,mac / linux的标志是不同的。在您的config.exs中:

so_reuseport =
  case :os.type() do
    {:unix, :linux} -> {:raw, 1, 15, <<1::32-native>>}
    {:unix, :darwin} -> {:raw, 0xffff, 0x0200, <<1::32-native>>}
  end

config :yourapp, YourApp.Endpoint,
  http: [port: {:system, "PORT"}, transport_options: [socket_opts: [so_reuseport]]]

在Phoenix 1.4.9上进行了测试,但是我想较早的版本也可以。 这是二手选项的相应文档。