在分布式系統中,因為涉及到大量的機器,是以部署略微有些繁瑣。
使用Erlang開發的系統,我們可以通過boot_server來加載我們的代碼,免去了ssh登陸伺服器,更新代碼這樣繁瑣的步驟。我們隻需要将最新的beam檔案放到一個server,作為Erlang的boot_server,其他的機器啟動Erlang時,通過連接配接這個Boot Server加載最新的應用代碼,完成程式的啟動。
架設Server ip為:8.17.85.135
其中一個Client為: 124.118.219.104
啟動一個Boot Server涉及的主要子產品為erl_boot_server,我們可以通過erlang_boot_server:start/1啟動boot server,通過erl_boot_server:add_slave/1加載一個slave,也就是允許連接配接本機進而加載代碼的client。我們也可以通過kernel config來啟動boot server,這樣更簡單:
bserver.config:
[
{kernel, [{start_boot_server, true} ,
{boot_server_slaves, [{124,118,219,104}]}]}
].
(注:根據Erlang 文檔,slave可以采用atom, string, tuple多種方式來表示,可是我嘗試隻能使用tuple,不知是否bug?)
随後啟動
erl -setcookie "cookie" -config bserver
至此,我們的boot server就啟動成功了,接下來讓我們的client從boot server啟動。
client:
erl -loader inet -hosts "8.17.85.135" -id node1 -setcookie "cookie"
很遺憾,在我的機器,沒有啟動成功,因為我client是widnows xp系統。
boot server啟動對client的要求
1. Slave在Boot Server的Slaves清單中
2. Erlang OTP版本相同
3. Cookie設定相同
4. 路徑一緻
以上4點不一定準确,需要我回頭在家中的linux上進行嘗試,呵呵,本人保留對以上4點要求修改的的權力 :)
根據文檔循規蹈矩的走了一遍,有很多疑問和不解,需要去代碼中遨遊一翻了。
根據init.erl, kernel.erl, erl_prim_loader.erl我簡單的羅列了下面的啟動過程:
erl啟動過程:
1. shell中輸入 erl ......
2. emulator調用init:boot/1啟動(通過 erlang:whereis(init)傳回pid為<0,0,0>,init是第一個process)
3. 啟動erl_prim_loader,其負責擷取具體的檔案從本地(efile)或遠端的boot_server(inet)
4. 根據-boot選項,擷取boot script檔案名稱,通過erl_prim_loader擷取boot腳本
5. 解析boot script,調用init:eval_script/8執行對應的語句
6. boot script執行完成後,調用init:start_em/1啟動erl參數中-s -run對應的子產品
7. 執行完畢,啟動完成
對于Erlang系統的啟動是根據boot script,通過erl_prim_loader從local或server擷取具體的module BinCode
随後通過erlang:load_module加載。
有個問題,這裡的erl_prim_loader,要麼是通過efile,要麼是通過inet,有沒有一個hybrid的版本呢,我可以讓部分 module通過inet加載,而部分通過local加載,通過修改boot.script可以麼?這個需要尋找一個好的方案,期待答案....