elixir 高可用系列(一) Agent

2021-09-08 11:48:24 字數 2352 閱讀 6208

elixir 本身是一種 immutable 的語言,預設情況下,程序間是不共享任何狀態的,程序之間通過訊息來互動。

而 agent 則封裝了一種程序間共享狀態的方式,通過這種方式,不用顯式的寫 send/receieve 的**,就能方便的在程序之間共享狀態。

首先,看乙個在不用 agent 的情況下,如何獲取程序狀態的例子。

defmodule withoutagent do

def start do

map.new()

enddef get(map, key) do

if map.has_key?(map, key) do

map.get(map, key)

else

nilend

enddef put(map, key, val) do

map.put(map, key, val)

enddef delete(map, key) do

map.delete(map, key)

endend

測試 withoutagent 的使用:

iex> m = withoutagent.start

%{}iex> withoutagent.get(m, "map-key")

niliex> m = withoutagent.put(m, "map-key", "map-val")

%iex> withoutagent.get(m, "map-key")

"map-val"

iex> m = withoutagent.delete(m, "map-key")

%{}iex> m = withoutagent.get(m, "map-key")

nil

從上面的使用可以看出,為了使用 withoutagent 中的狀態(乙個 map),外部還必須要自己管理 withoutagent 的返回的狀態 m,

通過 withoutagent 來改變狀態時,每次都要將當前狀態 m 作為乙個引數傳給 withoutagent。

只有乙個程序使用 withoutagent 時,上述方式沒有什麼問題,當有多個程序使用 withoutagent,每個程序持有的狀態 m 很難保持一致。

elixir 中的 agent 其實並不是 elixir 發明的新東西,而是封裝了 erlang otp 中現有的 ets (erlang term storage)

使用 agent 來重新實現上面的例子:

defmodule withagent do

def start do

agent.start_link(fn -> map.new end, name: __module__)

enddef get(key) do

agent.get(__module__, fn map ->

if map.has_key?(map, key) do

map.get(map, key)

else

nilend

end)

enddef put(key, val) do

agent.update(__module__, &map.put(&1, key, val))

enddef delete(key) do

agent.get_and_update(__module__, fn map ->

if map.has_key?(map, key) do

map.pop(map, key)

else

nilend

end)

endend

測試 withagent 的使用:

iex> withagent.start

iex> withagent.get("map-key")

niliex> withagent.put("map-key", "map-val")

:okiex> withagent.get("map-key")

"map-val"

iex> withagent.delete("map-key")

"map-val"

iex> withagent.get("map-key")

nil

從上面的使用中可以看出,使用了 agent 之後,使用方完全不用自己管理 withagent 的狀態,只要操作狀態即可。

這樣,多個程序同時使用 withagent 時,也不用管狀態衝突的事情,狀態如果有衝突也是在 withagent 中自己管理。

總的來說,agent 就是狀態的簡單的封裝,方便程序間狀態的共享。

此外,除了上面用的方法,agent 中的所有方法參照:agent

elixir 高可用系列(一) Agent

elixir 本身是一種 immutable 的語言,預設情況下,程序間是不共享任何狀態的,程序之間通過訊息來互動。而 agent 則封裝了一種程序間共享狀態的方式,通過這種方式,不用顯式的寫 send receieve 的 就能方便的在程序之間共享狀態。首先,看乙個在不用 agent 的情況下,如...

elixir 高可用系列(一) Agent

elixir 本身是一種 immutable 的語言,預設情況下,程序間是不共享任何狀態的,程序之間通過訊息來互動。而 agent 則封裝了一種程序間共享狀態的方式,通過這種方式,不用顯式的寫 send receieve 的 就能方便的在程序之間共享狀態。首先,看乙個在不用 agent 的情況下,如...

mysql系列 mha高可用

一 切換流程 1 mha通過主探測服務和第二檢測指令碼判斷主庫服務不可用 2 獲取所有存活從庫最新讀取的mysql binlog位點,進行對比,或許最新的位點資訊 3 如果主庫伺服器還能連線,根據位點資訊拷貝位點之後的差異binlog 4 選擇新主 1 如果沒有新主配置,則選擇最新位點資訊的從庫 2...