go gin web服务器使用fvbock/endless优雅地重启或停止

gin使用fvbock/endless

gin 正常使用注册路由时:

复制代码
package main

import "github.com/gin-gonic/gin"

func main() {
	r := gin.Default()
	r.GET("/ping", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"message": "pong",
		})
	})
	r.Run() // 监听并在 0.0.0.0:8080 上启动服务
}

使用 fvbock/endless

复制代码
package main

import (
    "github.com/fvbock/endless"
    "github.com/gin-gonic/gin"
)

func main() {
	r := gin.Default()
	r.GET("/ping", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"message": "pong",
		})
	})
    endless.ListenAndServe(":8000", r)   // 注意这一行要使用endless
}

编译

复制代码
$ go build -o endless test.go  
$ ./endless   
[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.

[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
 - using env:   export GIN_MODE=release
 - using code:  gin.SetMode(gin.ReleaseMode)

[GIN-debug] GET    /ping                     --> main.main.func1 (3 handlers)
2024/06/18 20:00:29 83605 :8000
[GIN] 2024/06/18 - 20:02:06 | 200 |      34.249µs |       127.0.0.1 | GET      "/ping"

控制台也有相应的响应:[GIN] 2024/06/18 - 20:02:06 | 200 | 34.249µs | 127.0.0.1 | GET "/ping"

修改源码,重新编译

注意之前的服务不要动,重新开新的窗口

修改源码,重新编译

复制代码
package main

import (
    "github.com/fvbock/endless"
    "github.com/gin-gonic/gin"
)

func main() {
	r := gin.Default()
	r.GET("/ping", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"message": "pong111", // 这行被修改了
		})
	})
    endless.ListenAndServe(":8000", r)   // 注意这一行要使用endless
}

此时新编译的包,会覆盖当前的旧包

复制代码
go build -o endless test.go

查看进程

复制代码
$ ps -ef | grep endless
  501 83605 82947   0  8:00PM ttys004    0:00.02 ./endless

使用kill命令向老进程发送信号,这里是关键

复制代码
kill -1 83605

这时第一个窗口就会有如下输出:

复制代码
[GIN-debug] GET    /ping                     --> main.main.func1 (3 handlers)
2024/06/18 20:09:16 84638 :8000
2024/06/18 20:09:16 83605 Received SIGTERM.
2024/06/18 20:09:16 83605 [::]:8000 Listener closed.
2024/06/18 20:09:16 83605 Waiting for connections to finish...
2024/06/18 20:09:16 83605 Serve() returning...

再次查看进程,发送请求

复制代码
$ ps -ef | grep endless
  501 84638     1   0  8:09PM ttys004    0:00.01 ./endless

endless进程还在,可进程号变了,内容也变了

这里发生了变化,流程如下:

  1. 老的进程收到SIGHUP信号,拒绝新连接请求旧进程,但要保证已有连接正常
  2. 启动了一个新的子进程,端口号还是8000
  3. 新的子进程开始 Acce,系统将新的请求转交新的子进程,老进程不会处理新的连接了,但是会依然处理还没有处理完的老连接,直到所有老的连接都处理完
  4. 旧进程处理完所有旧连接后正常结束,新的进程会处理新的连接,整个服务正常运行

信号

信号是 Unix 、类 Unix 以及其他 POSIX 兼容的操作系统中进程间通讯的一种有限制的方式

它是一种异步的通知机制,用来提醒进程一个事件(硬件异常、程序执行异常、外部发出信号)已经发生。当一个信号发送给一个进程,操作系统中断了进程正常的控制流程。此时,任何非原子操作都将被中断。如果进程定义了信号的处理函数,那么它将被执行,否则就执行默认的处理函数。

复制代码
$ kill -l
 1) SIGHUP	 2) SIGINT	 3) SIGQUIT	 4) SIGILL	 5) SIGTRAP
 6) SIGABRT	 7) SIGBUS	 8) SIGFPE	 9) SIGKILL	10) SIGUSR1
11) SIGSEGV	12) SIGUSR2	13) SIGPIPE	14) SIGALRM	15) SIGTERM
16) SIGSTKFLT	17) SIGCHLD	18) SIGCONT	19) SIGSTOP	20) SIGTSTP
21) SIGTTIN	22) SIGTTOU	23) SIGURG	24) SIGXCPU	25) SIGXFSZ
26) SIGVTALRM	27) SIGPROF	28) SIGWINCH	29) SIGIO	30) SIGPWR
31) SIGSYS	34) SIGRTMIN	35) SIGRTMIN+1	36) SIGRTMIN+2	37) SIGRTMIN+3
38) SIGRTMIN+4	39) SIGRTMIN+5	40) SIGRTMIN+6	41) SIGRTMIN+7	42) SIGRTMIN+8
43) SIGRTMIN+9	44) SIGRTMIN+10	45) SIGRTMIN+11	46) SIGRTMIN+12	47) SIGRTMIN+13
48) SIGRTMIN+14	49) SIGRTMIN+15	50) SIGRTMAX-14	51) SIGRTMAX-13	52) SIGRTMAX-12
53) SIGRTMAX-11	54) SIGRTMAX-10	55) SIGRTMAX-9	56) SIGRTMAX-8	57) SIGRTMAX-7
58) SIGRTMAX-6	59) SIGRTMAX-5	60) SIGRTMAX-4	61) SIGRTMAX-3	62) SIGRTMAX-2
63) SIGRTMAX-1	64) SIGRTMAX

endless server 监听以下几种信号量:

  • syscall.SIGHUP:触发 fork 子进程和重新启动
  • syscall.SIGUSR1/syscall.SIGTSTP:被监听,但不会触发任何动作
  • syscall.SIGUSR2:触发 hammerTime
  • syscall.SIGINT/syscall.SIGTERM:触发服务器关闭(会完成正在运行的请求)

endless 正正是依靠监听这些信号量,完成管控的一系列动作

相关推荐
橙子家8 小时前
浏览器缓存之【身份与会话管理】:Cookies 和 Private state tokens
前端
最新资讯动态9 小时前
HDC 2026 | 对话鲸鸿动能:存量时代,品牌如何夺回营销“主动权”?
前端
最新资讯动态9 小时前
游戏出海,从产品走向体系
前端
最新资讯动态9 小时前
20人团队跑出百万DAU、大厂也来抢量:谁在鸿蒙生态跑出加速度
前端
最新资讯动态10 小时前
千万开发者背后,鸿蒙商业化的B面
前端
爱勇宝11 小时前
AI 时代:智商决定起点,情商决定走多远
前端·ai编程
kyriewen12 小时前
用了半年 Claude Code 后,我尝试关掉它写了一周代码——结果比想象中严重
前端·javascript·ai编程
IT_陈寒12 小时前
Vite的静态资源打包让我熬夜到三点,这坑千万别跳
前端·人工智能·后端
徐小夕13 小时前
万字拆解 JitWord:企业级实时协同文档底层架构 + 大模型 AI 融合完整实践
前端·vue.js·github
一份执念13 小时前
uni-app 小程序分包限制处理与主包体积优化实战
前端·微信小程序