如何实现零宕机的配置热加载

2023-11-12

对于高可用的服务,为了保证服务可用性,更新配置时必然不能直接停止服务,可以使用配置热加载来避免服务暂停,不需要重启服务。

配置的热加载可以分为两个场景,手动更新与自动更新。

手动更新

对于一些临时调试,服务数量不多的情况下,可以进行手动更新配置。需要实现两点,如何触发更新,以及接受到更新后如何操作。

触发更新的手段很多,常见的有

  • 通过命令行,例如nginx -s reload
  • 通过信号,通常是SIGHUP,比如sshd、Prometheus等,其实Nginx的热加载内部也是调用SIGHUP信号
  • HTTP接口,例如Prometheus也支持HTTP的方式通过curl -X POST :9090/-/reload可以重新加载配置
  • RPC接口,类似HTTP

接受到配置更新通知后,需要程序内部来重新加载配置,类似初始化过程,但要注意运行时可以要加锁来保证线程安全。

自动更新

自动更新是建立手动更新的基础上,首先服务要提供手动更新的方法,其次可以通过服务本身或者外部进程来自动调用配置更新接口,外部程序可以使用SideCar的形式与服务绑定。

自动加载配置的关键是如何感知配置变化,要考虑到单机环境与分布式环境。

单机环境

Linux提供了inotify接口,可以用来监听文件或者目录的增上改查事件。我们可以使用inotify来监听配置变化,如果有更新则调用更新接口来实现热加载。其他平台也提供了类似的接口。

在Golang中fsnotify提供了跨平台的文件监听接口,可以方便的监听文件,使用方式如下:

    watcher, _ := fsnotify.NewWatcher()
    defer watcher.Close()

    // 监听目录或者文件
    watcher.Add("/tmp")

    go func() {
        for {
            // 获取监听事件
            select {
            case event, ok := <-watcher.Events:
                if !ok {
                    return
                }
                log.Println("event:", event)
                if event.Has(fsnotify.Write) {
                    log.Println("modified file:", event.Name)
                    // 进行更新操作
                }
            case err, ok := <-watcher.Errors:
                if !ok {
                    return
                }
                log.Println("error:", err)
            }
        }
    }()

分布式环境

在分布式环境中实现配置热更新,需要能够感知配置(本地或者远端),对于本地配置需要平台配合将远端配置同步到本地(比如kubernetes会同步ConfigMap到Pod中),然后按照单机环境的方式来监听文件变化。

对于远端配置,需要依赖额外的分布式配置中心,比如Apollo、etcd、ZooKeeper等。以etcd为例,etcd提供了watch接口,可以监听对应配置的变化

// 获取watch Channel
ch := client.Watch(d.watchContext, d.Prefix, clientv3.WithPrefix())

// 处理事件
for {
		select {
		case wr, ok := <-ch:
			if !ok {
				return fmt.Errorf("watch closed")
			}
			if wr.Err() != nil {
				return wr.Err()
			}
			for _, ev := range wr.Events {
				key, val := string(ev.Kv.Key), string(ev.Kv.Value)
				switch ev.Type {
				case mvccpb.PUT:
					// 更新处理逻辑
                    // 1. 对比配置是否变化
                    // 2. 变化了更新内存中的配置
				case mvccpb.DELETE:
					// 删除处理逻辑
				}
			}
		}
	}

为了实现配置更新通知,通常有两种方式,Pull与Push。

  • Pull就是客户端轮询,定期查询配置是否更新,这种方式实现简单,对服务器压力小,但时效性低
  • Push由服务端实现,通过维护一个长连接,实时推送数据,这种方式时效性高,但逻辑更复杂,连接过多会影响服务端性能。目前etcd v3版本是通过HTTP2来实现实时数据推送

总结

本文主要总结实现配置热更新的多种方式,手动更新可以通过Socket、信号等进程间通信手段来通知服务,自动更新可以通过inotify来感知配置变化,在分布式环境中就需要配合分布式配置中心来进行热更新。

Explore more in https://qingwave.github.io

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何实现零宕机的配置热加载 的相关文章

  • 如何在 Python 中将列表变量传递给 subprocess.call 命令

    我有一个清单 apps apps append wq35a5huqlja45jsyukrpmwuiayovrmh apps append q7mimvgduueernwvw4y22t5huemykntw apps append pmudbp
  • 访问单个结构体成员是否会将整个结构体拉入缓存?

    我一直在读乌尔里希 德雷珀的书 每个程序员都应该了解的内存知识 http lwn net Articles 250967 并在部分3 3 2 缓存效果的测量 http lwn net Articles 252125 页面中间 它给我的印象是
  • Python:文本覆盖在所有窗口顶部,包括 Linux 中的全屏

    我正在尝试用 python 编写一个简单的脚本 在所有窗口和全屏应用程序之上输出文本 该脚本的目的是以类似于 Steam FPS 计数器工作方式的方式输出平均负载和可用内存 以及其他有用的统计数据 到目前为止 我尝试了 pygame 但据我
  • 我如何知道哪个 /dev/input/eventX (X=0..7) 有 Linux 输入流?

    我正在尝试捕获 Linux 键盘 鼠标输入 并且我正在读取类似的事件 dev input event2 但似乎输入有时会定向到 dev input event2 有时到 dev input event3 我想知道是否有一个地方可以找出哪个流
  • 如何在 ssh 命令中使用长输入参数正确转义 qsub 命令?

    我有一个复杂的 qsub 命令可以远程运行 PROJECT NAME TEXT TEST PROJECT PACK ORGANIZATION source organization MY ORGANIZATION CONTACT NAME
  • 通过元层覆盖 Yocto 类

    感谢您的时间和支持 我计划使用 swupdate 进行更新 因此 我需要创建一个额外的分区来存储恢复分区 poky meta classes image live bbclass 是创建分区并刷新根文件系统的类 我已更新上述文件以再创建一个
  • Linux 上的最大子进程数

    下面的代码将产生尽可能多的子级 自己不会进一步fork 一旦父进程退出就会变成僵尸 父进程将产生多少个子进程 int main int argc char arg while fork gt 0 子进程的数量可以通过以下方式限制设置限制 2
  • 如何在 Linux 中检测通过 GUI 登录的用户

    我想在我的程序中捕获通过 GUI 登录的用户名 我的程序作为守护进程从 root 登录运行 如果非 root 用户通过 GUI 登录 我的程序应该会收到通知 我正在粘贴我当前的程序 该程序调用一个 perl 脚本 利用系统调用来检查当前登录
  • 从 Linux 内核模块的文件描述符获取文件名/路径?

    在Linux内核模块中 有没有一种方法可以从文件名 路径中获取文件名 路径 unsigned int fd 我知道这个答案 如何从内核模块内的文件描述符获取文件名 https stackoverflow com questions 8250
  • 为 bash 脚本创建应答文件

    我想为别人的 bash 脚本创建一个应答文件 当您运行 bash 脚本时 第一次安装该软件时 系统会询问您 5 个问题 我用的是yes script命令并且有效 它会自动应答yes对所有问题 不过我还是想回答一下no对于最后一个问题 有办法
  • 哪个信号被传递到信号处理程序中死锁的进程

    我有一个来自调用信号处理程序后死锁的进程的核心转储 如何确定传送了哪个信号以及是谁发送的 GDB 为接收信号的线程生成的回溯如下 信号处理程序在第 15 帧中被调用 gdb bt 0 0x00007fa9c204654b in sys fu
  • 如何在没有 root 访问权限的情况下在 Ubuntu 上安装 Google Test?

    我正在尝试根据以下方式安装 Google Test这个答案 https stackoverflow com a 21314020 6560773在没有 root 访问权限的 Ubuntu 上 因为我需要在工作中学习和使用它 设法在我自己的用
  • 获取后台进程的退出代码

    我有一个从我的主 bourne shell 脚本中调用的命令 CMD 该命令需要很长时间 我想修改脚本如下 作为后台进程并行运行命令 CMD CMD 在主脚本中 有一个循环每隔几秒监视生成的命令 该循环还向标准输出回显一些消息 指示脚本的进
  • c 中的分叉和管道过程

    所以我有一个项目要做 但我完全被难住了 我花了十个小时却一无所获 我并不是特别想要答案的代码 但是一些伪代码和正确方向的良好提示将有帮助 它分叉多个进程 k 命令行参数 通过管道连接 每个进程都连接到下一个进程 最后一个进程连接到第一个进程
  • 如何让SSH命令执行超时

    我有一个这样的程序 ssh q email protected cdn cgi l email protection exit echo output value gt 在上面的代码中 我尝试通过 SSH 连接到远程服务器 并尝试检查是否可
  • Bash:更新文件中的变量

    我知道这是一个简单的答案 在找到答案之前我可能可以继续在谷歌上进行挖掘 但我的日程很紧 我希望能得到一个轻松的答复 我需要在安装时更新 ifcfg eth0 中的变量 换句话说 这就是需要发生的事情 以下变量需要更改 ONBOOT no B
  • 您可以bind()和connect() UDP连接的两端吗

    我正在编写一个点对点消息队列系统 它必须能够通过 UDP 运行 我可以任意选择一侧或另一侧作为 服务器 但这似乎不太正确 因为两端都从另一端发送和接收相同类型的数据 是否可以绑定 和连接 两端 以便它们只能彼此发送 接收 这似乎是一种非常对
  • 安装 Pillow 错误:安装脚本退出并出现错误:命令“x86_64-linux-gnu-gcc”失败,退出状态为 1

    当我尝试安装 Pillow 2 5 3 时 我收到错误 命令 x86 64 linux gnu gcc 失败 退出状态为 1 这是所发生事件的完整日志 http pastebin com 5k2TsyJY 我需要这个库作为另一个 pytho
  • 启动jetty服务器时出现NoClassDefFoundError

    我正在尝试在码头服务器中托管我的网络应用程序 spring 我将 war 文件复制到 jetty 服务器中的 webapp 文件夹中 我并不是想嵌入jetty服务器 而是试图在jetty内托管应用程序 如tomcat 我没有安装jetty
  • /etc/php5/conf.d 文件夹中的 .ini 文件有什么用?

    我知道 ini 文件位于 etc php5 cli与 PHP 的 CLI 使用有关 文件位于 etc php5 fpm是关于 PHP 的 FastCGI FPM 方面 但是位于以下位置的 ini 文件又如何呢 etc php5 conf d

