gin 服务 无缝停启 更新服务

本贴最后更新于 2069 天前,其中的信息可能已经物是人非

原文链接 :https://juejin.im/post/5d2ed3776fb9a07edb397c77 (猜测)

  • 在 kill 服务时,使用 kill -12 **** 将服务停止。

  • 服务在收到信号量 12 (SIGUSR2) 后, 不再处理新请求,

  • 将已开始的请求处理完成,

  • 将 标准输出、错误输出 和 socket 的描述符转交给之后新启动的程序

  • 无缝启停完成

    例:kill -12 12345

package run import ( "context" "errors" "flag" "github.com/gin-gonic/gin" "log" "net" "net/http" "os" "os/exec" "os/signal" "syscall" "time" ) var ( listenerGin net.Listener = nil serverGin *http.Server = nil gracefulGin = flag.Bool("graceful", false, "listen on fd open 3(internal use only)") ) func GinRun(router *gin.Engine, port string) { var err error flag.Parse() serverGin = &http.Server{ Addr: port, Handler: router, } // 判断是否为 reload if *gracefulGin { log.Println("listening on the existing file descriptor 3") f := os.NewFile(3, "") // 获取 上个服务程序的 socket 的描述符 listenerGin, err = net.FileListener(f) } else { log.Println("listening on a new file descriptor") // 新建 listenerGin, err = net.Listen("tcp", serverGin.Addr) } if err != nil { log.Printf("listener error: %v\n", err) } go func() { // 开启服务 if err := serverGin.Serve(listenerGin); err != nil && err != http.ErrServerClosed { log.Printf("listen error:%v\n", err) } }() handleSig() log.Println("signal end") } func handleSig() { sign := make(chan os.Signal) signal.Notify(sign, syscall.SIGINT, syscall.SIGTERM, syscall.SIGUSR2) for { // 接收信号量 sig := <-sign log.Printf("signal receive: %v\n", sig) ctx, _ := context.WithTimeout(context.Background(), time.Second*10) switch sig { case syscall.SIGINT, syscall.SIGTERM: // 关闭服务 log.Println("shutdown") signal.Stop(sign) if err := serverGin.Shutdown(ctx); err != nil { log.Fatalf("[ service shutdown ] error:%v\n", err) } return case syscall.SIGUSR2: // 重启服务 log.Println("reload") // 先启动新服务 if err := reloadGin(); err != nil { log.Printf("[ service reload ] error: %v\n", err) continue } // 关闭旧服务 if err := serverGin.Shutdown(ctx); err != nil { log.Fatalf("[ service reload ] shutdown error:%v\n", err) } log.Println("[ service reload ] success") return } } } func reloadGin() error { tl, ok := listenerGin.(*net.TCPListener) if !ok { return errors.New("listener is not tcp listener") } f, err := tl.File() if err != nil { return err } // 命令行启动新程序 args := []string{"-graceful"} cmd := exec.Command(os.Args[0], args...) cmd.Stdout = os.Stdout // 1 cmd.Stderr = os.Stderr // 2 cmd.ExtraFiles = []*os.File{f} // 3 return cmd.Start() }

实例代码:demo.zip

  • golang

    Go 语言是 Google 推出的一种全新的编程语言,可以在不损失应用程序性能的情况下降低代码的复杂性。谷歌首席软件工程师罗布派克(Rob Pike)说:我们之所以开发 Go,是因为过去 10 多年间软件开发的难度令人沮丧。Go 是谷歌 2009 发布的第二款编程语言。

    501 引用 • 1395 回帖 • 247 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • NetBeans

    NetBeans 是一个始于 1997 年的 Xelfi 计划,本身是捷克布拉格查理大学的数学及物理学院的学生计划。此计划延伸而成立了一家公司进而发展这个商用版本的 NetBeans IDE,直到 1999 年 Sun 买下此公司。Sun 于次年(2000 年)六月将 NetBeans IDE 开源,直到现在 NetBeans 的社群依然持续增长。

    78 引用 • 102 回帖 • 701 关注
  • Mobi.css

    Mobi.css is a lightweight, flexible CSS framework that focus on mobile.

    1 引用 • 6 回帖 • 762 关注
  • Maven

    Maven 是基于项目对象模型(POM)、通过一小段描述信息来管理项目的构建、报告和文档的软件项目管理工具。

    188 引用 • 319 回帖 • 251 关注
  • CAP

    CAP 指的是在一个分布式系统中, Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可兼得。

    12 引用 • 5 回帖 • 635 关注
  • 正则表达式

    正则表达式(Regular Expression)使用单个字符串来描述、匹配一系列遵循某个句法规则的字符串。

    31 引用 • 94 回帖
  • 服务器

    服务器,也称伺服器,是提供计算服务的设备。由于服务器需要响应服务请求,并进行处理,因此一般来说服务器应具备承担服务并且保障服务的能力。

    125 引用 • 585 回帖 • 3 关注
  • Ngui

    Ngui 是一个 GUI 的排版显示引擎和跨平台的 GUI 应用程序开发框架,基于
    Node.js / OpenGL。目标是在此基础上开发 GUI 应用程序可拥有开发 WEB 应用般简单与速度同时兼顾 Native 应用程序的性能与体验。

    7 引用 • 9 回帖 • 400 关注
  • Gzip

    gzip (GNU zip)是 GNU 自由软件的文件压缩程序。我们在 Linux 中经常会用到后缀为 .gz 的文件,它们就是 Gzip 格式的。现今已经成为互联网上使用非常普遍的一种数据压缩格式,或者说一种文件格式。

    9 引用 • 12 回帖 • 170 关注
  • flomo

    flomo 是新一代 「卡片笔记」 ,专注在碎片化时代,促进你的记录,帮你积累更多知识资产。

    6 引用 • 143 回帖
  • Hprose

    Hprose 是一款先进的轻量级、跨语言、跨平台、无侵入式、高性能动态远程对象调用引擎库。它不仅简单易用,而且功能强大。你无需专门学习,只需看上几眼,就能用它轻松构建分布式应用系统。

    9 引用 • 17 回帖 • 635 关注
  • Follow
    4 引用 • 12 回帖 • 9 关注
  • 安全

    安全永远都不是一个小问题。

    203 引用 • 818 回帖 • 1 关注
  • 单点登录

    单点登录(Single Sign On)是目前比较流行的企业业务整合的解决方案之一。SSO 的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。

    9 引用 • 25 回帖 • 2 关注
  • RYMCU

    RYMCU 致力于打造一个即严谨又活泼、专业又不失有趣,为数百万人服务的开源嵌入式知识学习交流平台。

    4 引用 • 6 回帖 • 58 关注
  • InfluxDB

    InfluxDB 是一个开源的没有外部依赖的时间序列数据库。适用于记录度量,事件及实时分析。

    2 引用 • 93 关注
  • abitmean

    有点意思就行了

    35 关注
  • 强迫症

    强迫症(OCD)属于焦虑障碍的一种类型,是一组以强迫思维和强迫行为为主要临床表现的神经精神疾病,其特点为有意识的强迫和反强迫并存,一些毫无意义、甚至违背自己意愿的想法或冲动反反复复侵入患者的日常生活。

    15 引用 • 161 回帖
  • OpenCV
    15 引用 • 36 回帖 • 7 关注
  • 职场

    找到自己的位置,萌新烦恼少。

    127 引用 • 1708 回帖 • 1 关注
  • HTML

    HTML5 是 HTML 下一个的主要修订版本,现在仍处于发展阶段。广义论及 HTML5 时,实际指的是包括 HTML、CSS 和 JavaScript 在内的一套技术组合。

    108 引用 • 295 回帖
  • Solidity

    Solidity 是一种智能合约高级语言,运行在 [以太坊] 虚拟机(EVM)之上。它的语法接近于 JavaScript,是一种面向对象的语言。

    3 引用 • 18 回帖 • 433 关注
  • C++

    C++ 是在 C 语言的基础上开发的一种通用编程语言,应用广泛。C++ 支持多种编程范式,面向对象编程、泛型编程和过程化编程。

    107 引用 • 153 回帖 • 1 关注
  • 程序员

    程序员是从事程序开发、程序维护的专业人员。

    588 引用 • 3528 回帖
  • Firefox

    Mozilla Firefox 中文俗称“火狐”(正式缩写为 Fx 或 fx,非正式缩写为 FF),是一个开源的网页浏览器,使用 Gecko 排版引擎,支持多种操作系统,如 Windows、OSX 及 Linux 等。

    7 引用 • 30 回帖 • 388 关注
  • 自由行
    3 关注
  • PWL

    组织简介

    用爱发电 (Programming With Love) 是一个以开源精神为核心的民间开源爱好者技术组织,“用爱发电”象征开源与贡献精神,加入组织,代表你将遵守组织的“个人开源爱好者”的各项条款。申请加入:用爱发电组织邀请帖
    用爱发电组织官网:https://programmingwithlove.stackoverflow.wiki/

    用爱发电组织的核心驱动力:

    • 遵守开源守则,体现开源&贡献精神:以分享为目的,拒绝非法牟利。
    • 自我保护:使用适当的 License 保护自己的原创作品。
    • 尊重他人:不以各种理由、各种漏洞进行未经允许的抄袭、散播、洩露;以礼相待,尊重所有对社区做出贡献的开发者;通过他人的分享习得知识,要留下足迹,表示感谢。
    • 热爱编程、热爱学习:加入组织,热爱编程是首当其要的。我们欢迎热爱讨论、分享、提问的朋友,也同样欢迎默默成就的朋友。
    • 倾听:正确并恳切对待、处理问题与建议,及时修复开源项目的 Bug ,及时与反馈者沟通。不抬杠、不无视、不辱骂。
    • 平视:不诋毁、轻视、嘲讽其他开发者,主动提出建议、施以帮助,以和谐为本。只要他人肯努力,你也可能会被昔日小看的人所超越,所以请保持谦虚。
    • 乐观且活跃:你的努力决定了你的高度。不要放弃,多年后回头俯瞰,才会发现自己已经成就往日所仰望的水平。积极地将项目开源,帮助他人学习、改进,自己也会获得相应的提升、成就与成就感。
    1 引用 • 487 回帖 • 4 关注
  • 分享

    有什么新发现就分享给大家吧!

    248 引用 • 1794 回帖 • 3 关注