查看源代码 内核应用
描述
内核应用程序拥有运行 Erlang 运行时系统所需的所有代码:文件服务器、代码服务器等等。
内核应用程序是第一个启动的应用程序。它是强制性的,因为基于 Erlang/OTP 的最小系统由 Kernel 和 STDLIB 组成。 Kernel 包含以下功能区域
- 应用程序的启动、停止、监督、配置和分布
- 代码加载
- 日志记录
- 全局命名服务
- Erlang/OTP 的监督
- 与套接字的通信
- 操作系统接口
日志处理器
内核应用程序中定义了两个标准日志处理器。 这些在 内核用户指南 以及 logger_std_h
和 logger_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
- 用户定义的信号 1sigusr2
- 用户定义的信号 2sigchld
- 子进程停止或终止sigstop
- 停止进程sigtstp
- 在终端键入的停止
在 os:set_signal/2
中描述了设置操作系统信号。
配置
为 Kernel 应用程序定义了以下配置参数。 有关配置参数的更多信息,请参阅文件 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
指定。在 Kernel 用户指南的 日志记录 部分中描述了
logger
参数。logger_level = Level
- 指定 Logger 的主要日志级别。具有相同或更严重级别 的日志事件将通过主要日志级别检查。有关 Logger 和日志级别的更多信息,请参阅 Kernel 用户指南中的 日志记录 部分。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
- 指定 Logger 是否与 Erlang/OTP 21.0 之前的版本的 SASL 错误日志记录功能向后兼容。如果此参数设置为
true
,则默认的 Logger 处理程序不会记录任何进度、崩溃或监督报告。 如果随后启动了 SASL 应用程序,它会添加一个名为sasl
的 Logger 处理程序,该处理程序会根据 SASL 配置参数sasl_error_logger
和sasl_errlog_type
的值记录这些事件。有关 SASL 配置参数的信息,请参阅 sasl(6) 手册页中的 已弃用的错误日志记录事件处理程序和配置 部分。
有关 SASL 错误日志记录功能以及 Logger 如何与此向后兼容的信息,请参阅 SASL 用户指南中的 SASL 错误日志记录 部分以及 Kernel 用户指南中的 与 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
套接字的默认选项,请参阅inet
。inet_default_listen_options = [{Opt, Val}]
- 指定listen
(和accept
)套接字的默认选项,请参阅inet
。inet_dist_use_interface = ip_address()
- 如果 Erlang 节点的主机有多个网络接口,则此参数指定要侦听的接口。有关ip_address()
的类型定义,请参阅inet
。inet_dist_listen_min = First
inet_dist_listen_max = Last
为分布式 Erlang 节点的侦听器套接字定义First..Last
端口范围。inet_dist_listen_options = Opts
- 定义打开分布式 Erlang 节点的侦听套接字时要使用的额外套接字选项列表。 请参阅gen_tcp:listen/2
。inet_dist_connect_options = Opts
- 定义一个额外的套接字选项列表,用于连接到其他分布式 Erlang 节点。请参阅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
- 为网络定时器进程定义一个额外的 spawn 选项列表。对于与另一个节点的每个连接,都存在一个这样的进程。网络定时器进程负责监督与其关联的连接。这些进程还在建立连接时执行分布握手协议。当存在大量分布连接时,设置垃圾回收选项有助于减少内存使用。默认值为[link, {priority, max}]
,并且这两个选项无法更改。monitor
和{monitor, MonitorOpts}
选项是不允许的,如果存在,将被丢弃。有关有效选项的信息,请参阅erlang:spawn_opt/4
BIF 的文档。如果Opts
列表不是一个正确的列表,或者包含无效的选项,则连接的建立将失败。请注意,只有当使用的分布载体协议按照 ERTS 用户指南 ➜ 如何为 Erlang 分布实现替代载体 ➜ 分布模块 中描述的方式实现,而没有进一步更改时,上述行为才成立。所使用的分布载体协议的实现者可以选择忽略
net_ticker_spawn_options
参数或更改其行为。但是,目前所有随 OTP 提供的分布模块的行为都如上所述。net_tickintensity = NetTickIntensity
- 网络心跳强度 指定在 网络心跳时间 期间,当没有其他数据通过与另一个节点的连接发送时,要发送多少个心跳。这也决定了检查来自另一个节点的数据的频率。网络心跳强度越高,节点检测到无响应节点的时间就越接近所选的网络心跳时间段。网络心跳强度默认为4
。NetTickIntensity
的值应为4..1000
范围内的整数。如果NetTickIntensity
不是整数或小于4
的整数,则会静默使用4
。如果NetTickIntensity
是大于1000
的整数,则会静默使用1000
。注意
请注意,所有通信节点都应使用相同的网络心跳强度以及相同的网络心跳时间。
警告
请注意不要设置过高的网络心跳强度,因为如果设置得太高,您可能会使节点工作量过大。
net_ticktime = NetTickTime
- 指定网络心跳时间,以秒为单位。这是连接的节点可能无响应的最长时间,在此之后,它将被视为已关闭并断开连接。网络心跳时间和 网络心跳强度 共同决定了一个间隔
TickInterval = NetTickTime/NetTickIntensity
。每隔TickInterval
秒,如果在此前TickInterval
秒内没有向每个连接的节点发送任何内容,则会向其发送心跳。心跳是在连接上发送的一个小数据包。如果在此前NetTickIntensity
个TickInterval
秒间隔内没有收到心跳或有效负载数据包,则连接的节点将被视为已关闭。这确保了由于硬件错误等原因而没有响应的节点被视为已关闭。由于仅每
TickInterval
秒检查一次可用性,因此当检测到节点无响应时,节点实际无响应的时间T
可能在MinT
和MaxT
之间变化,其中MinT = NetTickTime - NetTickTime / NetTickIntensity MaxT = NetTickTime + NetTickTime / NetTickIntensity
NetTickTime
默认为60
秒,NetTickIntensity
默认为4
。因此,45 < T < 75
秒。注意
请注意,所有通信节点都必须指定相同的
NetTickTime
和NetTickIntensity
值,因为它决定了发出心跳的频率和预期接收心跳的频率。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
,则启动所有分布服务,例如rpc
、global
和net_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_server
为true
,则可以使用此参数使用从属 IP 地址列表初始化boot_server
SlaveIP = string() | atom | {integer(),integer(),integer(),integer()}
,其中
0 <= integer() <=255
。以原子、字符串和元组形式表示的
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()
- 指定是否将 shell 历史记录在erl
使用之间记录到磁盘 (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)
的形式调用,其中Reason
是application_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
使用。两种规则都可以在列表中混合使用。ObjDirSuffix
和SrcDirSuffix
的解释如下:如果对象所在目录名称的末尾与ObjDirSuffix
匹配,则通过调用filelib:wildcard/1
扩展通过将ObjDirSuffix
替换为SrcDirSuffix
创建的名称,并且在匹配项中找到的第一个常规文件是源文件。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 用法中的 Escripts 和非交互式 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
,以及可能的file
和modes
参数来替换。示例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 的向后兼容性。