新闻详情

新闻详情

首页 / 资讯中心 / 详情

Envoy 热重启包装器 hot-restarter.py:信号驱动的进程管理与平滑升级

发布时间:2026/9/14 15:18:56来源:尧图网络
Envoy 热重启包装器 hot-restarter.py:信号驱动的进程管理与平滑升级
Envoy 热重启包装器 hot-restarter.py信号驱动的进程管理与平滑升级【免费下载链接】envoyCloud-native high-performance edge/middle/service proxy项目地址: https://gitcode.com/GitHub_Trending/en/envoy本文围绕 Envoy 仓库中提供的热重启hot restartPython 包装脚本 hot-restarter.py 展开。读完后你将掌握如何让 monit、runit 等标准进程管理器托管 Envoy 的完整热重启生命周期包括启动脚本start_envoy.sh的正确写法、RESTART_EPOCH环境变量与--restart-epoch的联动机制、--use-dynamic-base-id场景下的 base ID 持久化要求以及 SIGHUP/SIGTERM/SIGCHLD/SIGUSR1 四类信号在包装器内部的完整处理语义并能结合 hot-restarter.py 的源码理解优雅退出与强制杀进程的时间边界。背景为什么需要一个热重启包装器Envoy 的核心运维能力之一是热重启新进程可以在旧进程 drain排空期间完整加载新代码与新配置通过 Unix domain socket 从旧进程接管监听 socket从而在不中断既有连接的前提下完成代码和配置的双更新。其整体架构进程间通信、drain 流程、--drain-time-s与--parent-shutdown-time-s的关系等在 热重启架构文档 中有完整描述。但热重启有一个前提每次 SIGHUP 触发后必须有一个“父进程/监管者”负责 fork 出携带新 epoch 的新 Envoy 进程并在新旧进程之间维持生命周期管理。官方文档 Hot restart Python wrapper 给出的方案就是仓库自带的hot-restarter.pyhot-restarter.py start_envoy.sh包装器本身不直接启动 envoy 二进制而是把第一个参数一个 shell 脚本forkexec 成子进程。这一设计使得 monit、runit 等进程管理器只需要盯住包装器这一个进程即可——这正是 hot-restarter.py 中main()注释明确写出的设计意图脚本被设计为可被 runit/monit 之类的进程监视器监控一旦它消失进程管理器采取纠正动作。启动脚本 start_envoy.sh 的完整写法文档给出的start_envoy.sh示例使用了 salt/jinja 风格语法可直接替换为任意配置管理系统的模板变量#!/bin/bash ulimit -n {{ pillar.get(envoy_max_open_files, 102400) }} sysctl fs.inotify.max_user_watches{{ pillar.get(envoy_max_inotify_watches, 524288) }} exec /usr/sbin/envoy -c /etc/envoy/envoy.cfg --restart-epoch $RESTART_EPOCH \ --service-cluster {{ grains[cluster_name] }} \ --service-node {{ grains[service_node] }} \ --service-zone {{ grains.get(ec2_availability-zone, unknown) }}其中几个关键点ulimit -n与sysctl fs.inotify.max_user_watches文档特别提示如果 Envoy 需要监听目录中的大量文件做配置热更新必须调高 Linux 的文件 watch 上限示例默认值 524288否则会因内核限制导致 inotify 监听失败。同理代理进程要预留足够的 fd 上限示例默认 102400。exec启动 envoy用exec替换 shell 进程保证 SIGHUP 等信号能直接落在 envoy 进程上且pid_list中记录的 PID 就是 envoy 本体。--restart-epoch $RESTART_EPOCH这是整个热重启协议的核心字段下一节详述。--service-cluster/--service-node/--service-zone这三个 命令行选项 用于覆盖 bootstrap node 信息是 statsd、CDS、tracing、zone-aware 路由等特性正确工作的前提在基于节点的配置管理体系如 salt grains中按主机动态注入即可。RESTART_EPOCH热重启代数与--restart-epoch的联动热重启包装器文档明确指出RESTART_EPOCH环境变量由 restarter 在每次重启时设置并必须传递给--restart-epoch选项。CLI 参考 对--restart-epoch的定义是热重启的“代数”Envoy 经历过多少次热重启而非全新启动首次启动默认为 0该选项决定 Envoy 是创建热重启所需的共享内存区域还是打开一个已存在的区域。在 hot-restarter.py 中这一行为由fork_and_exec()实现def fork_and_exec(): global restart_epoch os.environ[RESTART_EPOCH] str(restart_epoch) logger.info(forking and execing new child process at epoch {}.format(restart_epoch)) restart_epoch 1 child_pid os.fork() if child_pid 0: # Child process os.execl(sys.argv[1], sys.argv[1]) else: # Parent process pid_list.append(child_pid)流程要点脚本启动时restart_epoch初始为 0首次 fork 前将RESTART_EPOCH0写入环境变量再 exec 子进程——即“首次启动”语义每次收到 SIGHUP 再次调用fork_and_exec()时epoch 先自增再传递——新进程拿到RESTART_EPOCH1, 2, 3...对应 CLI 文档 中“每次热重启时应递增”的要求新旧两个 Envoy 进程因此能协商出正确的共享内存/Unix socket 关系epoch 0 创建epoch 0 打开已有区域配合 架构文档 描述的“新进程完成初始化后向旧进程索取监听 socket、再让旧进程进入 drain”的完整握手。--use-dynamic-base-id的特殊约束官方文档以 warning 框强调了与 base ID 相关的硬性约束若使用--use-dynamic-base-id该 flag 仅在RESTART_EPOCH为 0 时允许设置。start_envoy.sh必须获取被选中的 base ID通过--base-id-path把它持久化保存并在后续调用RESTART_EPOCH 0中作为--base-id的值传入。结合 CLI 参考 可把这一约束展开为一条可执行的运维规则选项作用epoch 0epoch 0--use-dynamic-base-id自动选取一个未占用的 base ID允许禁止--base-id-path path把选中的 base ID 写入文件写入不再生效读取已保存值--base-id integer显式指定共享内存 base ID可不设必须与首启选中的值一致也就是说start_envoy.sh中需要实现类似“epoch 为 0 时写--use-dynamic-base-id --base-id-path /var/run/envoy/base_idepoch 大于 0 时读文件并传--base-id $(cat ...)”的分段逻辑否则后续热重启将因共享内存区域不一致而失败。信号处理语义文档约定与源码实现包装器文档定义了四类信号的处理契约hot-restarter.py 在main()中注册了对应的全部处理器L210-L214signal.signal(signal.SIGTERM, sigterm_handler) signal.signal(signal.SIGINT, sigint_handler) signal.signal(signal.SIGHUP, sighup_handler) signal.signal(signal.SIGCHLD, sigchld_handler) signal.signal(signal.SIGUSR1, sigusr1_handler)SIGTERM / SIGINT优雅级联关闭文档约定干净地终止所有子进程并退出。实现见 term_all_children()先卸载 SIGCHLD 处理器signal.signal(signal.SIGCHLD, signal.SIG_DFL)防止关闭过程中反复进入子进程退出回调对pid_list中每个子进程发送 SIGTERM进入等待循环用os.waitpid(pid, os.WNOHANG)非阻塞轮询最长等待TERM_WAIT_SECONDS 30秒L15。源码注释特别提醒若你的进程管理器如 runit 的force-stop在超时后会发 KILL必须保证这个 30 秒小于管理器的 KILL 超时否则包装器会先于管理器被杀掉若 30 秒后仍有子进程存活对其发送 SIGKILLforce_kill_all_children()并以退出码 1 结束——向上游进程管理器传达“并非干净退出”的信号。SIGHUP触发热重启SIGUSR1无关的信号里SIGHUP 是最核心的sighup_handlerL105-L110直接调用fork_and_exec()重新 exec 第一个参数传入的脚本。新子进程带着递增后的RESTART_EPOCH启动Envoy 内部随后与仍在 drain 的旧进程完成 socket 交接。注意此时旧 Envoy 并不会被包装器杀死——它是旧 envoy 自行在 drain 完成后受--parent-shutdown-time-s约束默认 900 秒退出SIGCHLD 处理器再把它从pid_list中移除。SIGCHLD意外退出的熔断保护文档约定若任一子进程意外关停restarter 会把一切都关掉并退出由上层进程管理器负责把整个 restarter 重新拉起来。sigchld_handler 的判定逻辑子进程以退出码 0 结束视为有意退出例如热重启后 drain 完成的旧 envoy仅从列表中移除包装器继续存活子进程以非零退出码结束或被信号杀死标记kill_all_and_exit卸载 SIGCHLD 处理器、强杀其余所有子进程最后以退出码 1 退出——这正是“避免处于不可预期状态”的熔断语义也意味着runit/monit 必须配置成能自动重启 restarter若最终pid_list变空且无异常包装器以退出码 0 退出没有子进程可看自身已无存在意义。SIGUSR1日志轮转的原子重开文档约定SIGUSR1 被转发给 Envoy 子进程用于“原子移动 重开”式访问日志轮转。sigusr1_handler 对pid_list中所有子进程逐一os.kill(pid, signal.SIGUSR1)。这与 CLI 选项--log-path的说明相呼应设置--log-path后日志文件会在处理 SIGUSR1 时被重新打开。因此日志轮转脚本的标准套路是mv 旧日志 归档名之后向 restarter 发 SIGUSR1新旧两个 envoy若旧进程仍在 drain会同时把文件描述符切到新文件。主循环一个只有 3 行的“监管者”值得玩味的是 main() 的收尾部分——注册完信号处理器、fork 出第一个子进程后主循环只做一件事# Start the first child process and then go into an endless loop since everything else happens via # signals. fork_and_exec() while True: time.sleep(60)所有生命周期事件启动、热重启、关闭、异常熔断全部经由信号驱动主线程的存在只是为了让进程保持存活并阻塞在 sleep 中响应信号。这一极简结构也提示运维者restarter 自身几乎没有状态需要持久化它崩溃时由进程管理器重启即可恢复到“拉起一个 epoch 0 的 envoy”的初始状态。热重启配套命令行选项速查部署hot-restarter.py时与热重启直接相关的 CLI 选项 值得放在一起核对选项默认值与 restarter 的关系--restart-epoch integer0必须传入start_envoy.sh中的$RESTART_EPOCH由 restarter 自动递增--base-id integer无多实例共存时每套 envoy 需唯一 base IDepoch 0 时须复用首启选定的值--use-dynamic-base-id/--base-id-path无仅 epoch 0 可用配合脚本持久化 base ID--socket-path pathenvoy_domain_socket抽象命名空间热重启 IPC socket 路径参与同一组热重启的所有 envoy 进程必须一致--skip-hot-restart-on-no-parentfalse允许“父实例已消失”时降级为普通启动而非直接终止对 restarter 异常恢复场景有用--drain-time-s integer600旧进程 drain 时长应短于 parent shutdown 时间--parent-shutdown-time-s integer900新进程等待旧进程自行关闭的上限--hot-restart-version-打印二进制的热重启兼容性版本可与运行中实例的/hot_restart_versionadmin 端点对比升级前判断新旧二进制是否兼容实操部署要点小结进程管理器只盯 restarterrunit/monit 监控hot-restarter.py start_envoy.sh这一个进程SIGCHLD 熔断后 restarter 以非零码退出管理器重启它实现整组自愈。更新二进制/改静态配置向 restarter 发 SIGHUP 即完成热重启日常动态配置变更LDS/CDS 等 xDS则不需要走热重启。时间参数要配套TERM_WAIT_SECONDS30要小于进程管理器的强杀超时--drain-time-s默认 600s要小于--parent-shutdown-time-s默认 900sedge 场景可拉长 drain、S2S 场景可缩短如 60s/90s。Windows 不支持热重启架构文档 明确标注该特性在 Windows 上不可用restarter 方案仅适用于类 Unix 环境。升级前做兼容性检查用--hot-restart-version对比新二进制与运行中实例的版本避免不兼容的二进制直接 SIGHUP。延伸阅读热重启的进程间通信、drain 与 socket 处理细节docs/root/intro/arch_overview/operations/hot_restart.rst全部命令行选项参考docs/root/operations/cli.rst本文主文档docs/root/operations/hot_restarter.rst脚本源码与构建声明restarter/hot-restarter.py、restarter/BUILD【免费下载链接】envoyCloud-native high-performance edge/middle/service proxy项目地址: https://gitcode.com/GitHub_Trending/en/envoy创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

