让我们给http服务写一个版本更新接口,让它自动更新版本并重启服务吧。

初步例子

  注:为了精简,文中代码都去除了err处理  

main.go

var Version = "1.0"

/* 打印版本 */
func version(w http.ResponseWriter, r *http.Request) {
msg := fmt.Sprintf("version %v\n", Version)
w.Write([]byte(msg))
} /* 版本升级 */
func upgrade(w http.ResponseWriter, r *http.Request) {
// 1. 把新版本文件放置到服务主目录(简化)
os.Remove("test_restart")
os.Rename("new_test_restart", "test_restart") // 2. go的可执行文件加权限(省略) // 3. 重启服务
cmd := exec.Command("/bin/bash", "-c", "./restart.sh")
cmd.Output() w.Write([]byte("restart ok\n"))
} func main() {
// 记录pid
f,_ := os.Create("s.pid")
pid := os.Getpid()
f.WriteString(fmt.Sprintf("%v", pid))
fmt.Printf("System running:%v\n", pid) // 监听连接
mux := http.NewServeMux()
mux.HandleFunc("/version", version)
mux.HandleFunc("/upgrade", upgrade)
http.ListenAndServe("127.0.0.1:9527", mux)
}

restart.sh(重启脚本)

kill -9 $(cat s.pid)
nohup ./test_restart > nohup.log 2>&1 &

 测试

1. 编译后开始运行

2. 请求一下版本信息接口

3. 将代码中Version改为“1.1”, 生成一个新文件“new_test_restart”

4. 请求版本更新接口

发现问题

重启脚本是stop后start的,stop时直接杀死了进程,程序直接中断了当前所有的连接,此时接口函数还未return,导致调用方接收不到响应。

使用Endless

看来得不中断已有连接的情况下进行重启才行,不能简单的stop后start,得平滑重启。大致就是让父进程启动一个子进程去监听新的连接,自己不再监听新的连接,而是在处理完已有连接后终止,之后子进程独挑大梁。

随后发现github上的endless挺满足需求,它是一个不停机重启的服务器实现,实现流程为:

  1. 监听 SIGHUP 信号
  2. 收到信号后 fork 子进程(使用相同的启动命令),将服务监听的 socket 文件描述符传递给子进程
  3. 子进程启动成功后开始监听新的连接,并发送 SIGTERM 信号给父进程
  4. 父进程收到 SIGTERM 信号后停止接收新的连接,等待旧连接处理完成后终止
  5. 父进程终止,重启完成

关于 SIGHUP 信号,我们可以用“kill -1”命令发送给endless。

使用endless改动很小,在main函数中只需要把 http.ListenAndServe 修改为 endless.ListenAndServe即可:

main.go

func main() {
// 记录pid(省略) // 监听连接
mux := http.NewServeMux()
mux.HandleFunc("/version", version)
mux.HandleFunc("/upgrade", upgrade)
// http.ListenAndServe("127.0.0.1:9527", mux)
endless.ListenAndServe("127.0.0.1:9527", mux)
}

restart.sh

kill -1 $(cat s.pid)

再测试

1. 编译后开始运行(带时间前缀的是endless打印的日志)

2. 请求一下版本信息接口

3. 将代码中Version改为“1.1”, 生成一个新文件“new_test_restart”

4. 请求版本更新接口

请求没有被中断,成功接收了响应。

endless的日志比较清晰,77625的父进程接收 SIGHUP 后,fork了子进程77625,接收到子进程传递的 SIGHUP 后,等待已有连接处理完成后终止,完全符合上述介绍的流程。

5. 验证版本

至此不停机版本更新成功 ٩(◕‿◕。)۶

