GO的优雅终止姿势

简介: 最近优化了一版程序:用到了golang的优雅退出机制。

最近优化了一版程序:用到了golang的优雅退出机制。


程序使用etcd的election sdk做高可用选主,需要在节点意外下线的时候,主动去etcd卸任(删除10s租约), 否则已经下线的节点还会被etcd认为是leader


所以在这里,优雅退出是技术刚需。


另外根据《云原生十二要素方法论》 第9条: 快速启动和优雅终止可最大化健壮性 , 也推荐各位遵守实践。


Fast startup and shutdown are advocated for a more robust and resilient system.

粗浅的认知方案:捕获程序的终止信号, 主动去卸任


标准信号[1] Linux支持如下标准信号,第二列指示该信号遵守的标准。


Signal      Standard   Action   Comment
   ────────────────────────────────────────────────────────────────────────
   SIGABRT      P1990      Core    Abort signal from abort(3)
   SIGALRM      P1990      Term    Timer signal from alarm(2)
   SIGBUS       P2001      Core    Bus error (bad memory access)
   SIGCHLD      P1990      Ign     Child stopped or terminated
   SIGCLD         -        Ign     A synonym for SIGCHLD
   SIGCONT      P1990      Cont    Continue if stopped
   SIGEMT         -        Term    Emulator trap
   SIGFPE       P1990      Core    Floating-point exception
   SIGHUP       P1990      Term    Hangup detected on controlling terminal
                                   or death of controlling process
   SIGILL       P1990      Core    Illegal Instruction
   SIGINFO        -                A synonym for SIGPWR
   SIGINT       P1990      Term    Interrupt from keyboard
   SIGIO          -        Term    I/O now possible (4.2BSD)
   SIGIOT         -        Core    IOT trap. A synonym for SIGABRT
   SIGKILL      P1990      Term    Kill signal
   SIGLOST        -        Term    File lock lost (unused)
   SIGPIPE      P1990      Term    Broken pipe: write to pipe with no
                                   readers; see pipe(7)
   SIGPOLL      P2001      Term    Pollable event (Sys V);
                                   synonym for SIGIO
   SIGPROF      P2001      Term    Profiling timer expired
   SIGPWR         -        Term    Power failure (System V)
   SIGQUIT      P1990      Core    Quit from keyboard
   SIGSEGV      P1990      Core    Invalid memory reference
   SIGSTKFLT      -        Term    Stack fault on coprocessor (unused)
   SIGSTOP      P1990      Stop    Stop process
   SIGTSTP      P1990      Stop    Stop typed at terminal
   SIGSYS       P2001      Core    Bad system call (SVr4);
                                   see also seccomp(2)
   SIGTERM      P1990      Term    Termination signal
   SIGTRAP      P2001      Core    Trace/breakpoint trap
   SIGTTIN      P1990      Stop    Terminal input for background process
   SIGTTOU      P1990      Stop    Terminal output for background process
   SIGUNUSED      -        Core    Synonymous with SIGSYS
   SIGURG       P2001      Ign     Urgent condition on socket (4.2BSD)
   SIGUSR1      P1990      Term    User-defined signal 1
   SIGUSR2      P1990      Term    User-defined signal 2
   SIGVTALRM    P2001      Term    Virtual alarm clock (4.2BSD)
   SIGXCPU      P2001      Core    CPU time limit exceeded (4.2BSD);
                                   see setrlimit(2)
   SIGXFSZ      P2001      Core    File size limit exceeded (4.2BSD);
                                   see setrlimit(2)
   SIGWINCH       -        Ign     Window resize signal (4.3BSD, Sun)


其中SIGKILL,SIGSTOP信号不能被捕获、阻塞、忽略。


我们常见的三种终止程序的操作:


1.CTRL+C 实际是发送SIGINT信号,


2.kill pid的作用是向指定进程发送SIGTERM信号(这是kill默认发送的信息), 若应用程序没有捕获并响应该信号的逻辑,则该信号默认动作是kill掉进程,这是终止进程的推荐做法。


3.kill -9  pid 则是向指定进程发送SIGKILL信号,SIGKILL信号既不能被应用程序捕获,也不能被阻塞或忽略,


故要达成我们的目的,这里捕获 SIGINTSIGTREM信号就可满足需求。


golang提供signal包来监听并反馈收到的信号。


可针对长时间运行的程序,新开协程,持续监听信号,并插入优雅关闭的代码。


