Golang | Web开发之Gin多服务配置及优雅关闭平滑重启

这篇具有很好参考价值的文章主要介绍了Golang | Web开发之Gin多服务配置及优雅关闭平滑重启。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

欢迎关注「全栈工程师修炼指南」公众号

点击 👇 下方卡片 即可关注我哟!

设为星标⭐每天带你 基础入门 到 进阶实践 再到 放弃学习

专注 企业运维实践、网络安全、系统运维、应用开发、物联网实战、全栈文章 等知识分享

  花开堪折直须折,莫待无花空折枝 


作者主页:[ https://www.weiyigeek.top ]  

博客:[ https://blog.weiyigeek.top ]

作者<安全开发运维>学习交流群,回复【学习交流群】即可加入


文章目录:

0x00 如何自定义Gin服务配置及其启动多个服务?

0x01 如何优雅的关闭或者重启Gin应用程序?

1.使用 chan 通道监听中断信号(SIGINT和SIGTERM)

2.使用 os/exec 包来执行Gin平滑重启

3.使用 fvbock/endless 包实现访问指定路由平滑重启Gin服务

0x00 如何自定义Gin服务配置及其启动多个服务?

描述: 在Gin的生产环境中通常会自定义HTTP配置以达到最优性能,此处我们简单一下 Server 结构体中可配置的参数项。

// A Server defines parameters for running an HTTP server.
// The zero value for Server is a valid configuration.
type Server struct {
  // 配置监听地址:端口,默认是:8080
	Addr string
  // 要调用的处理程序,http.DefaultServeMux如果为nil
	Handler Handler
  // 如果为true,则将“OPTIONS*”请求传递给Handler 
	DisableGeneralOptionsHandler bool
  // 提供TLS配置
	TLSConfig *tls.Config
  //读取整个请求(包括正文)的最长持续时间。
	ReadTimeout time.Duration
  // 读取整请求(Header)的最长持续时间。
	ReadHeaderTimeout time.Duration
  // 超时写入响应之前的最长持续时间
	WriteTimeout time.Duration
  // 启用保持活动时等待下一个请求的最长时间
	IdleTimeout time.Duration
  // 控制服务器解析请求标头的键和值(包括请求行)时读取的最大字节数 (通常情况下不进行设置) 
	MaxHeaderBytes int
  // 在发生ALPN协议升级时接管所提供TLS连接的所有权。
	TLSNextProto map[string]func(*Server, *tls.Conn, Handler)
  // 指定了一个可选的回调函数,当客户端连接更改状态时调用该函数
	ConnState func(net.Conn, ConnState)
  // 为接受连接的错误、处理程序的意外行为以及潜在的FileSystem错误指定了一个可选的记录器
  ErrorLog *log.Logger
  // 返回/此服务器上传入请求的基本上下文
	BaseContext func(net.Listener) context.Context
  // 指定一个函数来修改用于新连接c的上下
	ConnContext func(ctx context.Context, c net.Conn) context.Context
  // 当服务器处于关闭状态时为true
	inShutdown atomic.Bool
	disableKeepAlives atomic.Bool
	nextProtoOnce     sync.Once // guards setupHTTP2_* init
	nextProtoErr      error     // result of http2.ConfigureServer if used
	mu         sync.Mutex
	listeners  map[*net.Listener]struct{}
	activeConn map[*conn]struct{}
	onShutdown []func()
	listenerGroup sync.WaitGroup
}

模块更新

go get -u golang.org/x/sync/errgroup
go mod tidy

示例代码:

package main

import (
	"log"
	"net/http"
	"time"

	"github.com/gin-gonic/gin"
	"golang.org/x/sync/errgroup"
)

// 处理属于同一总体任务的子任务的goroutine的集合
var (
	g errgroup.Group
)

// s2 Gin 服务的 Handler
func router02() http.Handler {
	e := gin.New()
	e.Use(gin.Recovery())
	e.GET("/", func(c *gin.Context) {
		c.JSON(
			http.StatusOK,
			gin.H{
				"code": http.StatusOK,
				"msg":  "Welcome server 02 blog.weiyigeek.top",
			},
		)
	})
	return e
}

func main() {
	// Default返回一个Engine实例,该实例已连接Logger和Recovery中间件。
	router := gin.Default()

	// Gin 服务s1.用于运行HTTP服务器的参数 (常规参数)
	s1 := &http.Server{
		// Gin运行的监听端口
		Addr: ":8080",
		// 要调用的处理程序,http.DefaultServeMux如果为nil
		Handler: router,
		// ReadTimeout是读取整个请求(包括正文)的最长持续时间。
		ReadTimeout: 5 * time.Second,
		// WriteTimeout是超时写入响应之前的最长持续时间
		WriteTimeout: 10 * time.Second,
		// MaxHeaderBytes控制服务器解析请求标头的键和值(包括请求行)时读取的最大字节数 (通常情况下不进行设置)
		MaxHeaderBytes: 1 << 20,
	}

	// Go在一个新的goroutine中调用给定的函数,此处将Go语言的并发体现的淋漓尽致。
	g.Go(func() error {
		return s1.ListenAndServe()
	})

	// 配置Gin中间件
	// Recovery返回一个中间件,该中间件可以从任何exception中恢复,并在出现exception时写入500。
	router.Use(gin.Recovery())

	// 服务s1的路由
	router.GET("/", func(c *gin.Context) {
		c.JSON(
			http.StatusOK,
			gin.H{
				"code": http.StatusOK,
				"msg":  "Welcome server 01 www.weiyigeek.top",
			},
		)
	})

	// Gin 服务s1.定义了不同的监听端口以及Handler
	s2 := &http.Server{
		Addr:         ":8081",
		Handler:      router02(),
		ReadTimeout:  5 * time.Second,
		WriteTimeout: 10 * time.Second,
	}
	g.Go(func() error {
		return s2.ListenAndServe()
	})

	if err := g.Wait(); err != nil {
		log.Fatal(err)
	}
}

偷偷的告诉你哟?极客全栈修炼】微信小程序已经上线了,

可直接在微信里面直接浏览博主博客了哟,后续将上线更多有趣的小工具。


执行结果:

Golang | Web开发之Gin多服务配置及优雅关闭平滑重启


0x01 如何优雅的关闭或者重启Gin应用程序?

1.使用 chan 通道监听中断信号(SIGINT和SIGTERM)

描述: 在Go Gin中,可以使用以下代码实现优雅地重启或停止, 确保所有连接都被正确关闭,避免数据丢失或损坏。

代码示例:

package main

import (
	"context"
	"log"
	"net/http"
	"os"
	"os/signal"
	"syscall"
	"time"

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

func main() {
	// 创建 Gin 实例
	router := gin.Default()

	// 添加路由
	router.GET("/", func(c *gin.Context) {
		c.String(http.StatusOK, "Hello, World! weiyigeek.top")
	})

	// 创建 HTTP Server
	srv := &http.Server{
		Addr:    ":8080",
		Handler: router,
	}

  // 开启一个goroutine启动服务 启动 HTTP Server
	go func() {
		if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
			log.Fatalf("listen: %s\n", err)
		}
	}()

	// 等待中断信号
	quit := make(chan os.Signal)
	// kill 默认会发送 syscall.SIGTERM 信号
	// kill -2 发送 syscall.SIGINT 信号,我们常用的Ctrl+C就是触发系统SIGINT信号
	// kill -9 发送 syscall.SIGKILL 信号,但是不能被捕获,所以不需要添加它
	// signal.Notify把收到的 syscall.SIGINT或syscall.SIGTERM 信号转发给quit
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) // 此处不会阻塞
	<-quit    // 阻塞在此,当接收到上述两种信号时才会往下执行
	log.Println("Shutdown Server ...")

	// 创建一个 5 秒的超时上下文
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	// 关闭 HTTP Server
  // 	// 5秒内优雅关闭服务(将未处理完的请求处理完再关闭服务),超过5秒就超时退出
	if err := srv.Shutdown(ctx); err != nil {
		log.Fatal("Server Shutdown:", err)
	}
	log.Println("Server exiting")
}

代码解析:
首先创建了一个Gin实例和一个HTTP Server,然后启动HTTP Server。接下来,使用signal.Notify()函数监听中断信号(SIGINT和SIGTERM),当接收到中断信号时,服务器会进入优雅关闭流程,即先关闭HTTP Server,然后等待5秒钟,最后退出程序。

在关闭HTTP Server时,我们使用了srv.Shutdown()函数,它会优雅地关闭HTTP Server并等待所有连接关闭。如果在5秒钟内没有关闭完所有连接,函数会返回错误。

知识补充: 使用os/signal包实现对信号的处理, 最常见的信号列表。

Golang | Web开发之Gin多服务配置及优雅关闭平滑重启

2.使用 os/exec 包来执行Gin平滑重启

描述: 在Linux的Go-gin环境中我们可以使用 os/exec 包来执行重启命令,然后在 Gin 中定义一个路由,使得访问该路由时会执行重启命令。

代码示例:

package main

import (
  "fmt"
  "net/http"
  "os"
  "os/exec"

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

func main() {
  r := gin.Default()
  // 重启的路由 /restart
  r.GET("/restart", func(c *gin.Context) {
    cmd := exec.Command("killall", "-HUP", "appweiyigeek")
    err := cmd.Run()
    if err != nil {
      fmt.Println("Error executing restart command:", err)
      c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to restart Gin server."})
      return
    }
    c.JSON(http.StatusOK, gin.H{"message": "Gin server restarted successfully."})
  })

  r.Run(":8080")
}

编译执行:

go build ./main.go -o appweiyigeek
./appweiyigeek

在上面的例子中,我们定义了一个路由 /restart,当访问该路由时,它会执行 killall -HUP appweiyigeek 命令来重启 Gin 服务, 这里的appweiyigeek应该替换为你实际的 Gin 应用程序的名称。

温馨提示: 此种重启方式可能会导致请求失败或者超时,因为它会强制关闭正在处理的连接, 如果你需要更加优雅的重启方式,可以考虑使用优雅重启的方式。

3.使用 fvbock/endless 包实现访问指定路由平滑重启Gin服务

描述: 由于endless在windows环境是不支持,所以博主针对下述代码在Linux环境下载并编译成二进制文件打包到Linux环境运行进行验证。

依赖下载:

go get -u github.com/fvbock/endless
go mod tidy

代码示例:

package main

import (
	"fmt"
	"log"
	"net/http"
	"os/exec"
	"strconv"
	"syscall"

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

func main() {
	pid := syscall.Getpid()

	// 1.默认的Gin引擎
	router := gin.Default()

	// 传统方式
	// server := &http.Server{
	// 	Addr:         ":8080",
	// 	Handler:      router,
	// 	ReadTimeout:  5 * time.Second,
	// 	WriteTimeout: 10 * time.Second,
	// }

	// 2.获取 Pid
	router.GET("/pid", func(c *gin.Context) {
		pid = syscall.Getpid()
		fmt.Println("Pid:", pid)
		c.JSON(http.StatusOK,
			gin.H{
				"code": http.StatusOK,
				"msg":  fmt.Sprintf("Gin Server Pid ->  %d.", pid),
			})
	})

	// 3.重启 Gin 服务
	router.POST("/restart", func(c *gin.Context) {
		pid = syscall.Getpid()
		fmt.Println("Restarting Gin Server.......", pid)
		err := exec.Command("kill", "-1", strconv.Itoa(pid)).Run()
		if err != nil {
			fmt.Println("Error executing restart command:", err)
			c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to restart Gin server."})
			return
		}
		c.JSON(http.StatusOK, gin.H{"message": "Gin server restarted successfully.", "pid": pid})
	})

	// 4.使用endless侦听TCP网络地址addr,然后使用处理程序调用Serve来处理传入连接上的请求
	err := endless.ListenAndServe(":8080", router)
	if err != nil || err != http.ErrServerClosed {
		log.Println("err:", err)
	}

	// 5.引入了endless扩展,将原本的Run方式启动项目改成了ListenAndServe方式所有此处主席掉
	// router.Run(":8080")
}

编译构建:

# 切换编译在Linux平台的64位可执行程序环境
go env -w CGO_ENABLED=0 GOOS=linux GOARCH=amd64

# 编译
go build -o endless-test-1 .\main.go

# 执行验证
chmod +x endless-test-1
nohup ./endless-test-1 &
[1] 1147978

Golang | Web开发之Gin多服务配置及优雅关闭平滑重启

执行效果:

# GET 请求 10.20.176.101:8080/pid
# POST 请求 10.20.176.101:8080/restart

Golang | Web开发之Gin多服务配置及优雅关闭平滑重启

请求restart后可以看见go-gin已经平滑重启了是不是很方便,效果如下。

Golang | Web开发之Gin多服务配置及优雅关闭平滑重启

亲,文章就要看完了,不关注一下【全栈工程师修炼指南】吗?

知识扩展:

  • 3、Windows下编译Mac, Linux平台的64位可执行程序:

$ go env -w CGO_ENABLED=0 GOOS=darwin3 GOARCH=amd64 
$ go env -w CGO_ENABLED=0 GOOS=linux GOARCH=amd64
  • 2、Linux下编译Mac, Windows平台的64位可执行程序:

$ go env -w CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 
$ go env -w CGO_ENABLED=0 GOOS=windows GOARCH=amd64
  • 1、Mac下编译Linux, Windows平台的64位可执行程序:

$ go env -w CGO_ENABLED=0 GOOS=linux GOARCH=amd64
$ go env -w CGO_ENABLED=0 GOOS=windows GOARCH=amd64

本文至此完毕,更多技术文章,尽情等待下篇好文!

原文地址: https://blog.weiyigeek.top/2023/6-2-745.html

如果此篇文章对你有帮助,请你将它分享给更多的人! 

Golang | Web开发之Gin多服务配置及优雅关闭平滑重启

Golang | Web开发之Gin多服务配置及优雅关闭平滑重启 学习书籍推荐 往期发布文章 Golang | Web开发之Gin多服务配置及优雅关闭平滑重启

公众号回复【0008】获取【Ubuntu22.04安装与加固脚本】

公众号回复【10001】获取【WinServer安全加固脚本】

公众号回复【10002】获取【KylinOS银河麒麟安全加固脚本】

公众号回复【0011】获取【k8S二进制安装部署教程】

公众号回复【0014】获取【Nginx学习之路汇总】

公众号回复【0015】获取【Jenkins学习之路汇总】

公众号回复【10005】获取【adb工具刷抖音赚米】

 热文推荐  

  • Golang | Web开发之Gin框架快速入门基础实践

  • Go开发学习 | 如何快速读取json/yaml/ini等格式的配置文件使用示例

  • Go开发学习 | 如何使用Gomail.v2模块包发送邮箱验证码消息及附件学习记录

  • Go开发学习 | 如何使用日志记录模块包针对日志按天数、按大小分隔文件示例

  • 开发基础 | Golang语言的RESTfulAPI接口设计规范快速入门

欢迎长按(扫描)二维码 取更多渠道哟!

欢迎关注 【全栈工程师修炼指南】(^U^)ノ~YO

添加作者微信【weiyigeeker 】 一起学习交流吧!

关注回复【学习交流群】即可加入【安全运维沟通交流小群

温馨提示: 由于作者水平有限,本章错漏缺点在所难免,希望读者批评指正,若有问题或建议请在文章末尾留下您宝贵的经验知识,或联系邮箱地址

master@weiyigeek.top 或 关注公众号 [全栈工程师修炼指南] 留言。

点个【赞 + 在看】吧!

点击【"阅读原文"】获取更多有趣的知识!   文章来源地址https://www.toymoban.com/news/detail-481061.html

到了这里,关于Golang | Web开发之Gin多服务配置及优雅关闭平滑重启的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Web服务器配置与管理

    个人主页:熬夜磕代码丶 作品专栏: java se 我变秃了,也变强了 给大家介绍一款程序员必备刷题平台——牛客网 点击注册一起刷题收获大厂offer吧 本次Web服务器配置与管理是基于计算器网络课程设计,大部分都是刚学完计算机网络,对Web服务器了解甚少,所以今天推出一期小

    2024年02月02日
    浏览(47)
  • 如何在Packet Tracer配置Web服务和DNS服务

    在说配置服务之前,我先介绍介绍这个Packet Tracer吧,Packet Tracer是Cisco(思科)公司针对其CCNA认证开发的一个可视化的交互式教学工具,它可以用来模拟设计网络、搭建各种复杂的网络应用环境、配置网络设备和排除网络故障。 说完用途了,然后我们来看看他的工作界面,大

    2024年02月08日
    浏览(36)
  • VPN服务器配置、路由服务器配置、视频服务器配置、DNS服务器配置、DHCP服务器配置、E-mail服务器配置、FTP服务器配置、Web服务器配置、证书服务器配置及管理

    期末考核学习笔记记录 本文主要记录了VPN、路由服务、视频服务器、DNS服务器、DHCP服务器、E-mail服务器、FTP服务器、Web服务器、证书服务器的简单配置与管理。此为作者期末考核作业,配置过程粗糙不严谨之处还望包涵。 一、 实验目的 1、 掌握VPN服务的安装与配置 2、 熟悉

    2024年02月08日
    浏览(69)
  • Linux的Web服务器配置

    准备工作: 1.准备两台虚拟机(CentOS):一台作为服务器,一台作为客户机(选择仅主机模式进行连接) 2.检查是否安装好了httpd:rpm -q httpd 3.如果没有安装好,安装步骤: ①.cd /run/media/root/CentOS 7 x86_64/Packages (使用自动补全) ②.查看目录下的文件 ls | grep httpd 选择第一个下

    2024年02月05日
    浏览(40)
  • WEB服务器配置与HTTP分析

    目录 实验目的: 实验要求: 实验原理: 实验步骤: 步骤1:创建拓扑 步骤2:为PC、Client和Server配置IPv4地址、子网掩码和域名服务器 步骤3:启动设备和服务器 步骤4:测试PC-1、Client-1和Server-1之间的通信 步骤5:在Server-1上配置并启动DNS服务器  步骤6:在Server-1上配置并启动

    2024年01月17日
    浏览(53)
  • 使用CentOS 7配置Web服务-第二篇

    接上一个实验dhcp实验已经配置好ip了 这个实验我们来在CentOS 7配置Web服务 1、创建一台虚拟主机网站,满足以下功能: 1)网站页面存放路径为学生用户家目录。 2)网站访问端口为8080 3)可通过ip地址192.168.1.学号访问 4)可通过域名访问,域名为学生姓名。例如www.zhangsan.com

    2024年02月11日
    浏览(38)
  • 实验六 WEB FTP服务器配置

    实验六 WEB FTP服务器配置    一、实验目的 理解IIS服务的基本概念; 掌握在Windows 2003 server 上安装WEB服务器的方法; 掌握WEB服务器的配置方法; 掌握在客户端访问WEB服务器的方法。 理解FTP的基本概念与工作原理; 安装FTP服务器方法; 配置与管理FTP服务器的方法; 客户端访

    2024年02月09日
    浏览(40)
  • 如何在虚拟专用服务器上配置 Nginx Web 服务器

    本文档涵盖的是不再受支持的 Ubuntu 版本。如果您目前正在运行 Ubuntu 12.04 服务器,我们强烈建议升级或迁移到受支持的 Ubuntu 版本: 升级到 Ubuntu 14.04 从 Ubuntu 14.04 升级到 Ubuntu 16.04 将服务器数据迁移到受支持的版本 原因: Ubuntu 12.04 已于 2017 年 4 月 28 日到达生命周期终点(

    2024年04月27日
    浏览(41)
  • IIS的安装及web服务器配置

    1.打开“控制面板”,按照“大图标”方式查看,然后选择“程序和功能”。 2. 进入“程序与功能”后,选择“启用或关闭Windows功能”。 3.在“Windows功能”中, 找到“Internet Information Services”部分。 4. 勾选以下部分,这里要注意喽,一定不要少勾呦,缺少一个都有可能不好使

    2024年02月11日
    浏览(78)
  • Web服务器启用HTTPS的配置方法

    本文于2016年3月完成,发布在个人博客网站上。 考虑个人博客因某种原因无法修复,于是在博客园安家,之前发布的文章逐步搬迁过来。 可以参考Jerry Qu的本博客 Nginx 配置之完整篇。 以Java语言实现的Connector为例,介绍配置方法。 Windows下,可以在CMD下执行命令 Unix下,可以在

    2024年02月04日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包