檢視原始碼 核心應用程式

描述

核心應用程式包含了執行 Erlang 執行時期系統所需的所有程式碼:檔案伺服器、程式碼伺服器等等。

核心應用程式是第一個啟動的應用程式。它是強制性的,因為基於 Erlang/OTP 的最小系統由核心和 STDLIB 組成。核心包含以下功能領域:

  • 應用程式的啟動、停止、監管、配置和分發
  • 程式碼載入
  • 記錄
  • 全域名稱服務
  • Erlang/OTP 的監管
  • 與 socket 通訊
  • 作業系統介面

記錄器處理程式

核心應用程式中定義了兩個標準的記錄器處理程式。這些在核心使用者指南中、以及在 logger_std_hlogger_disk_log_h 手冊頁面中有所描述。

作業系統訊號事件處理程式

可以使用核心應用程式的事件管理器訂閱非同步作業系統訊號 (請參閱 OTP 設計原則gen_event),並將其註冊為 erl_signal_server。安裝了一個預設的訊號處理程式,可以處理以下訊號:

  • sigusr1 - 預設處理程式將停止 Erlang 並產生一個帶有口號「Received SIGUSR1」的崩潰轉儲。這相當於呼叫 erlang:halt("Received SIGUSR1")

  • sigquit - 預設處理程式將立即停止 Erlang。這相當於呼叫 erlang:halt()

  • sigterm - 預設處理程式將正常終止 Erlang。這相當於呼叫 init:stop()

事件

任何添加到 erl_signal_server 的事件處理程式都必須處理以下事件。

  • sighup - 在控制終端上偵測到掛斷或控制程序終止

  • sigquit - 從鍵盤退出

  • sigabrt - 從中止發出的中止訊號

  • sigalrm - 從警報發出的計時器訊號

  • sigterm - 終止訊號

  • sigusr1 - 使用者定義的訊號 1

  • sigusr2 - 使用者定義的訊號 2

  • sigchld - 子程序已停止或終止

  • sigstop - 停止程序

  • sigtstp - 在終端上輸入的停止

os:set_signal/2 中描述了設定作業系統訊號。

配置

