Elixir clustering with DNS SRV records.
The package can be installed by adding dns_srv_cluster
to your list of dependencies in mix.exs
:
def deps do
[
{:dns_srv_cluster, "~> 0.3.0"}
]
end
Add to your DNS zone your SRV record (https://en.wikipedia.org/wiki/SRV_record):
_app._tcp.yourdomain.com. 60 IN SRV 0 10 1234 node1.yourdomain.com.
_app._tcp.yourdomain.com. 60 IN SRV 0 10 1234 node2.yourdomain.com.
_app._tcp.yourdomain.com. 60 IN SRV 0 10 1234 node3.yourdomain.com.
_app._tcp.yourdomain.com. 60 IN SRV 0 10 1234 node4.yourdomain.com.
Add to your config files (config/prod.exs
, config/dev.exs
):
config :dns_srv_cluster,
query: "_app._tcp.yourdomain.com"
Add this to your rel/env.sh.eex
:
export RELEASE_DISTRIBUTION="${RELEASE_DISTRIBUTION:-"name"}"
export RELEASE_NODE="${RELEASE_NODE:-"<%= @release.name %>"}"
By default, nodes from the same release will have the same cookie. If you want different
applications or releases to connect to each other, then you must set the RELEASE_COOKIE
,
either in your deployment platform or inside rel/env.sh.eex
:
export RELEASE_COOKIE="my-app-cookie"
query
- your DNS SRV record, for example: "_app._tcp.yourdomain.com".interval
- the millisec interval between DNS queries. Defaults to5_000
.connect_timeout
- the millisec timeout to allow discovered nodes to connect. Defaults to10_000
.
Do in mix.exs
:
def deps do
[
{:dns_srv_cluster, "~> 0.3.0", runtime: false}
]
end
runtime: false
will block application from starting.
And use DNSSRVCluster.Worker
as a child:
children = [
{DNSSRVCluster.Worker, query: "_app._tcp.yourdomain.com"}
]
{:ok, pid} = Supervisor.start_link(children, strategy: :one_for_one)
Tests automatically run against a matrix of OTP and Elixir Versions, see the ci.yml for details.
OTP \ Elixir | 1.15 | 1.16 | 1.17 |
---|---|---|---|
24 | ✅ | ✅ | N/A |
25 | ✅ | ✅ | ✅ |
26 | ✅ | ✅ | ✅ |
27 | N/A | N/A | ✅ |
Documentation can be found at https://hexdocs.pm/dns_srv_cluster.