zoukankan      html  css  js  c++  java
  • Golang 服务优雅重启

    很多时候对于服务升级的做法简单粗暴, 就简单的杀进程启动新的进程.

    还有的好一点就是多个相同的服务依次升级, 保证有服务可用. 但是公平的说这两种都会丢失请求中的连接.

    鉴于这种情况, 在现实中我们可以使用优雅重启来搞定这个问题. Golang 实现优雅重启的原理也很简单:

    • 监听 USR2 信号;

    • 收到信号后将服务监听的文件描述符传递给新的子进程;

    • 此时新老进程同时接收请求;

    • 父进程停止接收新请求, 等待旧请求完成(或超时);

    • 父进程退出.

    对于上面的原理看似简单, 其实是分成了两个大的要点:

    • 新老进程同时监听同一端口, 这个很简单, Go 很早旧支持;

    • 如何等待旧的请求完成, 这个在 Go 1.8 (新增了Server.Shutdown) 之前是需要费一番功夫的.

    我们搞定了上面的原理之后, 加上 Go 1.8 的完美等待旧请求的实现,

    我实现了一个简单的优雅重启库: https://github.com/douglarek/zerodown.

    zerodown 完美兼容基于 Go 标准库 Server 监听服务.

    对于标准库的使用, 我们可以象下面一样使用:

    package main
    
    import (
        "fmt"
        "log"
        "net/http"
        "time"
    
        "github.com/douglarek/zerodown"
    )
    
    func main() {
        http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
            time.Sleep(5 * time.Second)
            fmt.Fprintln(w, "Hello, World!")
        })
        log.Fatalln(zerodown.ListenAndServe(":8080", nil))

    对于第三方库 Gin 我们可以:

    package main
    
    import (
        "log"
        "net/http"
        "time"
    
        "github.com/douglarek/zerodown"
    
        "github.com/gin-gonic/gin"
    )
    
    func main() {
        router := gin.Default()
        router.GET("/", func(c *gin.Context) {
            time.Sleep(5 * time.Second)
            c.String(http.StatusOK, "Hello, World!")
        })
        log.Fatalln(zerodown.ListenAndServe(":8080", router))
    }
  • 相关阅读:
    iOS应用开发最佳实践
    Pywinauto 基于Win32 程序的自动化功能测试工具
    通信系统概论---电路交换与分组交换
    手动设置3G的wifi迷你无线路由
    作为一个软件测试工作者的思考
    中国人咋对“拼爹”现象如此诟病?
    HLS协议实现
    div:给div加滚动栏 div的滚动栏设置
    关于PCA算法的一点学习总结
    搜索引擎技术之概要预览
  • 原文地址:https://www.cnblogs.com/ExMan/p/14665796.html
Copyright © 2011-2022 走看看