go程序不停机重启的更多相关文章

  1. endless 如何实现不停机重启 Go 程序?

    转载请声明出处哦~,本篇文章发布于luozhiyun的博客:https://www.luozhiyun.com/archives/584 前几篇文章讲解了如何实现一个高效的 HTTP 服务,这次我们来 ...

  2. linux 程序失败自动重启

    最近写了一个spark streaming 程序,但是程序跑着跑着就报错了,而且不会自动重启,以下脚本实现了程序失败自动重启 基本原理:查看程序日志文件是否有ERROR或Exception字样,有说明 ...

  3. C#程序注销、重启、关机和锁定电脑

    一:截图 二:源代码 using System; using System.Collections.Generic; using System.Linq; using System.Text; usi ...

  4. android程序崩溃后重启

    有时候由于测试不充分或者程序潜在的问题而导致程序异常崩溃,这个是令人无法接受的,在android中怎样捕获程序的异常崩溃,然后进行一些必要的处理或重新启动 应用这个问题困恼了我很久,今天终于解决了该问 ...

  5. 任务计划程序-Windows2008定时重启

    参考网站:https://www.cnblogs.com/yeyun/p/6209540.html Windows系统的任务计划程序,可以添加计划任务,设置任务开始时间及执行的间隔,实现应用的自动执行 ...

  6. 解决Android后台清理APP后,程序自动重启的问题

    最近解决了一个Android APP的bug,发现APP在被后台清理后,会自动重启.现象很奇怪,有的手机(HTC)后台清理后,程序会再次重启,而有的手机(小米)则不会.猜想可能是小米手机内部做了处理, ...

  7. java:如何让程序按要求自行重启?

    正文开始前的废话: 这里的程序即包括b/s的web application,也包括standalone的类c/s的java application.   为什么要自我重启?   场景1:分布式环境中, ...

  8. Qt之重启应用程序

    简介 今天分享的内容有些意思-如何重启一个应用程序.其实,有时候这是一个很重要的功能点,而且很人性化.易用性很好. 例如:切换用户.当某个用户登录成功之后,需要切换到其它账号,那么这时,你就知道它的重 ...

  9. 【Qt】Qt之重启应用程序【转】

    简介 今天分享的内容有些意思-如何重启一个应用程序.其实,有时候这是一个很重要的功能点,而且很人性化.易用性很好. 例如:切换用户.当某个用户登录成功之后,需要切换到其它账号,那么这时,你就知道它的重 ...

随机推荐

  1. 5-基本的sql查询以及函数的使用

    基本SQL查询语句以及函数的使用 格式元素 描述 YYYY 四位的年份 MONTH 月份的英文全称 MON 月份的英文简写 MM 月份的数字表示 DD 日起的1-31数字表示 D 星期几的数字表示1- ...

  2. mysql创建用户及赋予某用户权限(附带基础查看表内容)

    首先登陆mysql 一:show databases;  展示所有数据库(root用户下) 二:use xxx (数据库名)使用use选择数据库 三:show xxx   查看数据库中的表 四:des ...

  3. 题解 Hero meet devil

    题目传送门 题目大意 给出一个长度为 \(n\) 的字符串,对于每个 \(k\in [0,n]\),求出有多少个长度为 \(m\) 的字符串满足两者最长公共子序列长度为 \(k\). \(n\le 1 ...

  4. Poetry(1)Poetry介绍与安装

    介绍 Poetry 是Python 中的依赖管理和打包工具,当然它也可以配置虚拟环境.它允许您声明项目所依赖的库,并为您管理(安装/更新)它们. 之前一直使用virtualenvwrapper管理虚拟 ...

  5. UML图 | 时序图(顺序、序列图)绘制

    上一次写过一篇 UML | 类图 相关的文章,平时规范开发会用的上,或者是写什么文档,就还是需要画图,就像毕业设计就是如此.希望能够帮助到大家. 注:本文中所用画图软件为 Microsoft Visi ...

  6. 第六次Scrum Metting

    日期:2021年5月3日 会议主要内容概述:讨论前后端进度,前端各模块对接以及前后端对接. 一.进度情况 组员 负责 两日内已完成的工作 后两日计划完成的工作 工作中遇到的困难 徐宇龙 后端 数据模块 ...

  7. [no code][scrum meeting] Beta 7

    $( "#cnblogs_post_body" ).catalog() 例会时间:5月21日15:30,主持者:彭毛小民 下次例会时间:5月22日15:30,主持者:赵涛 昨日为5 ...

  8. windows下wchar_t的问题

    使用vs新建工程或者编译工程的时候默认在编译设置里面讲wchar_t设置为内置类型,如下图: 但是在编译相互依赖的工程的时候,如果有的工程不将wchar_t设置为内置类型的时候,将会出现链接错误,需要 ...

  9. 鸿蒙轻内核M核的故障管家:Fault异常处理

    摘要:本文先简单介绍下Fault异常类型,向量表及其代码,异常处理C语言程序,然后详细分析下异常处理汇编函数实现代码. 本文分享自华为云社区<鸿蒙轻内核M核源码分析系列十八 Fault异常处理& ...

  10. Spring Security:Servlet 过滤器(三)

    3)Servlet 过滤器 Spring Security 过滤器链是一个非常复杂且灵活的引擎.Spring Security 的 Servlet 支持基于 Servlet 过滤器,因此通常首先了解过 ...