ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Erlang/OTP Kernel 应用权威指南:核心服务、OS 信号处理与全部配置参数详解

Erlang/OTP Kernel 应用权威指南:核心服务、OS 信号处理与全部配置参数详解 编程语言语言运行时标准库编译器并发编程【免费下载链接】otpErlang/OTP项目地址https://gitcode.com/gh_mirrors/ot/otp点击查看免费下载Kernel 是 Erlang/OTP 运行时系统的心脏它承载了启动/停止/监督应用、代码加载、日志、全局名称服务、Socket 通信与操作系统接口等全部基础能力是系统中第一个被启动且强制必需的应用。本文以 lib/kernel/doc/kernel_app.md 为骨架结合lib/kernel/src/下的真实实现源码系统讲解 Kernel 的功能域、erl_signal_server信号事件机制并逐一剖析从connect_all到os_cmd_shell的全部配置参数及其默认值、取值约束与底层影响读完即可独立完成 Kernel 的配置调优与故障排查。Kernel 应用概述第一个启动、强制必需的基础设施根据 Kernel 应用文档Kernel application 包含了运行 Erlang 运行时系统所需的全部代码文件服务器file server、代码服务器code server等。它有两个关键属性第一个启动的应用整个系统的启动顺序中 Kernel 最先运行强制必需基于 Erlang/OTP 的最小系统由Kernel STDLIB两个应用组成缺一不可。Kernel 覆盖以下功能领域应用的启动、停止、监督、配置与分发distribution代码加载code loading日志logging全局名称服务global name serviceErlang/OTP 的监督supervision与 Socket 的通信操作系统接口从源码可以印证这些职责的落点。kernel.app.src 中{applications, []}表明 Kernel 不依赖任何其他 OTP 应用其{mod, {kernel, []}}指定了应用回调模块即 kernel.erl 中的start/2start(_, []) - %% Setup the logger and configure the kernel logger environment ok logger:internal_init_logger(), ok os:internal_init_cmd_shell(), case supervisor:start_link({local, kernel_sup}, kernel, []) of {ok, Pid} - ok erl_signal_handler:start(), ok logger:add_handlers(kernel), {ok, Pid, []}; Error - Error end.启动时依次完成 Logger 内部初始化、os:internal_init_cmd_shell/0、启动kernel_sup监督树、注册 OS 信号处理器erl_signal_handler:start/0并加载 Kernel 的日志处理器。kernel.erl 中注释的进程结构图显示kernel_sup采用one_for_all策略intensity 0, period 1即任意子进程崩溃都会终止整个节点其下挂载了code_server代码服务、file_server文件服务、erl_dist分布式、safe_sup等子系统以及disk_log、pg、logger、user等服务。这意味着 Kernel 层任何核心组件失效都会导致节点整体退出——这是它作为运行时基础设施的必然设计。Logger HandlersKernel 提供的两个标准日志处理器Kernel 应用预定义了两个标准 Logger 处理器handler详见 Kernel Users Guide 的 Logging 章节logger_std_h默认处理器负责将日志输出到标准输出standard_io或文件也是 OTP 默认使用的 handlerlogger_disk_log_h基于disk_log的处理器将日志写入 disk_log 文件支持按大小/时间进行日志轮转。logger_std_h的源码位于 logger_std_h.erllogger_disk_log_h位于 logger_disk_log_h.erl。两个 handler 均依赖logger_h_commonlogger_h_common.erl提供文件处理、缓冲与配置校验等公共逻辑。在 kernel.erl 的start/2中logger:add_handlers(kernel)负责按 Kernel 配置实例化这些标准处理器。Logger 的完整配置机制primary log level、handler 配置、过滤器、格式化器等在kernel_app.md的配置参数部分展开见下文。OS Signal Event Handler订阅与处理异步操作系统信号Kernel 应用通过其事件管理器event manager参见 OTP Design Principles 中的gen_event行为提供异步 OS 信号的订阅能力该事件管理器注册名为erl_signal_server。任何进程都可以向其添加事件处理器event handler来订阅特定信号。默认信号处理器Kernel 安装了一个默认信号处理器处理以下三个信号信号默认行为等价调用sigusr1停止 Erlang 并生成 slogan 为Received SIGUSR1的 crashdumperlang:halt(Received SIGUSR1)sigquit立即停止 Erlangerlang:halt()sigterm正常终止 Erlanginit:stop()上述行为在源码 erl_signal_handler.erl 中一目了然handle_event(sigusr1, S) - erlang:halt(Received SIGUSR1), {ok, S}; handle_event(sigquit, S) - erlang:halt(), {ok, S}; handle_event(sigterm, S) - error_logger:info_msg(SIGTERM received - shutting down~n), ok init:stop(), {ok, S};可见sigterm如kill默认信号或容器编排发送的终止信号会触发优雅关闭init:stop/0按顺序停止所有应用而sigusr1用于主动抓取 crashdump 诊断现场sigquit则是立即强制退出。事件列表handler 必须处理的事件任何添加到erl_signal_server的事件处理器都必须处理以下事件事件含义sighup在控制终端上检测到挂断或控制进程死亡sigquit键盘发起的 Quitsigabrtabort 产生的中止信号sigalrmalarm 产生的定时器信号sigterm终止信号sigusr1用户自定义信号 1sigusr2用户自定义信号 2sigchld子进程停止或终止sigstop停止进程sigtstp终端输入 Stopsigcont停止后继续sigwinch窗口大小变化siginfo键盘发起的状态请求。注意多个操作系统尤其是 Linux不支持该信号此时调用os:set_signal/2会抛出badarg异常信号如何被设置启用/禁用、忽略等由os:set_signal/2描述实现见 os.erl。Kernel 配置参数全景解析Kernel 的全部配置参数通过应用配置机制设置application:set_env(kernel, Key, Value)、erl -kernel Key Value、sys.config中的{kernel, [...]}等。下方按功能域分组逐一说明同时给出默认值与取值约束。默认值可从 kernel.app.src 的{env, [...]}与源码实现交叉验证。分布式与全局名称服务connect_all true | false默认true。启用后m:global会主动连接所有对它可见的节点。文档建议同时启用prevent_overlapping_partitions以保证global维护一个完全连通的网络并避免其在名称注册与锁服务上出现不一致。已废弃的命令行参数-connect_all boolean见 erl_cmd.md效果相同但配置参数定义后优先于命令行参数。实现上 global.erl 通过application:get_env(kernel, connect_all)读取并允许init:get_argument(connect_all)兜底。distributed [Distrib]指定哪些应用是分布式的、以及允许在哪些节点上执行。其中Distrib {App,Nodes} | {App,Time,Nodes}App atom()Time integer()0Nodes [node() | {node(),...,node()}]详细语义由application:load/2描述。dist_auto_connect Value指定节点何时被自动连接。若未指定节点总是被自动连接例如要向某节点发消息时。Value取值never连接永不自动建立必须显式连接见m:net_kernelonce连接自动建立但每个节点仅一次节点下线后须显式重新连接。epmd_module module()配置负责与 epmd 通信的模块。未定义时默认为erl_epmd实现见 erl_epmd.erl。已废弃命令行参数-epmd_module module效果相同配置参数优先。erl_epmd_node_listen_port integer()配置m:erl_epmd用于监听连接并向其他节点发起连接的端口。设置后即使 EPMD 不可用Erlang VM 也能以分布式模式启动未设置时端口自动选择等价于端口0。已废弃命令行参数erl_epmd_port module效果相同配置参数优先。permissions [Perm]指定应用启动时的默认权限Perm {ApplName,Bool}其中ApplName atom()Bool boolean()。权限机制见application:permit/2。global_groups [GroupTuple]定义全局组见m:global_groupGroupTuple {GroupName, [Node]} | {GroupName, PublishType, [Node]}GroupName atom()PublishType normal | hiddenNode node()prevent_overlapping_partitions true | false默认true。启用后global会在节点间连接丢失时主动防止形成重叠分区overlapping partitions。该修复默认开启如需关闭务必先阅读m:global中关于此修复的重要说明。从 kernel.app.src 可见其默认值确为true且 global.erl 在启动时同步读取connect_all与prevent_overlapping_partitions两个参数。start_distribution true | false默认true。为true时启动所有分布式服务如rpc、global、net_kernel需要完全禁用分布式功能的系统应设为false。start_dist_ac true | false默认false。为true时启动dist_ac服务器分布式应用场景。若该参数未定义则当distributed参数被设置时启动该服务器。sync_nodes_mandatory [NodeName]指定本节点正常启动所必须存活的节点列表。若列表内某节点未在指定时间内启动本节点也不会启动。默认[]。sync_nodes_optional [NodeName]指定本节点正常启动时可以存活的节点列表即使这些节点未在指定时间内启动本节点照常启动。默认空列表。sync_nodes_timeout integer() | infinity指定等待 mandatory 与 optional 节点启动的时间毫秒。未定义时不进行任何节点同步。该选项确保global得到同步。网络连接与节点存活检测inet_default_connect_options [{Opt, Val}]指定connect套接字的默认选项见m:inet。inet_default_listen_options [{Opt, Val}]指定listen及accept套接字的默认选项见m:inet。inet_dist_use_interface ip_address()当主机拥有多个网络接口时指定分布式节点监听哪个接口ip_address()类型定义见m:inet。inet_dist_listen_min First、inet_dist_listen_max Last定义分布式 Erlang 节点监听套接字的端口范围First..Last。这是穿透防火墙/安全组场景最常用的参数。inet_dist_listen_options Opts定义打开分布式节点监听套接字时附加的套接字选项列表见gen_tcp:listen/2。inet_dist_connect_options Opts定义连接其他分布式节点时附加的套接字选项列表见gen_tcp:connect/4。inet_parse_error_log silent设置后当各类 Inet 配置文件出现错误行并被跳过时不再产生任何日志事件。inetrc Filename指定 Inet 用户配置文件的名称字符串详见 ERTS Users Guide 的 Inet Configuration。net_setuptime SetupTimeSetupTime必须为正整数或浮点数表示连接建立过程中每个单独网络操作的最大允许时间。最大允许值120超出则按120处理默认7秒未指定或值非法时。注意该值并不限制总的连接建立时间而是限制建立与握手过程中的单次网络操作耗时。log_missed_net_ticks true | false默认false。控制是否对分布式连接上每次错过的 sub-tick 记录警告。当一个连接在一个 tick 间隔内未收到对方任何数据即视为错过一次 sub-tick此后每个错过的 sub-tick 都会发出警告直到节点在连续错过net_tickintensity次 sub-tick 后被判定下线——届时无论本参数如何都会记录最终的超时警告。net_ticker_spawn_options Opts定义 net ticker 进程的额外 spawn 选项。每个到其他节点的连接对应一个 net ticker 进程负责监督连接并执行分布式握手协议。默认[link, {priority, max}]这两项不可修改monitor与{monitor, MonitorOpts}不允许出现若存在会被丢弃。当分布式连接数量巨大时可配置垃圾回收相关选项以降低内存占用有效选项见erlang:spawn_opt/4BIF 文档。若Opts不是合法列表或含非法选项连接建立将失败。需要说明的是上述行为仅在所使用的分布式载体协议按 ERTS Users Guide 中 Alternative Carrier 的 Distribution Module 规范 实现且未做改动时成立载体协议实现者可以选择忽略或改变该参数行为。目前 OTP 自带的所有 distribution 模块均按上述行为工作。net_tickintensity NetTickIntensityNet tick intensity 表示在一个 net tick time 周期内当连接上没有其他数据发送时发送多少个 tick同时决定以多高的频率检查来自对方节点的数据。强度越高节点越接近所选的 net tick time 周期就能发现无响应节点。默认4合法范围为整数4..1000非整数或小于4时静默使用4大于1000时静默使用1000。注意所有相互通信的节点必须使用相同的 net tick intensity 与 net tick time。警告不要设置过高的 net tick intensity以免节点被 tick 工作淹没。net_ticktime NetTickTime指定 net tick time秒即一个已连接节点可保持无响应、直至被判定下线并断开的大致时间。net tick time 与 net tick intensity 共同决定间隔TickInterval NetTickTime/NetTickIntensity每TickInterval秒若最后一个TickInterval内未向某连接发送任何数据则向其发送一个 tick连接上的小数据包若在最近NetTickIntensity个TickInterval间隔内既未收到 tick 也未收到 payload 数据包则该节点被判定为下线。由于可用性每TickInterval秒才检查一次实际检测到节点无响应的时间T会在以下区间浮动MinT NetTickTime - NetTickTime / NetTickIntensity MaxT NetTickTime NetTickTime / NetTickIntensity默认NetTickTime 60秒、NetTickIntensity 4因此实际检测时间约为45 T 75秒。其他约束与事实所有通信节点必须配置相同的NetTickTime与NetTickIntensity因为它们同时决定发送 tick 的频率与期望接收 tick 的频率NetTickTime必须是NetTickIntensity的倍数若不是NetTickTime会在内部向上取整到最近的毫秒。net_kernel:get_net_ticktime()仍按截断到秒的值上报通常情况下终止节点会被传输协议如 TCP/IP立即检测到。源码佐证见 net_kernel.erl 的make_init_opts/1从Opts或application:get_env(kernel, net_ticktime | net_tickintensity)读取net_ticktime兜底60000毫秒、net_tickintensity兜底4并执行向上取整为 intensity 倍数与合法性钳制init/1中TickInterval NetTicktime div NetTickIntensity后spawn_link(net_kernel, ticker, ...)启动 ticker 进程。运行时可通过net_kernel:set_net_ticktime/1,2与get_net_ticktime/0动态调整与查询。日志Loggerlogger [Config]指定 Logger 的配置primary log level 与 SASL 兼容性除外二者分别由logger_level与logger_sasl_compatible指定。完整说明见 Kernel Users Guide 的 Logging 章节。logger_level Level指定 Logger 的 primary log level等于或更严重级别的日志事件才能通过检查。Level emergency | alert | critical | error | warning | notice | info | debug | all | none。默认notice见 kernel.app.src 中{logger_level, notice}。运行时可调用logger:set_primary_config(level, Level)修改logger:set_primary_config/2。logger_metadata Metadata指定日志事件的 primary metadataMetadata map()默认#{}。logger_sasl_compatible true | false指定 Logger 是否与 Erlang/OTP 21.0 之前版本的 SASL 错误日志功能向后兼容。默认false。设为true时默认 Logger handler 不记录 progress、crash、supervisor 报告随后启动 SASL 应用时SASL 会添加名为sasl的 Logger handler按 SASL 配置参数sasl_error_logger与sasl_errlog_type记录这些事件见 sasl_app.md 相关章节。注意若本参数为true、sasl_errlog_type指示记录 progress 报告、且配置的 primary log level 为notice或更严重级别则 SASL 会自动将 primary log level 提升为info——这可能覆盖Kernel 配置参数logger_level的值以便让级别为info的 progress 报告能够转发给各 handler。os_cmd_shell string()指定通过os:cmd/2调用系统命令时使用的 shell。默认自动探测。对应实现为 os.erl 中的os:internal_init_cmd_shell/0且 kernel.erl 的config_change/3会在配置变化时重新初始化。Shell 与标准 I/Oshell_docs_ansi boolean()指定 shell 中渲染的文档是否使用 ANSI 转义码。另见t:shell_docs:config/0。注意 kernel.app.src 中的默认值是auto。shell_history enabled | disabled | module()指定 shell 历史记录策略enabled在erl两次使用之间将历史记录写入磁盘disabled完全不记录默认module()使用用户指定模块记录历史该模块须导出load() - [string()]shell 启动时加载的字符串列表与add(iodata()) - ok.每输入新行时调用。shell_history_drop [string()]指定不应持久化的历史行例如[q()., init:stop().]可忽略关闭节点的命令。默认[]kernel.app.src 中确为{shell_history_drop, []}。shell_history_file_bytes integer()shell 最多记忆的字节数。默认 512KB最小 50KB。shell_history_path string()shell 历史文件的存放位置。默认使用filename:basedir(user_cache, erlang-history)返回的用户缓存目录。standard_io_encoding Encoding设置 standard_io 收发字节按 unicode 还是 latin1 解释。默认在主机支持时按 Unicode 解释通过本参数可在启动时配置编码。效果类似io:setopts(standard_io, {encoding, Encoding})但会在任何字节被读取之前应用。Encoding取值unicode使用 unicode 模式latin1使用 latin1 模式_其他任何值都会被忽略由系统自行配置现代系统上通常是 unicode。详见 Escripts and non-interactive I/O in Unicode Usage in Erlang。文件与源码查找source_search_rules [DirRule] | [SuffixRule]指定供filelib:find_file/2与filelib:find_source/2使用的规则列表。规则类型DirRule {ObjDirSuffix,SrcDirSuffix}目录后缀对如{ebin, src}供filelib:find_file/2使用SuffixRule {ObjSuffix,SrcSuffix,[DirRule]}按文件扩展名区分的目录后缀规则三元组例如[{.beam, .erl, [{ebin, src}]}]供filelib:find_source/2使用。两种规则可混合。解释方式若对象所在目录名的结尾匹配ObjDirSuffix则将ObjDirSuffix替换为SrcDirSuffix得到的新名字通过filelib:wildcard/1展开首个匹配到的常规文件即为源文件。设置为非空列表时替换默认规则。启动、关闭与监督shutdown_timeout integer() | infinity指定节点关闭时application_controller等待应用终止的时间。计时器超时后application_controller会暴力杀死挂起应用的application_master。未定义时默认infinity。shutdown_func {Mod :: atom(), Func :: atom()}设置application_controller开始终止时调用的函数。以Mod:Func(Reason)调用Reason为application_controller的终止原因该函数必须尽快返回否则application_controller无法正常终止。start_boot_server true | false默认false。为true时启动boot_server见m:erl_boot_server嵌入式系统使用该服务时应设为true。boot_server_slaves [SlaveIP]当start_boot_server为true时可用其初始化boot_server的从属 IP 地址列表。SlaveIP string() | atom | {integer(),integer(),integer(),integer()}其中0 integer() 255。示例原子形式150.236.16.70、字符串形式150,236,16,70、元组形式{150,236,16,70}。默认[]。start_disk_log true | false默认false。为true时启动disk_log_server见m:disk_log嵌入式系统使用该服务时应设为true。start_pg true | false默认false。为true时启动默认的pgscope 服务器见m:pg使用该服务的嵌入式系统应设为true。start_timer true | false默认false。为true时启动timer_server见m:timer使用该服务的嵌入式系统应设为true。已废弃的配置参数error_logger 兼容层Erlang/OTP 21.0 引入了新的日志 API。旧的error_logger事件管理器及其上的事件处理器仍然可用但默认不再使用。以下两个 Kernel 配置参数仍可设置但仅当对应的 Logger 配置参数未设置时才生效error_logger已被默认logger_std_hhandler 的type以及可选的file、modes参数取代。示例将日志写入/tmp/erlang.logerl -kernel logger [{handler,default,logger_std_h,#{config#{file/tmp/erlang.log}}}]error_logger_format_depth已被默认 handler 格式化器的depth参数取代。示例限制输出深度为 10 并保留 legacy headererl -kernel logger [{handler,default,logger_std_h,#{formatter{logger_formatter,#{legacy_headertrue,template[{logger_formatter,header},\n,msg,\n],depth10}}}]更多信息参见 Backwards compatibility with error_logger。配置实践要点小结设置方式sys.config的{kernel, [{Key, Value}, ...]}段、erl -kernel Key Value命令行或运行时application:set_env(kernel, Key, Value)优先级配置参数优先于同名已废弃命令行参数例如connect_all、epmd_module、erl_epmd_node_listen_port分布式集群一致性net_ticktime、net_tickintensity必须在所有通信节点上保持一致否则会导致节点被误判下线或检测延迟异常net_ticktime需为net_tickintensity的整数倍否则内部向上取整嵌入式精简系统start_boot_server、start_disk_log、start_pg、start_timer等开关默认false按需开启以节省资源完全禁用分布式功能可设置start_distribution false故障诊断通过kill -USR1 beam.pid触发带 slogan 的 crashdump、kill -TERM触发优雅关闭、net_kernel:get_net_ticktime/0核对 tick 配置是日常运维三板斧。以上全部参数的默认值均可与 kernel.app.src 的{env, [...]}段以及 net_kernel.erl、global.erl、erl_signal_handler.erl 等实现源码互相印证为实际部署调优提供可靠依据。赞分享编程语言语言运行时标准库编译器并发编程【免费下载链接】otpErlang/OTP项目地址https://gitcode.com/gh_mirrors/ot/otp点击查看免费下载相关推荐Authelia bcrypt 密码哈希生成实战指南authelia crypto hash generate bcrypt 命令详解与源码原理Authelia bcrypt 密码哈希生成实战指南authelia crypto hash generate bcrypt 命令详解与源码原理 本文以 Au编程语言语言运行时标准库编译器并发编程PowerDNS权威服务器配置详解PowerDNS权威服务器配置详解 前言 PowerDNS是一款功能强大且灵活的DNS服务器软件其权威服务器组件提供了丰富的配置选项。本文将深入解析Power网络与通信**Erlang/OTP 安装与配置完全指南**Erlang/OTP 安装与配置完全指南 项目基础介绍及主要编程语言 Erlang/OTP 是一个专为构建高度可扩展的软实时系统设计的编程语言及其运行时环境。它编程语言语言运行时标准库编译器并发编程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表