服务优雅停止和服务优雅启动

问题请在评论区中一起交流,一起进步

优雅停止

1.什么时候会触发优雅停止?

像突然停电,硬件物理损坏,进程收到sigkill信号(执行kill -9 <PID>)时,服务会被立即终止,不会触发优雅停止

当服务在滚动更新版本(master从1.2.1升级到1.2.2),服务缩容(根据负载情况减少实例数量),服务器关机或者重启时,会触发优雅停止,即执行一系列善后工作:

1.停止接收新的请求。

2.等待当前正在处理的请求全部完成。

3.释放占用的资源,如数据库连接、文件句柄等。

4.执行清理工作,如将内存中的数据刷到磁盘。

5.所有工作完成后,再安全退出。

2.如果不进行优雅停止,会发生什么?比如:

一个请求刚处理到一半(比如,数据库事务只提交了一部分),服务突然被终止 这会导致:

1.数据不一致:用户的订单可能只创建了一半。

2.客户端错误:用户会看到一个突然断开的连接错误。

3.资源泄露:数据库连接可能没有被正常关闭。

3.在go中如何实现:

Go 的 net/http 包从 1.8 版本开始,为 http.Server 提供了原生的 Shutdown() 方法,让实现优雅停机变得非常简单

Go 复制代码
func main() {
    // 创建一个channel用于接收系统信号
    quitChannel := make(chan os.Signal, 1)

    //将操作系统发来的 os.Interrupt 信号(通常是用户按下了 Ctrl+C)转发到 quitChannel 这个通道里。
    signal.Notify(quitChannel, os.Interrupt)

    //创建一个http请求路由器
    serverMux := http.NewServeMux()
    // 注册路由
    serverMux.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {
       log.Println("Received a new request...")
       writer.Write([]byte("Hello, this is a graceful shutdown example."))
       log.Println("Finished processing request.")
    })

    server := &http.Server{
       Addr:    ":8080",
       Handler: serverMux,
    }

    // 起个goroutine来启动http服务
    go func() {
       log.Println("Server is starting on port 8080...")
       if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
          log.Fatalf("Could not listen on %s: %v\n", server.Addr, err)
       }
    }()

    // 阻塞主 goroutine,直到接收到关闭信号
    <-quitChannel
    log.Println("Received shutdown signal. Server is shutting down...")
    
    // 收到关闭信号后,开始优雅关机
    
    // 设置超时时间,超出这个时间,即使请求还是执行,也要关闭这个连接了
    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    // 调用 Shutdown(),开始优雅关闭
    // Shutdown 会阻塞,直到所有连接都处理完毕或 context 超时
    if err := server.Shutdown(ctx); err != nil {
       log.Fatalf("Server shutdown failed: %v", err)
    }

    log.Println("Server has been shut down gracefully.")
}

Shutdown() 方法原理就是:

1.关闭http服务器的监听端口(任何新的客户端请求都无法建立连接,它们会立刻被拒绝)

2.会遍历当前服务器持有的所有连接,

【1】对于正在处理请求的连接 (Active Connections),它会耐心地等待它们完成当前的请求-响应周期,注意此时会进行超时强行关停连接,即请求执行时间太长就会强行关闭连接,比如设置10s后就要强行终止连接了

【2】对于已经处理完请求但保持着 keep-alive 的空闲连接 (Idle Connections),它会立即关闭它们

优雅启动

服务在宣布"我已经准备好对外提供服务"之前,必须完成所有必要的初始化工作。这包括:

加载配置文件。

建立数据库连接池。

初始化缓存(缓存预热)。

连接到其他依赖的微服务。

......

只有当所有依赖都准备就绪后,服务才开始监听端口,接收外部流量。

相关推荐
烂蜻蜓1 小时前
Flask入门教程(十二):表单处理——从基础到Flask-WTF完整实践
后端·python·flask
2601_962055978 小时前
跟据spring boot版本,查看对应的tomcat,并查看可支持的tomcat的版本范围
spring boot·后端·tomcat
Lost of 程序猿10 小时前
ASP.NET Core API 幂等性设计深度实战:从一次重复申领事故说起
后端·asp.net
QQ_216962909611 小时前
【源码编号:project79475】SpringBoot校内二手交易平台:商品发布、分类检索、留言交流、订单管理全流程实战
java·spring boot·后端
郑州光合科技余经理12 小时前
本地生活服务系统:模块边界与结算字段怎么拆
java·开发语言·前端·后端·系统架构·uni-app·php
IT_陈寒12 小时前
Vue的嵌套组件竟然吃掉了我的事件?
前端·人工智能·后端
大辉狼_音频架构13 小时前
进阶:从源码编译 SOF 固件与 topology
后端
大辉狼_音频架构13 小时前
上板:让 SOF 在 FRDM-i.MX8MP 上跑起来
后端
大辉狼_音频架构14 小时前
FRDM-IMX8MP UUU 烧录 eMMC 指南
后端
运行时异常15 小时前
【WMS 仓储系统集成 AI Agent 实战】第 3 讲:Spring Security 6 + JWT——addFilterBefore 一词之差,全站 401
java·后端