2014-06-13 64 views
2

我有一個erlang節點與一些應用程序。我想讓我的應用程序從一些中央服務器獲取環境變量(例如hiera server)。有沒有什麼辦法可以覆蓋.app文件中的環境變量,用從某個地方獲得的自定義變量替換它? 當然,我不想在我的應用程序代碼中進行任何更改。Erlang,覆蓋環境

+0

難道 「不想做任何更改」 自動排除使用 'set_env/3'? – Alexander

+0

我認爲'set_env/3'是合適的,但我正在尋找不要在我的應用程序中保留任何這樣的邏輯的方法。想想,使用一些特定的應用程序是合適的,它將在其他應用程序之前加載,並設置任何其他應用程序。 –

+0

'應用程序:get_env/1,2,3'很容易成爲高度併發場景中的瓶頸,所以最好只在gen_server初始階段執行此操作,並將配置置於狀態。這就是爲什麼如果你將在應用程序啓動後設置env,你必須編寫自定義邏輯來處理配置更新。 – danechkin

回答

3

如果您想徹底避免應用程序代碼的更改,最好的方法是使用外部配置文件並從中央服務器複製到每個「本地」服務器。如果您在sys.config中的應用程序列表末尾指定了一個文件路徑(假設您使用的是發行版),則BEAM VM也會將該文件作爲附加配置加載。

使用此功能,您可以在/etc/my_service/extended.config等位置創建一個文件,並使用某個服務或其他服務自動更新文件。木偶是一個可以爲你做這個部分的工具的例子;看起來像Hiera(我不熟悉)將是另一個。

爲了清楚起見,使用這種方法,您sys.config文件應該是這樣:

[ 
    {my_app1, [ 
      {my_param1, 1}, 
      {my_param2, "string"} 
     ]}, 
    {my_app2, [ 
      ... 
     ]}, 
    "/etc/my_service/extended.config" 
]. 

但是,那樣的做法有一定的侷限性顯著,即在該配置文件只裝載一次,如果您想在服務運行時更改BEAM VM,則必須重新啓動BEAM VM。如果你正在生成一個Erlang版本(因此sys.config),它也會工作得最好。

如果你不使用一個Erlang釋放,沒有sys.config文件,你還可以指定使用-config命令行參數的配置文件,erl

最好的方法,國際海事組織,將要求您對應用程序進行一些小修改。我建議將參數存儲在分佈式mnesia表(或任何其他數據庫,實際上,只要您可以輕鬆查詢它)。隨後,將您的application:get_env/2,3呼叫替換爲您定義的函數的調用,該函數會檢查您正在存儲設置的數據庫,然後返回application:get_env/2,3

例如:

-record(setting, {key, value}). 
get_setting(App, Key) -> 
    get_setting(App, Key, undefined). 

get_setting(App, Key, Default) -> 
    case mnesia:dirty_read(settings, {App, Key}) of 
     [] -> 
      application:get_env(App, Key, Default); 
     [_ = #setting{value = Value}] -> 
      Value 
    end. 
+0

是的,感謝這樣詳細的答案,我認爲最適合我的是從hiera生成配置文件,並在BEAM啓動之前將此配置複製到每個本地服務器。 –