Golang Go语言中热更新的简单可行的解决方案
Golang Go语言中热更新的简单可行的解决方案
现在项目队列消费者打算用 go 来重构。
现在问下 go 实现热更新的方式
初期暂时不考虑 k8s 那套,有什么其他比较好的办法吗
就是类似 nginx 热更新那样,起新的 work 进程来接替旧的 work 进程
更多关于Golang Go语言中热更新的简单可行的解决方案的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
热更新,运行中的线程 栈幁怎么处理?
用新的二进制代码处理?新的二进制的代码能兼容老的栈幁结构?
具体技术原理有什么介绍吗
#1 看了…一下 nginx 用的是操作系统的提供进程信号 机制… 那这跟 k8s 流量切换本质上没什么区别…
nginx 是无状态的,但是应用程序可能是有状态的,fork 新程接管流量之后退出的方案是有的,比如 https://github.com/fvbock/endless
如果想实现程序不停机维护,最简单的方法其实是双实例+负载均衡。不在代码层面做这个事了。
进程中的数据应该没法保留。毕竟底层没有个 VM 在运行。只能是交给第三方或者做个集群什么的。
如果 socket 也要传递给新进程,可以参考 https://mosn.io/docs/concept/smooth-upgrade/ 通过 UNIX Domain Socket 传 fd 。
另外还有个管理器可以参考,会下载新包重启的 https://github.com/jpillora/overseer 。
README 里有个连接讲原理. 其实就是 nginx 那套, spawn 一个新的子进程加载 elf binary, 复制 fd, 接管新流量, 老的进程会等待一个 graceful timeout 的时间把已接收的请求处理完, 你是消息队列消费者的话就要确保 task 能在这个时间内被处理完否则会被强制 kill. 和 k8s 还是有区别的, k8s 是在 kube-proxy 那层完成的流量切换, 没这么 tricky, 功能更强(可以实现红绿部署).
你说兼容栈帧那套单进程内热更新我很确定 go 是没有的,这个需要语言 runtime 支持, 印象里只有 erlang 支持, 而且限制性很大, 好处也就是能保留内存缓存.
印象中 go 好像没办法实现守护进程的
以前尝试过用代码完成热更新( API server ),但因为用 docker 运行会遇到了解决不了的问题而放弃。
前面加个 nginx
为什么非要热更新 不中断服务无缝更新不行吗? nginx -> 2 个 upstream 先更新 1 更新完再更新 2 不是美滋滋?
endless 挺好的,需要写个脚本找一下旧的进程,然后 kill -SIGHUP endless 会根据 kill 信号 fork 进程
现在都只用 air 了,发现文件变动自动重启,比热更新方便些
mosn 里面有个通过 Unix socket,传递 accept fd 的骚操作
bee 了解一下
这个方案应该更适合我们的业务
应该是我理解有偏差了,直接用 nginx 切业务就可以了。
谢谢大家了
在Golang(Go语言)中,实现热更新(Hot Reload)意味着能够在不重启程序的情况下,对程序中的代码进行修改并使其立即生效。以下是一些简单且可行的热更新解决方案:
-
使用第三方库:
- fresh:一个Go语言工具,可以监控代码文件的变化,并在检测到变化时自动重新构建和重启应用程序。
- gin:一个高性能的Go语言Web框架,自带热更新功能。
- facebookgo/grace:一个用于实现优雅重启的库,但同样可以用于热更新。
- fvbock/endless:一个用于实现无限循环的库,也可以用于热更新。
-
使用插件机制:
Go语言支持插件机制,可以将一些功能封装成插件,并在运行时动态加载和更新。这需要将需要热更新的功能封装成插件,并编译成.so文件,然后在主程序中动态加载插件并调用其功能。
-
利用文件监控:
通过监控代码文件的变化,当文件被修改时,重新编译并运行应用程序。这可以使用fsnotify库来实现。
-
使用dlv调试器:
dlv(Delve)是一个强大的Go语言调试器,支持热更新功能。可以在调试过程中修改代码并保存,dlv会自动检测到代码的变化并重新加载程序。
需要注意的是,热更新可能会引入一些复杂性和潜在的问题,如内存泄漏、状态不一致等。因此,在生产环境中使用热更新时,务必谨慎,并确保充分测试。