随机推荐

  • 如何安装并运行SiB-CROP模型

    目录 1 环境配置 1 1 Supported Platforms 1 2 Prerequisites 2 下载SIB CROP代码 3 SIB CROP模型编译 4 下载驱动数据 5 SIB CROP模型运行 主要参考 1 官方文档 ht
  • PSYoungGen ParNewGeneration DefNewGeneration等名词解释

    HotSpot VM的GC组老人之一Jon Masamitsu很久之前就写过blog讲解这个 https blogs oracle com jonthecollector entry our collectors 简单来说 有这么多东西反映
  • Python+opencv:图像修复

    简介 OpenCV 是一个开源的计算机视觉库 它包含了许多图像处理和计算机视觉算法 使用 OpenCV 进行图像修复主要依赖于传统的图像处理技术 OpenCV 图像修复方法及其原理 1 去噪 图像去噪是消除图像中的噪声 提高图像质量的过程
  • Springboot2.0 上传图片 jar包导出启动(第二章)

    目录 一 目录文件结构讲解 二 文件上传实战 三 jar包方式运行web项目的文件上传和访问处理 核心知识 最后 一 目录文件结构讲解 简介 讲解SpringBoot目录文件结构和官方推荐的目录规范 1 目录讲解 src main java
  • 连接已失效_西门子S7-1500PLC如何通过IP地址进行HMI连接

    通过系统 IP 地址进行 HMI 连接 要求 S7 1500R H 冗余系统 如 CPU 1513R 1PN 系统 IP 地址已启用 带有 PROFINETI 接口的 HMI 设备 操作步骤 要与 S7 1500R H 冗余系统建立 HMI
  • ai人工智能_人工智能的6种最佳启动选择

    ai人工智能 意见 Opinion Artificial Intelligence is the fastest growing field in the present day According to fortune the stati
  • linux下u盘如何将分割的合在一起,我又一个8g的U盘,想分两个区,一个区装系统,用PE引导,另一个分割槽用来存放档案,有什么工具,怎么操作,...

    我又一个8g的U盘 想分两个区 一个区装系统 用PE引导 另一个分割槽用来存放档案 有什么工具 怎么操作 以下文字资料是由 历史新知网www lishixinzhi com 小编为大家搜集整理后发布的内容 让我们赶快一起来看一下吧 我又一个
  • Window10 64位,通过Python读取.mif, shp文件

    1 读取依赖库及安装 依赖模块osgeo osgeo依赖于GDAL mif 是Mapinfo支持的信息 shp是 postgis存储地理空间信息的文件格式 尝试了很多安装方法 包括安装Anaconda 因为有博客说anaconda中包含GD
  • 第8章 应用程序架构

    第8章 应用程序架构 之前 介绍了让团队可以对问题域的有用概念抽象建模的技术 不过 这一章将介绍可以在应用程序上下文中利用领域模型的模式 其中考虑到了持久化 展现以及其他技术需求 应用程序架构 遵循DDD原则开发软件不需要使用任何特殊的应用
  • macbook bluetooth is not available (蓝牙不可用)

    新的MacBookPro Retina 一直没用过蓝牙 今天碰巧带了蓝牙耳机 连接的时候发现蓝牙的图标上面多了一个波浪线 显示 is not available google了几种方法 1 删除 Library Preferences 并重
  • STL在算法设计中的应用——数据的排序

    数据的排序 STL在算法设计中的应用有如下几种 存放主数据 存放临时数据 检测数据元素的唯一性 数据的排序 优先队列作为堆 此篇主要内容就是 数据的排序 对于list容器中元素的排序可以使用其成员函数sort 对于数组或者vector等具有
  • Java OutputStreamWriter.write()方法具有什么功能呢?

    转自 Java OutputStreamWriter write 方法具有什么功能呢 下文笔者讲述OutputStreamWriter write 方法的功能简介说明 如下所示 OutputStreamWriter的功能 输出字符流 自动将
  • 博客搭建(零):静态博客和动态博客的区别

    更好的阅读地址哦 静态博客 HTML CSS Javascript 优点 速度快 占用小 成本低 很安全 不易崩溃 易于抓取 缺点 无法支持原生评论 访问量统计 注册登录等功能 操作繁琐 上手难 网页内容固定 代码完全公开 日常维护繁琐 结
  • Ubuntu安装qt-opensource-linux-x64-5.11.1教程

    登陆qt官方下载页面 http download qt io archive qt 本文以安装qt opensource linux x64 5 11 1为例 把下载好的qt opensource linux x64 5 11 1 run放
  • node.js多版本管理nvm安装、切换、443问题等

    一 背景 线上环境出现问题 前端小哥本地编译不通过需要帮其看一下具体原因 由于我本地的node版本时16 3 0 项目编译需要v14 19 3 由于不同的项目支持的node版本不同 此时需要一个node多版本的管理工具 这是需要nvm管理n
  • 腾讯云直播工具类

    Maven 腾讯云直播
  • Port 1-1023

    Port Protocol 0 Reserved 1 TCPMUX TCP Port Service Multiplexer 2 Management Utility 3 Compression Process 4 5 Remote Job
  • LeetCode 剑指 Offer 34. 二叉树中和为某一值的路径

    输入一棵二叉树和一个整数 打印出二叉树中节点值的和为输入整数的所有路径 从树的根节点开始往下一直到叶节点所经过的节点形成一条路径 示例 给定如下二叉树 以及目标和 sum 22 5 4 8 11 13 4 7 2 5 1 返回 5 4 11
  • 刷题之轮转数组

    给你一个数组 将数组中的元素向右轮转 k 个位置 其中 k 是非负数 示例 1 输入 nums 1 2 3 4 5 6 7 k 3 输出 5 6 7 1 2 3 4 解释 向右轮转 1 步 7 1 2 3 4 5 6 向右轮转 2 步 6
  • 如何实现零宕机的配置热加载

    对于高可用的服务 为了保证服务可用性 更新配置时必然不能直接停止服务 可以使用配置热加载来避免服务暂停 不需要重启服务 配置的热加载可以分为两个场景 手动更新与自动更新 手动更新 对于一些临时调试 服务数量不多的情况下 可以进行手动更新配置