為核心應用程式定義了以下配置參數。有關配置參數的更多資訊,請參閱檔案 app

  • connect_all = true | false - 如果啟用 (true),這也是預設值,global 將主動連線到所有它知道的節點。請注意,您還需要啟用 prevent_overlapping_partitions,以便 global 確保維護完全連線的網路。prevent_overlapping_partitions 還可以防止 global 的名稱註冊和鎖定出現不一致的情況。

    現在已棄用的命令列參數 -connect_all <boolean>connect_all 配置參數具有相同的效果。如果定義了此配置參數,它將覆蓋命令列參數。

  • distributed = [Distrib] - 指定哪些應用程式是分發式的,以及允許它們在哪個節點上執行。在此參數中

    • Distrib = {App,Nodes} | {App,Time,Nodes}

    • App = atom()
    • Time = integer()>0
    • Nodes = [node() | {node(),...,node()}]

    此參數在 application:load/2 中進行了描述。

  • dist_auto_connect = Value - 指定何時自動連線節點。如果未指定此參數,則始終自動連線節點,例如,當要將訊息傳送到該節點時。Value 是以下之一:

    • never - 永遠不會自動建立連線,必須明確連線。請參閱 net_kernel

    • once - 自動建立連線,但每個節點僅建立一次。如果節點關閉,則必須隨後明確連線。請參閱 net_kernel

  • epmd_module = module() - 配置負責與 epmd 通訊的模組。如果未定義此參數,則預設為 erl_epmd

    現在已棄用的命令列參數 -epmd_module <module>epmd_module 配置參數具有相同的效果。如果定義了此配置參數,它將覆蓋命令列參數。

  • erl_epmd_node_listen_port = integer() - 配置 erl_epmd 用於監聽連線並連線到其他節點的埠。如果設定了此旗標,即使 EPMD 不可用,Erlang VM 也將以分散式模式啟動。如果未設定,則會自動選擇一個埠 (相當於埠 0)。有關更多詳細資訊,請參閱 erl_epmd

    現在已棄用的命令列參數 erl_epmd_port <module>erl_epmd_node_listen_port 配置參數具有相同的效果。如果定義了此配置參數,它將覆蓋命令列參數。

  • permissions = [Perm] - 指定應用程式啟動時的預設權限。在此參數中

    • Perm = {ApplName,Bool}
    • ApplName = atom()
    • Bool = boolean()

    application:permit/2 中描述了權限。

  • logger = [Config] - 指定 記錄器 (Logger) 的配置,但主要日誌級別除外,該級別使用 logger_level 指定,以及與 SASL 錯誤記錄的相容性,該相容性使用 logger_sasl_compatible 指定。

    logger參數在核心使用者指南的 記錄章節中進行了描述。

  • logger_level = Level - 指定記錄器的主要日誌級別。具有相同或更嚴重級別的日誌事件將通過主要日誌級別檢查。有關記錄器和日誌級別的更多資訊,請參閱核心使用者指南中的 記錄章節。

    Level = emergency | alert | critical | error | warning | notice | info | debug | all | none

    若要在執行時期變更主要日誌級別,請使用 logger:set_primary_config(level, Level)

    預設為 notice

  • logger_metadata = Metadata - 指定日誌事件的主要中繼資料。

    Metadata = map()

    預設為 #{}

  • logger_sasl_compatible = true | false - 指定記錄器的行為是否與 Erlang/OTP 21.0 之前的版本中的 SASL 錯誤記錄功能向後相容。

    如果此參數設定為 true,則預設記錄器處理程式不會記錄任何進度、崩潰或監管程式報告。如果然後啟動 SASL 應用程式,它將新增一個名為 sasl 的記錄器處理程式,該處理程式會根據 SASL 配置參數 sasl_error_loggersasl_errlog_type 的值記錄這些事件。

    有關 SASL 配置參數的資訊,請參閱 sasl(6) 手冊頁面中的 已棄用的錯誤記錄器事件處理程式和配置 章節。

    有關 SASL 錯誤記錄功能以及記錄器如何與其向後相容的資訊,請參閱 SASL 使用者指南中的 SASL 錯誤記錄 章節,以及核心使用者指南中的 與 error_logger 向後相容性 章節。

    預設為 false

    注意

    如果此參數設定為 true,且 sasl_errlog_type 指出應記錄進度報告,且設定的主要日誌級別為 notice 或更嚴重時,SASL 會自動將主要日誌級別設定為 info。也就是說,此設定可能會覆寫核心配置參數 logger_level 的值。這是為了讓日誌級別為 info 的進度報告可以轉發給處理常式。

  • global_groups = [GroupTuple] - 定義全域群組,請參閱 global_group。在此參數中

    • GroupTuple = {GroupName, [Node]} | {GroupName, PublishType, [Node]}

    • GroupName = atom()
    • PublishType = normal | hidden

    • Node = node()
  • inet_default_connect_options = [{Opt, Val}] - 指定 connect sockets 的預設選項,請參閱 inet

  • inet_default_listen_options = [{Opt, Val}] - 指定 listen(和 accept)sockets 的預設選項,請參閱 inet

  • inet_dist_use_interface = ip_address() - 如果 Erlang 節點的主機有多個網路介面,此參數指定要監聽哪個介面。關於 ip_address() 的型別定義,請參閱 inet

  • inet_dist_listen_min = First
    inet_dist_listen_max = Last

    定義分散式 Erlang 節點的監聽器 socket 的 First..Last 連接埠範圍。

  • inet_dist_listen_options = Opts - 定義在開啟分散式 Erlang 節點的監聽 socket 時要使用的一組額外 socket 選項。請參閱 gen_tcp:listen/2

  • inet_dist_connect_options = Opts - 定義在連線到其他分散式 Erlang 節點時要使用的一組額外 socket 選項。請參閱 gen_tcp:connect/4

  • inet_parse_error_log = silent - 如果設定,當在各種 Inet 設定檔中發現並略過錯誤的行時,不會發出任何日誌事件。

  • inetrc = Filename - Inet 使用者設定檔的名稱(字串)。詳細資訊請參閱 ERTS 使用者指南中的 Inet Configuration 章節。

  • net_setuptime = SetupTime - SetupTime 必須為正整數或浮點數,且會被解釋為在連線到另一個 Erlang 節點的連線設定期間,每個網路操作允許的最大時間。最大允許值為 120。如果指定的值較高,則會使用 120。如果未指定變數,或值不正確(例如,不是數字),則預設為 7 秒。

    請注意,此值不會限制總連線設定時間,而是限制連線設定和握手期間的每個個別網路操作。

  • net_ticker_spawn_options = Opts - 定義 net ticker 程序的額外產生選項列表。每個與另一個節點的連線都有一個這樣的程序。net ticker 程序負責監管與其相關聯的連線。這些程序也會在設定連線時執行分散式握手協定。當有大量分散式連線時,設定垃圾收集選項有助於減少記憶體使用量。預設值為 [link, {priority, max}],這兩個選項無法變更。monitor{monitor, MonitorOpts} 選項不允許,如果存在則會被捨棄。關於有效選項的資訊,請參閱 erlang:spawn_opt/4 BIF 的文件。如果 Opts 列表不是正確的列表,或包含無效選項,則連線設定將會失敗。

    請注意,只有在使用的分散式載體協定實作方式如 ERTS 使用者指南 ➜ 如何為 Erlang 分散式實作替代載體 ➜ 分散式模組 中所述,且未做進一步變更時,上述行為才成立。所使用的分散式載體協定的實作者可能已選擇忽略 net_ticker_spawn_options 參數或變更其行為。目前,所有隨 OTP 提供的分散式模組都會如上所述運作。

  • net_tickintensity = NetTickIntensity - *網路心跳強度*指定在 網路心跳時間期間,當沒有其他資料透過連線傳送到另一個節點時,要傳送多少個心跳。這也決定了檢查來自另一個節點的資料的頻率。網路心跳強度越高,節點偵測到無回應節點的時間就越接近選擇的網路心跳時間週期。網路心跳強度預設為 4NetTickIntensity 的值應為 4..1000 範圍內的整數。如果 NetTickIntensity 不是整數或小於 4 的整數,則會無聲無息地使用 4。如果 NetTickIntensity 是大於 1000 的整數,則會無聲無息地使用 1000

    注意

    請注意,所有通訊節點都應使用相同的*網路心跳強度*以及相同的*網路心跳時間*。

    警告

    請小心不要設定過高的網路心跳強度,因為如果設定過高,您可能會使節點的工作量過載。

  • net_ticktime = NetTickTime - 指定以秒為單位的*網路心跳時間*。這是連線節點可能無回應的大概時間,直到被認為已關閉並因此斷線。

    網路心跳時間與 網路心跳強度 一起決定一個間隔 TickInterval = NetTickTime/NetTickIntensity。每隔 TickInterval 秒,如果最後的 TickInterval 秒內沒有傳送任何內容,則會對每個連線節點進行心跳。心跳是在連線上傳送的小封包。如果最後 NetTickIntensityTickInterval 秒的間隔內未收到任何心跳或承載封包,則會認為連線的節點已關閉。這可確保因硬體錯誤等原因而無回應的節點被視為已關閉。

    由於可用性僅每 TickInterval 秒檢查一次,因此當偵測到時,節點無回應的實際時間 T 可能在 MinTMaxT 之間變化,其中

    MinT = NetTickTime - NetTickTime / NetTickIntensity
    MaxT = NetTickTime + NetTickTime / NetTickIntensity

    NetTickTime 預設為 60 秒,而 NetTickIntensity 預設為 4。因此,45 < T < 75 秒。

    注意

    請注意,*所有*通訊節點都應指定*相同*的 NetTickTimeNetTickIntensity 值,因為它決定了傳出心跳的頻率和預期傳入心跳的頻率。

    NetTickTime 需要是 NetTickIntensity 的倍數。如果設定的值不是,則 NetTickTime 會在內部四捨五入到最接近的毫秒。net_kernel:get_net_ticktime() 將會回報截斷為最接近秒的網路心跳時間。

    通常,終止的節點會立即被傳輸協定(如 TCP/IP)偵測到。

  • prevent_overlapping_partitions = true | false - 如果啟用 (true),當節點之間的連線遺失時,global 會主動防止形成重疊分割區。此修正預設為啟用。如果您打算停用此修正,請務必閱讀 global 文件中關於此修正的更多重要資訊。

  • shutdown_timeout = integer() | infinity - 指定在節點關機期間,application_controller 等待應用程式終止的時間。如果計時器過期,application_controller 會強行終止掛起應用程式的 application_master。如果未定義此參數,則預設為 infinity

  • sync_nodes_mandatory = [NodeName] - 指定哪些其他節點*必須*處於活動狀態,此節點才能正確啟動。如果清單中的某些節點未在指定時間內啟動,則此節點也不會啟動。如果未定義此參數,則預設為 []

  • sync_nodes_optional = [NodeName] - 指定哪些其他節點*可以*處於活動狀態,此節點才能正確啟動。如果此清單中的某些節點未在指定時間內啟動,則此節點仍會啟動。如果未定義此參數,則預設為空列表。

  • sync_nodes_timeout = integer() | infinity - 指定此節點等待必要和可選節點啟動的時間(以毫秒為單位)。如果未定義此參數,則不會執行節點同步處理。此選項可確保 global 同步。

  • start_distribution = true | false - 如果參數為 true,則啟動所有分散式服務,例如 rpcglobalnet_kernel。對於想要停用所有分散式功能的系統,此參數應設定為 false

    預設值為 true

  • start_dist_ac = true | false - 如果參數為 true,則啟動 dist_ac 伺服器。對於使用分散式應用程式的系統,此參數應設定為 true

    預設值為 false。如果未定義此參數,則在設定參數 distributed 時會啟動伺服器。

  • start_boot_server = true | false - 如果參數為 true,則啟動 boot_server(請參閱 erl_boot_server)。在嵌入式系統中使用此服務時,應將此參數設定為 true

    預設為 false

  • boot_server_slaves = [SlaveIP] - 如果組態參數 start_boot_servertrue,則可以使用此參數初始化 boot_server,並提供從屬 IP 位址清單。

    SlaveIP = string() | atom | {integer(),integer(),integer(),integer()},

    其中 0 <= integer() <=255

    以 atom、字串和元組形式表示的 SlaveIP 範例

    '150.236.16.70', "150,236,16,70", {150,236,16,70}.

    預設值為 []

  • start_disk_log = true | false - 如果參數為 true,則啟動 disk_log_server(請參閱 disk_log)。在嵌入式系統中使用此服務時,應將此參數設定為 true

    預設為 false

  • start_pg = true | false - 如果參數為 true,則啟動預設的 pg 範圍伺服器(請參閱 pg)。在嵌入式系統中使用此服務時,應將此參數設定為 true

    預設為 false

  • start_timer = true | false - 如果參數為 true,則啟動 timer_server(請參閱 timer)。在嵌入式系統中使用此服務時,應將此參數設定為 true

    預設為 false

  • shell_history = enabled | disabled | module() - 指定是否應在 erl 的使用之間將 shell 歷史記錄記錄到磁碟 (enabled) 、完全不記錄 (disabled) 或使用使用者指定的模組來記錄 shell 歷史記錄。此模組應匯出 load() -> [string()],返回在 shell 啟動時要載入的字串清單,以及 add(iodata()) -> ok.,每次在 shell 中輸入新行時都會呼叫。預設情況下,記錄功能已停用。

  • shell_history_drop = [string()] - 不應保留的特定記錄行。例如,["q().", "init:stop()."] 將允許忽略關閉節點的命令。預設值為 []

  • shell_history_file_bytes = integer() - shell 應記住多少位元組。預設情況下,該值設定為 512kb,最小值為 50kb。

  • shell_history_path = string() - 指定 shell 歷史記錄檔案的儲存位置。預設值為使用者快取目錄,由 filename:basedir(user_cache, "erlang-history") 返回。

  • shutdown_func = {Mod :: atom(), Func :: atom()} - 設定 application_controller 在開始終止時呼叫的函式。該函式以 Mod:Func(Reason) 的形式呼叫,其中 Reasonapplication_controller 的終止原因,並且它必須盡快返回,以便 application_controller 正確終止。

  • source_search_rules = [DirRule] | [SuffixRule]

    其中

    • DirRule = {ObjDirSuffix,SrcDirSuffix}
    • SuffixRule = {ObjSuffix,SrcSuffix,[DirRule]}
    • ObjDirSuffix = string()
    • SrcDirSuffix = string()
    • ObjSuffix = string()
    • SrcSuffix = string()

    指定 filelib:find_file/2 filelib:find_source/2 使用的規則清單。如果將其設定為空清單以外的其他值,則會取代預設規則。規則可以是簡單的目錄尾碼對,例如 {"ebin", "src"}filelib:find_file/2 使用這些規則,或者根據檔案名稱副檔名指定單獨目錄尾碼規則的三元組,例如 [{".beam", ".erl", [{"ebin", "src"}]}filelib:find_source/2 使用這些規則。這兩種規則可以混合在清單中。

    ObjDirSuffixSrcDirSuffix 的解釋如下:如果物件所在目錄名稱的結尾與 ObjDirSuffix 相符,則透過將 ObjDirSuffix 替換為 SrcDirSuffix 而建立的名稱會透過呼叫 filelib:wildcard/1 來展開,並且在比對中找到的第一個常規檔案是原始檔。

  • standard_io_encoding = Encoding - 設定透過 standard_io 傳送或接收的位元組應解譯為 unicode 還是 latin1。預設情況下,如果主機支援,則輸入和輸出會解譯為 Unicode。使用此旗標,您可以在啟動時設定編碼。

    這與 io:setopts(standard_io, {encoding, Encoding}) 的運作方式類似,但會在讀取 standard_io 上的任何位元組之前套用。

    Encoding 是下列其中一個

    • unicode - 設定 standard_io 以使用 unicode 模式。

    • latin1 - 設定 standard_io 以使用 latin1 模式。

    • _ - 除 unicode 或 latin1 以外的任何內容都將被忽略,並且系統將自行設定編碼,通常在現代系統上為 unicode。

    如需更多詳細資訊,請參閱 Erlang 中 Unicode 使用的 Escript 和非互動式 I/O

  • os_cmd_shell = string() - 指定透過 os:cmd/2 呼叫系統命令時要使用的 shell。預設情況下,shell 會自動偵測。

已棄用的組態參數

在 Erlang/OTP 21.0 中,新增了用於記錄的新 API。舊的 error_logger 事件管理員以及在此管理員上執行的事件處理程式仍然有效,但預設情況下不再使用它們。

仍然可以設定下列應用程式組態參數,但僅當未設定 Logger 的對應組態參數時才會使用它們。

  • error_logger - 透過設定預設 logger_std_h 處理程式的 type 以及可能的 filemodes 參數來取代。範例

    erl -kernel logger '[{handler,default,logger_std_h,#{config=>#{file=>"/tmp/erlang.log"}}}]'
  • error_logger_format_depth - 透過設定預設處理程式格式器的 depth 參數來取代。範例

    erl -kernel logger '[{handler,default,logger_std_h,#{formatter=>{logger_formatter,#{legacy_header=>true,template=>[{logger_formatter,header},"\n",msg,"\n"],depth=>10}}}]'

如需更多資訊,請參閱 與 error_logger 的回溯相容性