当前位置: 首页 > article >正文

go语言gin框架平滑关闭——思悟项目技术2

目录

前言

直接关闭的缺陷

平滑关闭的使用场景

例子


思悟项目:

golang qq邮件发送验证码——思悟项目技术1


前言

平滑关闭(graceful shutdown)是指在停止服务时,能够让现有的连接、任务或者操作优雅地完成,而不是直接中断。

平滑关闭的核心思想是在系统接收到停止信号后,不再接收新请求,只处理当前正在执行的请求,确保所有请求完成后,系统才正式关闭。

直接关闭的缺陷

比如说有一个web服务,我们要升级web服务,也就是版本迭代。但是在升级前,要先把服务关闭。我们可以直接包里终止程序,然后启动新的服务,但是这样做存在缺陷:

  • 当前的请求可能会被中断,导致数据丢失。
  • 未完成的后台任务会被强行中断。(用户体验感也会很差)
  • 数据库连接、文件等资源可能没有机会释放,导致潜在的资源泄漏。

平滑关闭的使用场景

  1. 项目版本迭代
  2. 服务重启维护
  3. 服务迁移
  4. 防止数据丢失

(例如王者荣耀更新时,正在打游戏的玩家不会更新,等到这局游戏结束后才会进行更新。)

例子

package main

import (
	"context"
	"errors"
	"github.com/gin-gonic/gin"
	"log"
	"net/http"
	"os"
	"os/signal"
	"syscall"
	"time"
)

var i = 0

func main() {
	router := gin.Default()
	// 创建两个接口,一个延迟9秒钟返回信息
	router.GET("/a", func(c *gin.Context) {
		time.Sleep(9 * time.Second)
		i++
		c.JSON(http.StatusOK, gin.H{
			"num": i,
		})
	})

	// 一个立刻返回信息
	router.GET("/b", func(c *gin.Context) {
		i++
		c.JSON(http.StatusOK, gin.H{
			"num": i,
		})
	})

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

	// 在协程中启动服务器
	go func() {
		if err := srv.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
			log.Fatalf("listen: %s\n", err)
		}
	}()

	// 创建信号通道,监听 SIGINT 和 SIGTERM
	quit := make(chan os.Signal, 1)
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)

	// 阻塞直到收到信号
	si := <-quit

	log.Println("Shutting down server...", si)

	// shutdown方法需要传入一个上下文参数,有两种写法:
	// 1.带超时,接收到信号之后,9秒之后无论当前请求是否完成都强制断开
	ctx, cancel := context.WithTimeout(context.Background(), 9*time.Second)
	// 2.不带超时,等待当前请求全部完成再断开
	// ctx, cancel = context.WithCancel(context.Background())
	defer cancel()

	// 调用 Shutdown 方法平滑关闭
	if err := srv.Shutdown(ctx); err != nil {
		// 当请求还在的时候强制断开了连接将产生错误,err不为空
		log.Fatal("Server forced to shutdown:", err)
	}
	
	log.Println("Server exiting")
}

步骤具体为:

  1. 捕获信号:使用 os/signal 包捕获终止信号。
  2. 创建 context:创建一个 context,当捕获到信号时触发 context 的取消,从而让正在进行的任务停止接收新的请求。
  3. 调用 Shutdown 方法:http.Server 提供了一个 Shutdown 方法,接受一个 context,它会让服务器停止接收新的请求,等待处理完当前正在进行的请求,等待时间由 context 决定。

参考:Golang 平滑重启之优雅关机


http://www.kler.cn/a/376301.html

相关文章:

  • 服务器数据恢复—DELL EqualLogic PS6100系列存储简介及如何收集故障信息?
  • 人工智能与数据安全:Facebook如何应对隐私挑战
  • 「Mac畅玩鸿蒙与硬件11」鸿蒙UI组件篇1 - Text 和 Button 组件详解
  • 贪心算法习题其二【力扣】【算法学习day.19】
  • Qt指定程序编译生成文件的位置
  • 输出【namespace = LaunchConfiguration(‘namespace‘)】中具体的namespace代表的字符串
  • 【Spark中创建RDD的两种方式】Spark中如何获取sc对象、以及创建RDD的两种方式
  • 异步编程的利之Future模式深入解析(In Depth Analysis of Future Patterns)
  • 数据可视化组件DataV在Vue3中的基本使用
  • 【GIN】go-gin 中 validator 验证功能
  • 【element el-date-picker限制时间选择范围】
  • 鸿蒙生态:机遇与挑战
  • 一对一直播源码搭建部署环境说明
  • 【性能测试】jmeter如何写入数据到文件,做持久化保存
  • linux之网络子系统-用户层接收数据包之多路复用方案(epoll)
  • jenkins 构建报错 mvn: command not found
  • 高压线路覆冰厚度测量,输电线路微波覆冰监测装置守护电网安全
  • 【Python系列】poetry安装与使用
  • WPF+MVVM案例实战(十八)- 自定义字体图标按钮的封装与实现(ABD类)
  • arcgis坐标系问题
  • 虚拟机指定固定ip地址
  • 自然语言处理(文本预处理基础)
  • Python数据分析案例61——信贷风控评分卡模型(A卡)(scorecardpy 全面解析)
  • Go语言的使用
  • 高级SQL技巧详解与实例
  • 华为机试HJ17 坐标移动