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进程还在,可进程号变了,内容也变了

这里发生了变化,流程如下:
- 老的进程收到SIGHUP信号,拒绝新连接请求旧进程,但要保证已有连接正常
- 启动了一个新的子进程,端口号还是8000
- 新的子进程开始 Acce,系统将新的请求转交新的子进程,老进程不会处理新的连接了,但是会依然处理还没有处理完的老连接,直到所有老的连接都处理完
- 旧进程处理完所有旧连接后正常结束,新的进程会处理新的连接,整个服务正常运行
信号
信号是 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 正正是依靠监听这些信号量,完成管控的一系列动作
go gin web服务器使用fvbock/endless优雅地重启或停止的更多相关文章
- 用go-module作为包管理器搭建go的web服务器
本篇博客主要介绍了如何从零开始,使用Go Module作为依赖管理,基于Gin来一步一步搭建Go的Web服务器.并使用Endless来使服务器平滑重启,使用Swagger来自动生成Api文档. 源码在 ...
- Gin Web框架简单介绍
翻译自: https://github.com/gin-gonic/gin/blob/develop/README.md Gin Web框架 branch=master"> Gin是用 ...
- 嵌入式web服务器
要实现在PC上通过网页控制连接到嵌入式开发板的相机. 限于开发板的环境,不能选择appche等大型web服务器,选择了boa. 要想pc端跨平台,那就不能用ActiveX控件,如果仅在windows平 ...
- linux下通过acl配置灵活目录文件权限(可用于ftp,web服务器的用户权限控制)
linux下通过acl配置灵活目录文件权限(可用于ftp,web服务器的用户权限控制) 发表于2012//07由feng linux 本身的ugo rwx的权限,对于精确的权限控制很是力不从心的,ac ...
- 深入理解Tornado——一个异步web服务器
本人的第一次翻译,转载请注明出处:http://www.cnblogs.com/yiwenshengmei/archive/2011/06/08/understanding_tornado.html原 ...
- 使用 C# 编写简易 ASP.NET Web 服务器
原文 http://www.cnblogs.com/lcomplete/p/use-csharp-write-aspnet-web-server.html 如果你想获得更好的阅读体验,可以前往我在 g ...
- C# 编写简易 ASP.NET Web 服务器
C# 编写简易 ASP.NET Web 服务器 你是否有过这样的需求——想运行 ASP.NET 程序,又不想安装 IIS 或者 Visual Studio?我想如果你经常编写 ASP.NET 程序的话 ...
- 自己模拟的一个简单的web服务器
首先我为大家推荐一本书:How Tomcat Works.这本书讲的很详细的,虽然实际开发中我们并不会自己去写一个tomcat,但是对于了解Tomcat是如何工作的还是很有必要的. Servlet容器 ...
- VS2017 无法连接到Web服务器“IIS Express”终极解决方案
今天日了gou了,一大早打开VS2017的时候出现无法连接到Web服务器"IIS Express"的错误,然后必应了一下,再谷歌了一下找到的解决方法也都千篇一律,奈何都没能解决,最 ...
- Netty入门(三)之web服务器
Netty入门(三)之web服务器 阅读前请参考 Netty入门(一)之webSocket聊天室 Netty入门(二)之PC聊天室 有了前两篇的使用基础,学习本文也很简单!只需要在前两文的基础上稍微改 ...
随机推荐
- Qt数据库应用13-通用数据库分页
一.前言 数据库分页展示,在所有的涉及到数据库记录的项目中都是需要的,除了简单的设备信息表.用户信息表这种很少几条几十条数据量的表除外,其余的日志记录表等都需要分页展示数据,少量的数据可以滚动条下拉查 ...
- Diary & Note - 两个惊喜
我们有单位根反演: \[\sum_{k\mid n}[x^n]f(x)=\frac{1}{k}\sum_{i=0}^{k-1}f(\omega_k^i). \] 我们有 CRT: \[x\equi ...
- React源码解析(1): JSX语法与react项目渲染过程
好家伙 0.前言 由于工作的需要,我不得不入手了react的全家桶,曾经我的主要技术栈是vue. 从vue转到react,一开始我感到非常不适应,jsx的语法的不了解,react hooks的使用 ...
- 前端(一)-Html
1.网页基本信息 <!DOCTYPE html> 浏览器使用的规范 <head> 网页头 <body> 主体部分 <meta> 元数据 meta的nam ...
- 项目PMP之一项目管理介绍
一.项目定义: 概要:为创造独特的产品.服务或成果而进行的临时性工作 组织创造价值和效益.项目驱动变更创造商业价值的主要方式 特性/要素: 独特的产品.服务或成果,即一个或多个可交付成果(范围.进度( ...
- w3cschool-Struts2 概述
Struts2 概述 Struts2 是目前较为普及和成熟的基于MVC设计模式的web应用程序框架,它不仅仅是Struts1 的升级版本,更是一个全新的Struts架构.最初,是以WebWork框架和 ...
- 快速修改MySQL数据库名称
原理:先创建新的数据库,然后利用information_schema数据库表结构信息,用 RENAME命令 将旧的表迁移到新数据库里面,最后删除旧的数据库名称即可. 步骤如下: #查询目标数据库下面的 ...
- Flask: SSO原理及实现
原文链接:http://www.tuicool.com/articles/ZbyU3e 现在大多数软件公司的业务不再是单条线,而是发展成多元化的产品线.包括多个网站应用.移动APP以及桌面软件,那么 ...
- FIDO 密钥登录
FIDO 密匙登录 [1]介绍了一些基础密码知识,科普性较好,在此摘抄一下: 说起密码,你会想起什么? 密码太多,记不住? 图省事所有网站用同一个密码,一个泄露了,手忙脚乱地去改密码? 网站被脱库,数 ...
- redis如何设置密码
密码设置 这里简单介绍一下redis如何设置密码redis密码设置有两种方式,一种需要重启redis服务,一种不需要重启redis服务. 首先,介绍一下需要重启redis服务的设置方式即找到redis ...