Seata TCC模式实战:分布式事务解决方案详解 2026/9/14 16:10:09

Seata TCC模式实战:分布式事务解决方案详解

## 1. 项目概述第一次接触分布式事务时,我被这个看似简单实则复杂的领域深深吸引。作为从单体架构转型微服务的必经之路,分布式事务问题就像悬在架构师头顶的达摩克利斯之剑。在电商系统中,用户支付成功后需要同时更新订单状态、扣减库存、增…

阅读更多 →
二维区域和问题的动态优化与工程实践 2026/9/14 16:10:09

二维区域和问题的动态优化与工程实践

1. 面试高频题解析:二维区域和(可变)问题第一次在技术面遇到这道题时,我盯着白板上的矩阵愣了足足十秒钟。面试官轻描淡写地说:"这不就是个二维前缀和的变形吗?"后来我才明白,这道题之…

阅读更多 →
高考英语高效备考:资源选择与使用策略 2026/9/14 16:10:09

高考英语高效备考:资源选择与使用策略

1. 高三英语资源合集概述作为一名经历过高考的英语教师,我深知高三阶段英语学习资源的重要性。高三英语资源合集是针对高考英语备考的系统性学习材料集合,包含词汇、语法、阅读、写作、听力等全方位内容。这类资源通常由经验丰富的教师团队整理&#xff…

阅读更多 →
Laravel 8.x框架核心特性与最佳实践解析 2026/9/14 16:10:09

Laravel 8.x框架核心特性与最佳实践解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
博士论文研究方法章节的严谨性与可复现性提升技巧 2026/9/14 16:10:09

博士论文研究方法章节的严谨性与可复现性提升技巧

1. 研究方法章节的常见痛点分析作为指导过数十篇博士论文的学术顾问,我发现研究方法章节普遍存在两大核心问题:严谨性不足和可复现性缺失。这两个问题往往导致评审专家对研究成果的可靠性产生质疑。严谨性不足主要体现在:变量定义模糊不清&am…

阅读更多 →
如何从源码构建 Keploy 的 v3-dev Docker 镜像? 2026/9/14 16:07:09

如何从源码构建 Keploy 的 v3-dev Docker 镜像?

如何从源码构建 Keploy 的 v3-dev Docker 镜像? 【免费下载链接】keploy Open-source platform for creating safe, isolated production sandboxes for API, integration, and E2E testing. 项目地址: https://gitcode.com/GitHub_Trending/ke/keploy Keplo…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