请问你们是如何实现服务不中断的代码发布更新的

2023-03-10 15:38:38 +08:00
 brader
目前我知道的一个自动化的方式就是 k8s 的滚动更新。

大家实际生产中,应该不是每个人都有使用 k8s 吧?
像你们 java 、go 这些语言,发布新版本的时候,如果不用 k8s ,你们是怎么实现平滑更新过度的,还是直接暴力重启?
5441 次点击
所在节点    程序员
59 条回复
brader
2023-03-10 16:10:42 +08:00
@LeegoYih 我想到的比较简单的处理方式也是这样的,但是这个方式手动好操作,要做成自动化,不容易吧?
LeegoYih
2023-03-10 16:13:19 +08:00
@brader 不知道你有没有使用类似 Jenkins 之类的工具,结合这些工具还是挺方便的,手写脚本确实比较麻烦
brader
2023-03-10 16:15:44 +08:00
@LeegoYih Jenkins 我用过,但是它的流水线部署本质上,和你写 shell 或者代码,没有很大区别吧,只是它结合了比较多的插件和功能。 还是要自己实现自动化不中断的流程啊
libook
2023-03-10 16:17:52 +08:00
@brader #20 运维写几个 shell 脚本通常就可以搞定了。有些 CI/CD 工具,比如 jenkins ,也可以看看。
sujin190
2023-03-10 16:21:48 +08:00
之前我们的做法是自己再外面套了层守护进程,有守护进程来打开端口,然后创建子进程继承过去,然后重启的时候守护进程先创建新的进程,然后给旧的进程发送停止信号,旧进程会先关闭监听端口,然后等待所有请求处理完后慢慢退出,这样就可以实现完全平滑无异常重启更新了,这个好处是和 nginx 负责均衡啥的都不相干,应用自己就能完成,相对简单

不过很可惜像 supervisor 啥都不支持这个功能,其实 supervisor 完全可以打开端口后放在固定 fd 上,比如 3 ,或者可以通过参数传递 fd 的值,然后启动子进程后,子进程直接通过 fd 创建 socket 就好了
brader
2023-03-10 16:23:54 +08:00
@sujin190 这种方案就相当于项目代码自实现的 reload 效果了吧,麻烦点就是每个项目都要自己实现这样一个功能
Alliot
2023-03-10 16:31:23 +08:00
Nginx upstream + healthcheck

假设 有 a b 2 个节点,发布时先将 A 置为 unhealth 状态,流量全部调度到 b 发布完成后置为 health ,同理发布 b 即可。
sujin190
2023-03-10 16:33:35 +08:00
@brader 对,不是啥大服务,单节点又没注册中心啥的,网关负载均衡啥的也不在本机,流量不高不低,想随时随意可以重启没啥异常,搞啥都感觉费劲。。
getoffworkontime
2023-03-10 16:37:14 +08:00
摘除旧服务的时候, 怎么保证旧服务中的任务已经执行完?
vincent7245
2023-03-10 16:43:36 +08:00
服务器是分布式的,滚动升级
brader
2023-03-10 16:44:52 +08:00
@Alliot 我手动操作也是采用类似这样的方案,就是自动化好像不好实现
anonymous2351d00
2023-03-10 17:01:45 +08:00
做一个 流量转发的中间层 成为 A ,你的服务 v1 版本称为 B1
假如 A -> B1 现在要发 B2 版本
保证 A -> B1 的流量控制 部署 B2 ,流量情况 nil -> B2
部署 B2
以非常非常快速的手速,光一样的敲动命令来 调整流量转发层 A -> B2
此时 nil -> B1
这个版本就好了
malusama
2023-03-10 17:12:48 +08:00
@getoffworkontime 优雅退出
awanganddong
2023-03-10 17:33:03 +08:00
这个问题我昨天还在思考。
比如我们公司用的腾讯云的 lbs

首先第一步发送 curl ,将 clb 中配置的后端服务的权重置为 0 ,这时候不存在新增请求,只存在存量请求。这个过程中服务器 clb 还可以转发响应。

接下来就开始关闭 go 进程,这时候 go 代码可以配置优雅退出。等原来 go 进程退出后,就开始启用新的 go 进程。
cyningxu
2023-03-10 17:45:17 +08:00
多实例+注册中心?
ccagml
2023-03-10 19:07:08 +08:00
好奇,如果是类似数据库表结构变了,可以这样滚动更新吗
pengtdyd
2023-03-10 19:27:27 +08:00
半夜 3 点钟,断线 30 分钟没什么大不了,影响不了啥业务,不要把公司的业务想的那么重要,就像你穿了一件新衣服走在大街上,你以为别人都是注视你,其实别人压根不关心你穿的啥,别把自己想的太重要。
brader
2023-03-10 20:54:13 +08:00
@ccagml 你说的这个问题,和实现平滑更新没很大关系。你这个问题,更多的应该在代码层面实现,做一下版本控制,我这几年一直是这么干的,没遇到啥问题
samun
2023-03-10 20:59:17 +08:00
@lincanbin 如果有耗时比较耗时的操作在跑呢 下线了也得等一段时间才能关
dnsjia
2023-03-10 21:04:18 +08:00

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/922911

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX