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

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(使用前将#替换为@)

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

随机推荐

  • 如何安装并运行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
  • 如何实现零宕机的配置热加载

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