ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Erlang/OTP 配置系统全解析:config 配置文件、sys.config 与 `-config`/`-configfd` 实战指南

Erlang/OTP 配置系统全解析:config 配置文件、sys.config 与 `-config`/`-configfd` 实战指南 编程语言语言运行时标准库编译器并发编程【免费下载链接】otpErlang/OTP项目地址https://gitcode.com/gh_mirrors/ot/otp点击查看免费下载本文以 Erlang/OTP 官方配置参考文档lib/kernel/doc/references/config.md为核心骨架结合仓库中的erl启动器文档、application模块源码与 SASL 发布处理实现系统讲解 Erlang/OTP 中配置文件Name.config的语法、命令行接入方式-config与-configfd、嵌入式模式下的sys.config约定、多文件 include 与合并语义以及通过application:get_env/1,2读取配置参数的完整链路。读完本文你将能独立编写、组织并调试 Erlang/OTP 应用的系统配置文件理解配置优先级与发布升级期间配置更新的真实行为。配置文件是什么应用配置参数的载体在 Erlang/OTP 中配置文件configuration file用于为系统中的各个应用提供配置参数configuration parameters的取值。系统通过erl命令行的-config Name参数来加载名为Name.config的系统配置文件等价地命令行参数-configfd以文件描述符file descriptor的方式读取同样的配置数据而不是从磁盘文件名读取。配置参数的值最终由调用application:get_env/1,2获取——这是所有 Erlang 代码读取应用配置的标准入口lib/kernel/src/application.erl。配置来源的优先级文档明确给出了三层配置来源的覆盖关系应用资源文件application resource file见 app(4)中的{env, Env}项定义了参数的默认值配置文件或文件描述符中的参数值覆盖应用资源文件中的值命令行 flags见 erts:erl(1)总是覆盖配置文件中的值。也就是说优先级从低到高为应用资源文件 配置文件 / 文件描述符 命令行参数。这是设计上允许系统级默认值 部署级覆盖 启动级临时覆盖三层协作的基础。多个配置来源的读取顺序配置数据从多个配置文件和文件描述符读取时严格遵循命令行上出现的先后顺序。例如erl -config a -configfd 3 -config b -configfd 4系统会依次读取a.config、文件描述符3、b.config、文件描述符4。如果一个配置参数在这些来源中被多次指定最后一个值覆盖前面所有的值last one wins。文件语法单个 Erlang 项的列表结构配置文件必须命名为Name.config其中Name可以是任意名字。文件内容必须是一个单一的 Erlang 项其语法如下[{Application1, [{Par11, Val11}, ...]}, ... {ApplicationN, [{ParN1, ValN1}, ...]}].其中Application atom()—— 应用名Par atom()—— 配置参数名Val term()—— 配置参数的值可以是任意 Erlang 项原子、数字、字符串、列表、元组、映射等。由于整个文件是一个可被file:consult/1解析的普通 Erlang 项仓库中 SASL 的发布打包代码正是用file:consult/1来校验sys.config的可解析性与格式见 lib/sasl/src/systools_make.erl 的check_sys_config/1。一个典型的最小配置文件示例[{kernel, [{logger_level, warning}, {logger, [{handler, default, logger_std_h, #{config #{type standard_io}}}]}]}, {myapp, [{port, 8080}, {debug, true}]}].这里为kernel与myapp两个应用分别设置了参数。注意Val的term()类型意味着配置值可以携带复杂的嵌套数据结构例如 logger 的 handler 配置就是一个多层映射。命令行接入-config与-configfd启动器文档 erts/doc/references/erl_cmd.md 对这两个参数给出了精确的定义-config Config [Config ...]指定一个或多个配置文件Config.config用于配置应用。配置文件格式与读取顺序详见 config 文档使用示例erl -config myapp -config logger等价于依次读取myapp.config与logger.config。-configfd FD [FD ...]指定一个或多个携带应用配置数据的文件描述符。其行为细节来自 erl_cmd.md配置型文件描述符会被读取到末尾EOF然后自动关闭文件描述符中的配置内容会被保存以便在调用init:restart/0或init:restart/1时复用——这正是 erts/preloaded/src/init.erl 中get_configfd/1、set_configfd/2所维护的configfdid_to_config映射的用途参数-configfd 0隐含-noinput因为 stdin 被用于读取配置不推荐将文件描述符 1标准输出和 2标准错误与-configfd一起使用因为这两个描述符通常用于向控制台打印信息。官方文档给出了两个 Unix shell 示例。第一个使用进程替换process substitution从文件描述符 3 读取配置$ erl \ -noshell \ -configfd 3 \ -eval \ io:format(~p~n,[application:get_env(kernel, logger_level)]),erlang:halt() 3 \ (echo [{kernel, [{logger_level, warning}]}].) {ok,warning}第二个示例演示两个文件描述符的顺序与覆盖规则——error覆盖warning$ echo [{kernel, [{logger_level, warning}]}]. test1.config $ echo [{kernel, [{logger_level, error}]}]. test2.config $ erl \ -noshell \ -configfd 3 \ -configfd 4 \ -eval \ io:format(~p~n,[application:get_env(kernel, logger_level)]),erlang:halt() \ 3 test1.config 4 test2.config {ok,error}可以看到命令行中后出现的-configfd 4对应的配置最终生效印证了按命令行顺序读取、后者覆盖前者的规则。-configfd特别适合在容器化、嵌入式中不便落盘临时配置文件的场景可以安全地通过管道或继承的描述符注入配置。配置优先级与启动器侧的覆盖实现从实现角度看-config/-configfd解析出的配置最终由application_controller统一管理lib/kernel/src/application_controller.erl并通过application:get_env/1,2暴露给应用代码。而命令行的最后覆盖语义则体现在 erts/preloaded/src/init.erl 的make_permanent/3与set_flag/3中当新发布版本被安装并设为 permanent 后init会通过set_flag(config, Config, Flags)更新内部 flags保证init:restart/0等重启路径使用新的-boot与-config参数——这也是配置文件内容会被保存并在重启时复用的底层原因。嵌入式模式与sys.config当 Erlang 以嵌入式模式embedded mode启动时系统假设恰好使用一个系统配置文件名为sys.config且必须位于$ROOT/releases/Vsn其中$ROOT是 Erlang/OTP 的安装根目录Vsn是发布版本号。发布处理release handling依赖这个假设安装一个新发布版本时新的sys.config会被读取用于更新各应用的配置。这意味着如果指定了另一个.config文件或者指定了多个.config文件会导致应用配置的更新不一致因为升级机制只认releases/Vsn/sys.config这一个文件。不过官方提供了一条从sys.config指向其它配置文件的路子——即下一节的include 机制。仓库中的相关实现证据SASL 的发布处理器 lib/sasl/src/release_handler.erl 在安装/升级发布时读写sys.config升级时从releases/CurrentVsn/sys.config复制到新版本目录L1834-L1836安装时用file:consult/1解析新版本的sys.configL2344发布打包工具 lib/sasl/src/systools_make.erl 在生成发布 tar 包时优先打包sys.config.src找不到才打包sys.config并会对sys.config做格式校验check_sys_config/1。另外本仓库根目录自带一个空的sys.config内容为[].见 sys.config可作为嵌入式启动时零配置的参考样例。从 sys.config 或 -configfd 配置中引入其它文件sys.config以及通过-configfd传入的配置都支持include其它配置文件。这种语法的结构可以用 Erlang 类型语言描述为[{Application, [{Par, Val}]} | IncludeFile].其中IncludeFile string()—— 一个.config文件的名字扩展名.config可以省略推荐使用绝对路径。相对路径的解析规则如果在sys.config中使用了相对路径IncludeFile会先在sys.config所在目录查找然后再相对于模拟器的当前工作目录查找如果在-configfd配置中使用了相对路径则先相对于包含 boot script 的目录查找参见-boot参数再相对于当前工作目录查找。这样设计使得无论在发布中还是在手工用-config/-configfd启动的节点里无论当前工作目录是什么都能用sys.config稳定地指向其它.config文件。合并语义遍历sys.config或-configfd配置内容时遇到文件名字符串就读取其内容并与当前结果合并遇到应用配置元组{Application, Env}就与当前结果合并合并意味着新参数被添加已存在的参数值被覆盖。文档给出的经典示例注意sys.config中字符串与元组可混排且最后一个元素后是句点sys.config: [/home/user/myconfig1 {myapp,[{par1,val1},{par2,val2}]}, /home/user/myconfig2]. myconfig1.config: [{myapp,[{par0,val0},{par1,val0},{par2,val0}]}]. myconfig2.config: [{myapp,[{par2,val3},{par3,val4}]}].合并后myapp的最终环境为[{par0,val0},{par1,val1},{par2,val3},{par3,val4}]逐项分析合并过程par0只出现在myconfig1中保留val0par1先被myconfig1设为val0又被sys.config覆盖为val1par2经历val0 - val2 - val3三次覆盖par3仅出现在myconfig2保留val4。可以看到合并顺序是从左到右、后者覆盖前者。错误处理在启动阶段如果sys.config或-configfd配置中指定的 include 文件不存在或内容错误运行时系统会在启动之前直接中止abort在发布安装阶段安装新发布版本时如果加载 include 文件出错安装不会失败而是返回一条错误消息并忽略出错的文件。这一差异体现了启动时严格、升级时宽容的工程取舍启动时配置错误必须立即暴露而发布升级时宁可跳过损坏的配置片段也要保证服务可切换。编程式读写配置参数配置文件的最终消费者是应用代码。标准读取接口定义在 lib/kernel/src/application.erlapplication:get_env(Par)L901-L902—— 获取当前应用由group_leader归属决定的参数值返回undefined | {ok, Val}当应用未加载、参数不存在或调用进程不属于任何应用时返回undefinedapplication:get_env(Application, Par)L918-L919—— 显式指定应用application:get_env(Application, Par, Def)L932-L933—— 参数不存在时返回默认值Defapplication:get_all_env/0,1L939-L953—— 返回应用的全部参数-值列表未加载或不属于任何应用时返回[]。这些调用最终都委托给application_controllerlib/kernel/src/application_controller.erl执行配置数据由该进程集中持有。对应地运行时写入配置的接口是application:set_env/1,2OTP 21.3 起L767-L809set_env(Config)/set_env(Config, Opts)可一次设置多个应用的配置等价于逐个调用set_env/4但更高效选项persistent true可保证设置的参数在应用加载/重载时不被应用资源文件中的值覆盖选项timeout用于指定超时默认 5000 ms适合应用控制器繁忙的场景官方同时给出Warning该函数只应在确认了解后果时用于自己的应用滥用可能使应用进入怪异、不一致的故障状态——因为应用在何时、以何种频率读取参数完全取决于应用自身实现。实战要点与常见陷阱综合官方文档与仓库实现以下是编写与部署配置文件时值得注意的要点多来源顺序敏感-config/-configfd按命令行出现顺序读取后者覆盖前者需要基础配置 增量覆盖时把覆盖项放在后面的来源中。优先级记忆资源文件 配置文件/描述符 命令行 flags调试参数不生效时先确认是否有更高优先级来源在覆盖。嵌入式发布只认一个sys.config位于$ROOT/releases/Vsn/想拆分配置务必使用 include 机制并优先使用绝对路径避免相对路径解析依赖当前工作目录。include 顺序即合并顺序新参数追加、已有参数覆盖最终环境是全部来源按序合并的结果。-configfd 0隐含-noinput且不要占用描述符 1、2配置型描述符读取到 EOF 后会被关闭。启动期 include 文件缺失会直接 abort发布升级期则仅告警并忽略两者的行为差异是设计使然。重启复用-configfd内容会被保存init:restart/0、init:restart/1重启后会复用无需重复注入。读取配置统一走application:get_env/1,2,3避免直接解析文件造成配置源不一致。参考与延伸阅读配置格式与 include 机制的权威定义lib/kernel/doc/references/config.md应用资源文件.app格式lib/kernel/doc/references/app.mderl命令行为参数-config/-configfd/-booterts/doc/references/erl_cmd.mdboot script启动脚本格式lib/sasl/doc/references/script.md应用与发布设计原则system/doc/design_principles/design_principles.md、发布处理底层实现配置读取与重启复用 erts/preloaded/src/init.erl、配置存储与查询 lib/kernel/src/application_controller.erl、发布升级中的sys.config处理 lib/sasl/src/release_handler.erl 与 lib/sasl/src/systools_make.erl赞分享编程语言语言运行时标准库编译器并发编程【免费下载链接】otpErlang/OTP项目地址https://gitcode.com/gh_mirrors/ot/otp点击查看免费下载相关推荐PowerToys Run 命令面板实战从唤醒、搜索到自定义的完整配置PowerToys Run 命令面板实战从唤醒、搜索到自定义的完整配置 PowerToys Run 是微软 PowerToys 里的命令面板用一个快捷键就能后端API网关Boto3 配置完全指南Config 对象、环境变量与 ~/.aws/config 配置文件详解Boto3 配置完全指南Config 对象、环境变量与 ~/.aws/config 配置文件详解 本篇技术指南围绕 Boto3AWS SDK for Pyt后端云原生Docz 自定义配置文件位置custom-config-location--config 参数与 src/doczrc.js 实战指南Docz 自定义配置文件位置custom config location config 参数与 src/doczrc.js 实战指南 导读 Docz 默认文档静态站点开发工具创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表