IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> 服务优雅下线,没你想的那么简单? -> 正文阅读

[网络协议]服务优雅下线,没你想的那么简单?

大家好,我是架构摆渡人。这是实践经验系列的第八篇文章,这个系列会给大家分享很多在实际工作中有用的经验,如果有收获,还请分享给更多的朋友。

服务部署,是一个避免不了的问题。按正常迭代的速度一般两周会发一个版本,此时就需要部署新的代码。发布方式,我相信主流的都是用滚动发布,因为这样的成本是最低的,机器数量是固定的,一台台机器轮流发布。

但是我们总会在发布过程中碰到一些报错信息,那是因为请求还没结束,某些组件已经强制停止了,比如我们的数据源,比如异步任务还没处理完。

那么如何解决这个问题呢?那就是服务优雅下线,估计大家都听过这个词,但我不知道有多少做到了随时发布都不影响功能的正常使用。

优雅下线涉及点

外部请求必须处理完

服务时时刻刻都在处理请求,一旦收到要停止的命令,那么必须等待当前的请求执行完毕才能去关闭一些资源,否则就会出现各种异常。

除了等待,还需要让外部的请求不要再过来,要告诉别人,我要下班了,不要来找我了,去找其他人吧。否则你永远都下不了班,是一样的道理。

异步任务必须处理完

这里的异步任务通常指我们放入线程池中进行处理的任务,如果强制进行程序的停止,那么线程池里的任务就会丢掉,所以除了同步被外部调用的逻辑要处理完,这种异步的逻辑也是要处理完的。

这里再提一点,就是如果异步任务丢失会对业务造成影响的这种场景,建议还是不要放到线程池里面进行处理,如果要放,那么必须有持久化,程序重启后可以继续执行。

消息必须消费完

消息也是异步任务的一种类型,我们的目标肯定也是需要让消息消费完才行。但是消息跟线程池里的任务最大的差别就在于:消息是有持久化的,并且有重试功能。

就算消息没消费完,程序强制停止,这条消息没有ACK,然后就会重试到另一台机器的实例上继续执行,前提是你的这个执行逻辑不能产生脏数据,一定要通过事务保证数据的一致性。

优雅下线解决方案

注销服务实例

下线最重要的一件事情就是注销自己的实例,这样才不会有后续的请求过来。注销实例主要是跟注册中心交互,将自己的实例从注册中心下线掉就行了。下线后服务消费者会重新从注册中心拉取最新的实例列表,也就不会将请求路由过来。

如果要下线的这个服务不是一个内部服务,而是网关呢?网关是流量的入口,客户端的请求过来的,客户端是自然不知道网关有多少实例,所以在网关前面都有一个负载均衡器,比如常用的Nginx。

那就需要将这个下线的网关实例从Nginx中进行下线操作,这样后续的流量才不会被转发过来,跟内部服务是一样的道理。

Nginx如果有独立的模块去对接注册中心的话,那么还是把注册中心的给下线掉,Nginx就能感知到下线动作。如果没有对接,而是固定的配置信息,那么就需要改Nginx的配置,然后重新加载即可。

注销MQ消费实例

通过下线注册中心里面的实例,外部流量就不会请求过来。此时还需要将MQ的实例进行下线操作,告诉MQ的服务端,不要再给我推消息了或者是客户端不再拉取消息。

实现思路

  1. 写一个停止流量的接口,在接口中将本身实例从注册中心,MQ进行下线操作。
  2. 写一个检测流量是否结束的接口,在接口中判断当前是否还有正在工作的线程,有没有正在处理的消息,有没有正在执行的异步任务等等。
  3. 当完全没有流量的时候,发布平台直接对当前进程进行kill操作,此时所有任务都已执行完并且没有新流量进来,无损操作。
  4. 执行发布流程。
    这里其实涉及到一个点,就是假如3分钟了,还是有任务在处理,那么是否要强制中断?

这里其实可以这么做,就是我们的服务本身的实例一旦下线,正常的话几秒钟后就应该没有任务了,因为对外的接口基本上都是毫秒级响应。主要就怕异步任务,比如线程池里堆积了好多任务等待执行,所以大家需要去梳理下,如果有这种场景就调整,不要往线程池里堆积任务,这样才能保证在下流量的时候能够尽快执行完成。

总结

其实优雅下线的核心在于流量的切换,就是我要下线的这个服务必须把所有外部的流量都切走,然后再把没处理完的事情处理完,完成后就可以直接重新发布了。

如果你们上了容器的话,容器管理平台应该是能够提供优雅下线的方式,像K8s里面应该就有优雅停止Pod的方式,不过我对K8s不太熟,记得是有的,其实原理也很简单,先启动一个Pod,完成之后将流量切过去就行了,这种方式更简单,充分利用了容器的优势。

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-01-17 11:49:32  更:2022-01-17 11:51:45 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 12:47:46-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码