Elixir 能夠運行在主/從, 故障轉移/接管模式下. 要使Elixir應用程序可以執行故障轉移/接管, Elixir應用程序必須是一個OTP應用程序.php
下面來建立一個包含Supervisor的Elixir項目node
mix new distro --sup
修改distro.ex
添加logger
模塊. 以記錄當觸發故障轉移/接管操做時的日誌記錄.git
defmodule Distro do use Application require Logger def start(type, _args) do import Supervisor.Spec, warn: false Logger.info("Distro application in #{inspect type} mode") children = [ worker(Distro.Worker, []) ] opts = [strategy: :one_for_one, name: Distro.Supervisor] Supervisor.start_link(children, opts) end end
Distro.Worker
是一個GenServer
: 它使用全局名稱註冊, 假設其運行在集羣中的一個節點上, 全局註冊讓咱們不用考慮其實際的運行位置, 只須要提供註冊名稱就能夠訪問.github
defmodule Distro.Worker do use GenServer require Logger def start_link do GenServer.start_link(__MODULE__, [], name: {:global, __MODULE__}) end def init([]) do {:ok, [], 1000} end def handle_info(:timeout, state) do Logger.debug "timeout" {:noreply, state, 1000} end end
編譯app
$ mix compile
本節闡述瞭如何把一個應用程序分佈到多個節點上分佈式
假設應用程序運行在3個節點上, 名稱分別爲abc
, bcd
, def
. 建立三個配置文件以下:ui
touch config/abc.config touch config/bcd.config touch config/def.config
配置文件中有3個重要的鍵值對. distributed
, sync_nodes_mandatory
和 sync_nodes_timeout
, 其中:debug
distributed
定義了分佈式應用的啓動延遲, 備用節點.日誌
sync_nodes_mandatory
定義強制要求的節點code
sync_nodes_timeout
定義了distributed
中全部節點都啓動完成須要等待的時間, 若是在此時間內要求的節點沒有所有啓動, 那麼全部節點上的應用啓動失敗.
abc.config
[ {logger,[{console,[{format,<<"$date $time $metadata[$level] $message\n">>}]}]}, {kernel, [{distributed, [ {'distro', 5000, ['abc@192.168.8.104', {'bcd@192.168.8.104', 'def@192.168.8.104'}]}]}, {sync_nodes_mandatory, ['bcd@192.168.8.104', 'def@192.168.8.104']}, {sync_nodes_timeout, 30000} ]}].
bcd.config
[ {logger,[{console,[{format,<<"$date $time $metadata[$level] $message\n">>}]}]}, {kernel, [{distributed, [ {distro,5000, ['abc@192.168.8.104', {'bcd@192.168.8.104', 'def@192.168.8.104'}]}]}, {sync_nodes_mandatory, ['abc@192.168.8.104', 'def@192.168.8.104']}, {sync_nodes_timeout, 30000} ]}].
def.config
[ {logger,[{console,[{format,<<"$date $time $metadata[$level] $message\n">>}]}]}, {kernel, [{distributed, [ {distro,5000, ['abc@192.168.8.104', {'bcd@192.168.8.104', 'def@192.168.8.104'}]}]}, {sync_nodes_mandatory, ['abc@192.168.8.104', 'bcd@192.168.8.104']}, {sync_nodes_timeout, 30000} ]}].
在不一樣的終端自動所有3個節點
iex --name abc@192.168.8.104 -pa _build/dev/lib/distro/ebin/ --app distro \ --erl "-config config/abc" iex --name bcd@192.168.8.104 -pa _build/dev/lib/distro/ebin/ --app distro \ --erl "-config config/bcd" iex --name def@192.168.8.104 -pa _build/dev/lib/distro/ebin/ --app distro \ --erl "-config config/def"
bcd
, def
是 abc
的備用節點. bcd
優先於def
, 若是abc
死掉, 應用程序會在bcd
上重啓, 若是bcd
死掉, 應用程序會轉移到def
, 這時候abc
, bcd
修復啓動後, 應用會被abc
接管.
終止(Ctrl+C兩次)節點abc@192.168.8.104
後,5秒內會在節點bcd@192.168.8.104
上重啓應用
再次啓動節點abc@192.168.8.104
後,應用在bcd@192.168.8.104
上中止, 應用被恢復後的abc@192.168.8.104
節點接管(Takeover)