c := make(chan os.Signal)
signal.Notify(c, syscall.SIGTERM, syscall.SIGINT)
go func() {
        select  {
            case sig:= <-c: {
                log.Infof("Got %s signal. Aborting...\n", sig)
                eCli.Close()    // 利用 etcd election sdk主动卸任
                os.Exit(1)    
            }
        }
    }()


是不是依旧适配容器?


我们得看DOCKER官方docker stop,docker kill命令的定义。


docker stop[2]: The main process inside the container will receiver SIGTREM, and after a grace period,SIGKILL .(default grace period =10s)

docker kill[3]:The main process inside the container is sent SIGKILL signal (default), or the signal that is specified with the --signal option


我们常用的docker stop命令:向容器内进程发送SIGTREM信号,10s后发送SIGKILL信号,这10s时间给了程序做优雅关闭的时机,所以上面代码的逻辑是能适配容器的。

相关文章
|
开发者
这款酷似飞书文档的工具开源了,支持私有部署!!!
这个酷似飞书文档的工具真的非常好用,体验和飞书差不多,同样支持 Markdown 语法,经常使用 Markdown 写文档的同学一定要试试了,相信你一定会喜欢上它,这个工具是我用差不多20天左右的时间开发的,而且它的前后端项目现在都已经开源了,如果你能帮我推广那我更是感激不尽。所以,如果你想有一个可以私有部署的文档工具,而且体验还特别棒的的,那就快来试试这个吧,相信它不会让你失望的。
1865 0
|
Oracle 安全 关系型数据库
Oracle数据恢复—Oracle数据库误删除的数据恢复方法探讨
删除Oracle数据库数据一般有以下2种方式:delete、drop或truncate。下面针对这2种删除oracle数据库数据的方式探讨一下oracle数据库数据恢复方法(不考虑全库备份和利用归档日志)。
|
前端开发 JavaScript 开发者
Angular状态管理神器ngrx Store:从零开始的实践指南与进阶优化秘籍,让你的前端应用状态井井有条、高效运行的绝招大揭秘
【8月更文挑战第31天】状态管理在现代Web应用开发中至关重要,特别是在构建大型、复杂的Angular应用时。ngrx Store借鉴Redux的设计理念,提供集中式状态管理和可预测的数据流,有助于增强应用的可维护性和可测试性。
345 0
|
JavaScript 搜索推荐 Java
vscode打造舒适的python开发环境
_shigen_ 是一位专注于Java、Python、Vue和Shell等技术的博主,分享成长与认知。本文旨在记录配置Mac Python开发环境的过程,以优化使用体验和效率。内容包括:检查与验证Python版本,设置pip的阿里云镜像源以加速下载,以及VSCode的个性化配置,如选用美观的等宽字体和安装Python、isort(导入排序)及autopep8(代码格式化)插件。通过这些步骤,读者可复刻作者的高效开发环境。关注_shigen_ ,每天学习新知识!
206 0
vscode打造舒适的python开发环境
|
开发框架 JSON 前端开发
循序渐进VUE+Element 前端应用开发(7)--- 介绍一些常规的JS处理函数
循序渐进VUE+Element 前端应用开发(7)--- 介绍一些常规的JS处理函数
|
存储 缓存 算法
Linux系统中内核态、用户态和零拷贝技术解析
Linux系统中内核态、用户态和零拷贝技术解析
758 0
|
小程序 Java Go
用golang实现一个小程序商城后台系统(moshopserver)
用golang实现一个小程序商城后台系统(moshopserver) golang和c/c++比起来是一门新的语言,一直想学,网上搜集了一些资料,有些人说很容易上手,确实是这样,和C/C++比起来,少了很多乱七八糟的语法。
3274 0
用golang实现一个小程序商城后台系统(moshopserver)
|
网络安全
Cloud Toolkit 支持 SSH 代理(跳板机)
在之前的文章中,我们分别针对开发者最主流的编程工具,介绍了《如何在 IntelliJ IDEA 中部署代码到服务器》,以及《https://yq.aliyun.com/articles/698375》。
6189 104
|
存储 Java
数据结构之第七章、队列(Queue)
队列具有先进先出FIFO(FirstIn First Out):进行的一端称为:进行的一端称为。
280 0
|
JSON 运维 Linux
Ansible 工作架构和原理| 学习笔记
快速学习 Ansible 工作架构和原理
Ansible 工作架构和原理| 学习笔记