百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 热门文章 > 正文

Go Web 框架 Gin 实践7—优雅的重启服务

bigegpt 2024-08-28 12:28 4 浏览

Go语言中文网,致力于每日分享编码知识,欢迎关注我,每天一起进步!

在前面编写案例代码时,我相信你会想到

每次更新完代码,更新完配置文件后 就直接这么 ctrl+c 真的没问题吗,ctrl+c到底做了些什么事情呢?

在这一节中我们简单讲述 ctrl+c 背后的信号以及如何在Gin中优雅的重启服务,也就是对 HTTP 服务进行热更新

项目地址:https://github.com/EDDYCJY/go-gin-example

ctrl + c

内核在某些情况下发送信号,比如在进程往一个已经关闭的管道写数据时会产生SIGPIPE信号

在终端执行特定的组合键可以使系统发送特定的信号给此进程,完成一系列的动作

因此在我们执行ctrl + c关闭gin服务端时,会强制进程结束,导致正在访问的用户等出现问题

常见的 kill -9 pid 会发送 SIGKILL 信号给进程,也是类似的结果

信号

本段中反复出现信号是什么呢?

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

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

所有信号

怎样算优雅

目的

  • 不关闭现有连接(正在运行中的程序)
  • 新的进程启动并替代旧进程
  • 新的进程接管新的连接
  • 连接要随时响应用户的请求,当用户仍在请求旧进程时要保持连接,新用户应请求新进程,不可以出现拒绝请求的情况

流程

1、替换可执行文件或修改配置文件

2、发送信号量 SIGHUP

3、拒绝新连接请求旧进程,但要保证已有连接正常

4、启动新的子进程

5、新的子进程开始 Accet

6、系统将新的请求转交新的子进程

7、旧进程处理完所有旧连接后正常结束

实现优雅重启

endless

Zero downtime restarts for golang HTTP and HTTPS servers. (for golang 1.3+)

我们借助 fvbock/endless 来实现 Golang HTTP/HTTPS 服务重新启动的零停机

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

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

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

安装

go get -u github.com/fvbock/endless

编写

打开 gin-blog 的 main.go文件,修改文件:

endless.NewServer 返回一个初始化的 endlessServer 对象,在 BeforeBegin 时输出当前进程的 pid,调用 ListenAndServe 将实际“启动”服务

验证

编译

$ go build main.go 

执行

$ ./main
[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
...
Actual pid is 48601

启动成功后,输出了pid为 48601;在另外一个终端执行 kill -1 48601 ,检验先前服务的终端效果

可以看到该命令已经挂起,并且 fork 了新的子进程 pid 为 48755

大致意思为主进程(pid为48601)接受到 SIGTERM 信号量,关闭主进程的监听并且等待正在执行的请求完成;这与我们先前的描述一致

唤醒

这时候在 postman 上再次访问我们的接口,你可以惊喜的发现,他“复活”了!

这就完成了一次正向的流转了

你想想,每次更新发布、或者修改配置文件等,只需要给该进程发送SIGTERM信号,而不需要强制结束应用,是多么便捷又安全的事!

问题

endless 热更新是采取创建子进程后,将原进程退出的方式,这点不符合守护进程的要求

http.Server - Shutdown()

如果你的Golang >= 1.8,也可以考虑使用 http.Server 的 Shutdown 方法

小结

在日常的服务中,优雅的重启(热更新)是非常重要的一环。而 Golang 在 HTTP 服务方面的热更新也有不少方案了,我们应该根据实际应用场景挑选最合适的

参考

本系列示例代码

  • go-gin-example

拓展阅读

  • manners
  • graceful
  • grace
  • plugin: new package for loading plugins · golang/go@0cbb12f · GitHub

相关推荐

Go语言泛型-泛型约束与实践(go1.7泛型)

来源:械说在Go语言中,Go泛型-泛型约束与实践部分主要探讨如何定义和使用泛型约束(Constraints),以及如何在实际开发中利用泛型进行更灵活的编程。以下是详细内容:一、什么是泛型约束?**泛型...

golang总结(golang实战教程)

基础部分Go语言有哪些优势?1简单易学:语法简洁,减少了代码的冗余。高效并发:内置强大的goroutine和channel,使并发编程更加高效且易于管理。内存管理:拥有自动垃圾回收机制,减少内...

Go 官宣:新版 Protobuf API(go pro版本)

原文作者:JoeTsai,DamienNeil和HerbieOng原文链接:https://blog.golang.org/a-new-go-api-for-protocol-buffer...

Golang开发的一些注意事项(一)(golang入门项目)

1.channel关闭后读的问题当channel关闭之后再去读取它,虽然不会引发panic,但会直接得到零值,而且ok的值为false。packagemainimport"...

golang 托盘菜单应用及打开系统默认浏览器

之前看到一个应用,用go语言编写,说是某某程序的windows图形化客户端,体验一下发现只是一个托盘,然后托盘菜单的控制面板功能直接打开本地浏览器访问程序启动的webserver网页完成gui相关功...

golang标准库每日一库之 io/ioutil

一、核心函数概览函数作用描述替代方案(Go1.16+)ioutil.ReadFile(filename)一次性读取整个文件内容(返回[]byte)os.ReadFileioutil.WriteFi...

文件类型更改器——GoLang 中的 CLI 工具

我是如何为一项琐碎的工作任务创建一个简单的工具的,你也可以上周我开始玩GoLang,它是一种由Google制作的类C编译语言,非常轻量和快速,事实上它经常在Techempower的基准测...

Go (Golang) 中的 Channels 简介(golang channel长度和容量)

这篇文章重点介绍Channels(通道)在Go中的工作方式,以及如何在代码中使用它们。在Go中,Channels是一种编程结构,它允许我们在代码的不同部分之间移动数据,通常来自不同的goro...

Golang引入泛型:Go将Interface「」替换为“Any”

现在Go将拥有泛型:Go将Interface{}替换为“Any”,这是一个类型别名:typeany=interface{}这会引入了泛型作好准备,实际上,带有泛型的Go1.18Beta...

一文带你看懂Golang最新特性(golang2.0特性)

作者:腾讯PCG代码委员会经过十余年的迭代,Go语言逐渐成为云计算时代主流的编程语言。下到云计算基础设施,上到微服务,越来越多的流行产品使用Go语言编写。可见其影响力已经非常强大。一、Go语言发展历史...

Go 每日一库之 java 转 go 遇到 Apollo?让 agollo 来平滑迁移

以下文章来源于GoOfficialBlog,作者GoOfficialBlogIntroductionagollo是Apollo的Golang客户端Apollo(阿波罗)是携程框架部门研...

Golang使用grpc详解(golang gcc)

gRPC是Google开源的一种高性能、跨语言的远程过程调用(RPC)框架,它使用ProtocolBuffers作为序列化工具,支持多种编程语言,如C++,Java,Python,Go等。gR...

Etcd服务注册与发现封装实现--golang

服务注册register.gopackageregisterimport("fmt""time"etcd3"github.com/cor...

Golang:将日志以Json格式输出到Kafka

在上一篇文章中我实现了一个支持Debug、Info、Error等多个级别的日志库,并将日志写到了磁盘文件中,代码比较简单,适合练手。有兴趣的可以通过这个链接前往:https://github.com/...

如何从 PHP 过渡到 Golang?(php转golang)

我是PHP开发者,转Go两个月了吧,记录一下使用Golang怎么一步步开发新项目。本着有坑填坑,有错改错的宗旨,从零开始,开始学习。因为我司没有专门的Golang大牛,所以我也只能一步步自己去...