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

如何在go中实现程序的优雅退出,go-kratos源码解析

使用kratos这个框架有近一年了,最近了解了一下kratos关于程序优雅退出的具体实现。

这部分逻辑在app.go文件中,在main中,找到app.Run方法,点进入就可以了

它包含以下几个部分:

  1. App结构体:包含应用程序的配置选项和运行时状态。

  2. New函数:创建一个App实例。

  3. Run方法:启动应用程序。主要步骤包括:

    • 构建ServiceInstance注册实例
    • 启动Server
    • 注册实例到服务发现
    • 监听停止信号
  4. Stop方法:优雅停止应用程序。主要步骤包括:

    • 从服务发现中注销实例
    • 取消应用程序上下文
    • 停止Server
  5. buildInstance方法:构建用于服务发现注册的实例。

  6. NewContext和FromContext函数:给Context添加AppInfo,便于后续从Context获取。

核心的逻辑流程是:

  1. 创建App实例
  2. 在App.Run()里面启动Server,注册实例,监听信号
  3. 接收到停止信号后会调用App.Stop()停止应用

我们先对Run方法进行一个源码进行查看

// Run executes all OnStart hooks registered with the application's Lifecycle.
func (a *App) Run() error {// 构建服务发现注册实例instance, err := a.buildInstance() if err != nil {return err}// 保存实例  a.mu.Lock()a.instance = instancea.mu.Unlock()// 创建错误组eg, ctx := errgroup.WithContext(NewContext(a.ctx, a))// 等待组,用于等待Server启动完成wg := sync.WaitGroup{}// 启动每个Serverfor _, srv := range a.opts.servers {srv := srv eg.Go(func() error {// 等待停止信号<-ctx.Done()  // 停止ServerstopCtx, cancel := context.WithTimeout(a.opts.ctx, a.opts.stopTimeout)defer cancel()return srv.Stop(stopCtx)})wg.Add(1)eg.Go(func() error {// Server启动完成wg.Done() // 启动Server  return srv.Start(NewContext(a.opts.ctx, a)) })}// 等待所有Server启动完成wg.Wait()// 注册服务实例if a.opts.registrar != nil {rctx, rcancel := context.WithTimeout(ctx, a.opts.registrarTimeout)defer rcancel()if err := a.opts.registrar.Register(rctx, instance); err != nil {return err}}// 监听停止信号c := make(chan os.Signal, 1)signal.Notify(c, a.opts.sigs...)eg.Go(func() error {select {case <-ctx.Done():return nilcase <-c:// 收到停止信号,停止应用------------- ⬅️注意此时return a.Stop() }})// 等待错误组执行完成if err := eg.Wait(); err != nil && !errors.Is(err, context.Canceled) {return err}return nil
}

核心逻辑就是这里⬇️,使用signal.Notify去监听操作系统给出的停止信号。

  // 监听停止信号c := make(chan os.Signal, 1)signal.Notify(c, a.opts.sigs...)eg.Go(func() error {select {case <-ctx.Done():return nilcase <-c:// 收到停止信号,停止应用return a.Stop() }})

然后调用了Stop方法,我们再看下Stop的源码

// Stop gracefully stops the application.
func (a *App) Stop() error {// 获取服务实例 a.mu.Lock()instance := a.instancea.mu.Unlock()// 从服务发现注销实例if a.opts.registrar != nil && instance != nil {ctx, cancel := context.WithTimeout(NewContext(a.ctx, a), a.opts.registrarTimeout)defer cancel()if err := a.opts.registrar.Deregister(ctx, instance); err != nil {return err}}// 取消应用上下文if a.cancel != nil {a.cancel() }return nil
}

主要步骤是:

1. 获取已经保存的服务实例
2. 如果配置了服务发现,则从服务发现中注销该实例
3. 取消应用上下文来通知应用停止在Run方法中,我们通过context.WithCancel创建的可取消的上下文Context,在这里通过调用cancel函数来取消该上下文,以通知应用停止。取消上下文会导致在Run方法中启动的协程全部退出,从而优雅停止应用。所以Stop方法比较简单,关键是利用了Context来控制应用生命周期。

我们可以注意到,在Run方法中,我们使用到了一个signal包下的Notify方法来对操作系统的关闭事件进行监听,这个是我们动作的核心,我把这部分单独整理在了另一篇文章中。

通过对操作系统事件的监听,我们就可以对一些必须完成的任务进行优雅地停止,如果有一些任务必须完成,我们可以在任务开始使用 wg := sync.WaitGroup{} 来对任务进行一个Add操作,当所有任务完成,监听到操作系统的关闭动作,我们需要使用wg.wait() 等待任务完成再进行退出。以实现一个优雅地启停。

相关文章:

如何在go中实现程序的优雅退出,go-kratos源码解析

使用kratos这个框架有近一年了&#xff0c;最近了解了一下kratos关于程序优雅退出的具体实现。 这部分逻辑在app.go文件中&#xff0c;在main中&#xff0c;找到app.Run方法&#xff0c;点进入就可以了 它包含以下几个部分: App结构体:包含应用程序的配置选项和运行时状态。 …...

Appium+python自动化(二十八)- 高级滑动(超详解)

高级溜冰的滑动 滑动操作一般是两点之间的滑动&#xff0c;这种滑动在这里称其为低级的溜冰滑动&#xff1b;就是上一节给小伙伴们分享的。然而实际使用过程中用户可能要进行一些多点连续滑动操作。如九宫格滑动操作&#xff0c;连续拖动图片移动等场景。那么这种高级绚丽的溜…...

github token使用方法

git remote set-url origin https://<githubtoken>github.com/<username>/<repositoryname>.git 在私有仓库的HTTPS的url上加入<githubtoken>即为token url&#xff0c;可以免ssh key登录...

Spring属性注解对配置项名称的自动转换

一、前言 在Spring中&#xff0c;我们经常需要将配置文件中的属性值注入到Java类中。Spring提供了两个主要的注解来实现这一功能&#xff1a;Value 和 ConfigurationProperties。其中 ConfigurationProperties支持将配置项名称与Java类中的属性名进行自动转换&#xff0c;包括…...

Docker 安全 Docker HTTPS请求过程与配置

Docker 容器安全注意点 尽量别做的事 尽量不用 --privileged 运行容器&#xff08;授权容器root用户拥有宿主机的root权限&#xff09; 尽量不用 --network host 运行容器&#xff08;使用 host 网络模式共享宿主机的网络命名空间&#xff09; 尽量不在容器中运行 ssh 服务 尽…...

DevOps(三)

CD(二) 1. 整体流程2. 环境准备1. jenkins安装2. 编译安装git3. docker安装4. docker-compose安装5. sonarqube安装6. harbor安装7. gitlab私服8. maven安装9. Nexus部署10. K8s部署3. 安装java及编写代码3.1 安装java3.2 安装IntelliJ IDEA3.3 安装tomcat3.4 安装maven3.5 c…...

AOP的妙用

一、改代码 自定义注解用于提示该代码已经在AOP中重构了 public interface ReviseToAop {// 用于记录修改状态String value() default ""; }使用注解&#xff08;无意义&#xff0c;只是表名被修改&#xff09; ReviseToAop("修改于&#xff1a;2023/7/30&quo…...

CAN转ETHERCAT网关将CAN 总线和 ETHERCAT 网络连接方法

由于好多现场会出现将CAN总线的设备接到EtherCAT网络中&#xff0c;由于协议的不相同&#xff0c;不能直接进行连接&#xff0c;现需一种能同时兼容CAN 总线和ETHERCAT网络的一种设备&#xff0c;由此捷米JM-ECT-CAN 是自主研发的一款 ETHERCAT 从站功能的通讯网关。该产品主要…...

【大数据趋势】7月30日 汇率,恒指期货的大数据趋势概率分析。

1. 数据源头之一 : 汇率变化 从程序模拟趋势来看&#xff0c;美元在持续弱势状态&#xff0c;周线上正在构建一个新的下跌趋势&#xff0c;而且正在反抽过程中&#xff0c;即将完成&#xff0c;如果没有外部干预&#xff0c;会顺势往下。从月线来看&#xff0c;高点逐步降低&a…...

mac使用mvn下载node-sass 会Binary download failed, trying source

m1 上使用nvm 以下node的版本可以直接下载&#xff08;Binary download&#xff0c;而不是 trying source&#xff09;而不用切换mac cpu架构 zhiwenwenzhiwenwendeMBP cockpit % nvm install 14.15.5 Downloading and installing node v14.15.5... Downloading https://node…...

【C++】开源:Muduo网络库配置与使用

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍Muduo网络库配置与使用。 无专精则不能成&#xff0c;无涉猎则不能通。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&#xff0c;下…...

VCS ICO - Intelligent Coverage Optimization

ico是vcs提供的用于优化覆盖率的feature&#xff1b;一般用户通过dist solver bofore等约束了变量的随机概率&#xff0c;而ico会在用户约束的基础上&#xff0c;做一些自动“修正”&#xff0c;以此来优化随机激励&#xff0c;提高随机多样性&#xff0c;加速覆盖率收敛&#…...

【分布式系统】分布式系统的8个谬误

网络可靠 对于分布式系统来说&#xff0c;网络、计算、存储是三大基石&#xff0c;系统之间进行拆分隔离之后&#xff0c;那么必定存在网络通讯&#xff0c;而网络是最不可靠的。 不管是从硬件层面还是软件层面来说&#xff0c;网络是不可靠的。&#xff08;断电、配置错误、ID…...

tinkerCAD案例:25. 量角器 - 测量角度

tinkerCAD案例&#xff1a;25. 量角器 - 测量角度 原文 Now we’re going to make a protractor! A Protractor is one of the most basic, but essential, tools for making measurements. It is, then, surprising that the modern protractor is barely over 200 years ol…...

Flutter 使用texture_rgba_renderer实现桌面端渲染视频

Flutter视频渲染系列 第一章 Android使用Texture渲染视频 第二章 Windows使用Texture渲染视频 第三章 Linux使用Texture渲染视频 第四章 全平台FFICustomPainter渲染视频 第五章 Windows使用Native窗口渲染视频 第六章 桌面端使用texture_rgba_renderer渲染视频&#xff08;本…...

linux虚拟机开机后桌面显示CentOS-7.5-x86盘片文件,并且无法远程连接虚拟机?

在虚拟机启动后遇到了显示CentOS-7.5-x86光盘片文件的问题&#xff0c;并且无法远程连接到虚拟机&#xff0c;有几个可能的解决方法&#xff1a; 检查虚拟机设置&#xff1a;确保虚拟机的网络适配器已正确配置&#xff0c;并且虚拟机配置的网络选项是桥接模式或 NAT 模式&#…...

【Spring Boot 源码学习】走近 AutoConfigurationImportSelector

AutoConfigurationImportSelector 源码解析 引言主要内容1. ImportSelector 接口2. DeferredImportSelector 接口3. AutoConfigurationImportSelector 功能概述 总结 引言 上篇博文我们了解了 EnableAutoConfiguration 注解&#xff0c;其中真正实现自动配置功能的核心实现者 …...

系统学习Linux-MySQL数据库备份(四)

一、概述 数据库备份是指将数据库中的数据、表格、视图、存储过程、触发器等信息备份到另一个地方&#xff0c;一遍在数据库丢失或损坏时进行恢复&#xff0c;数据库备份是数据库管理中必不可少的一项工作&#xff0c;通过备份可以保护数据库中的数据和业务。 二、数据备份的…...

具身智能controller---RT-1(Robotics Transformer)(中---实验介绍)

6 实验 实验目的是验证以下几个问题: RT-1可以学习大规模指令数据&#xff0c;并且可以在新任务、对象和环境上实现zero-shot的泛化能力&#xff1f;训练好的模型可以进一步混合多种其他数据&#xff08;比如仿真数据和来自其他机器人的数据&#xff09;吗&#xff1f;多种方…...

无涯教程-jQuery - load( url, data, callback)方法函数

load(url&#xff0c;data&#xff0c;callback)方法从服务器加载数据&#xff0c;并将返回的HTML放入匹配的元素中。 load( url, [data], [callback] ) - 语法 [selector].load( url, [data], [callback] ) 这是此方法使用的所有参数的描述- url - 包含请求发送到…...

【Shell】Shell编程之免交互

免交互&#xff1a;不需要人为控制就可以完成的自动化操作 自动化运维 Shell脚本和免交互是一个概念&#xff0c;但是两种写法 here document 使用i/o重定向的方式将命令的列表提供给交互式的程序或者命令 是一种标准输入&#xff0c;只能接受正确的指令或命令&#x…...

从Vue2到Vue3【七】——Vue2中响应式原理的实现及其缺陷

系列文章目录 内容链接从Vue2到Vue3【零】Vue3简介从Vue2到Vue3【一】Composition API&#xff08;第一章&#xff09;从Vue2到Vue3【二】Composition API&#xff08;第二章&#xff09;从Vue2到Vue3【三】Composition API&#xff08;第三章&#xff09;从Vue2到Vue3【四】C…...

用C语言实现堆排序算法

1.设计思路 排序的思想将一个数组按递增的顺序进行排序&#xff0c;将数组的第一个位置空下&#xff08;下标为0&#xff09;&#xff0c;因为会导致子节点和本身同一个结点&#xff08;i和2i一致&#xff09;&#xff0c;每次堆排序在下标1的位置放上了最大值&#xff0c;然后…...

tauri在github上进行自动更新打包并发版过程,实战操作避坑

从网上找了很多很多的文章&#xff0c;结果还是入坑了&#xff0c;一个问题找了一天才解决&#xff1a; Error A public key has been found, but no private key. Make sure to set TAURI_PRIVATE_KEY environment variable. 596 ELIFECYCLE  Command failed with exit code…...

css中flex后文本溢出的问题

原因&#xff1a; 为了给flex item提供一个合理的默认最小尺寸&#xff0c;flex将flex item的min-width 和 min-height属性设置为了auto flex item的默认设置为&#xff1a; min-width&#xff1a; auto 水平flex布局 min-height&#xff1a;auto 垂直flex布局 解决办法&…...

restful接口设计规范[仅供参考]

1. 域名 应该尽量将API部署在专用域名之下。 https://api.example.com 如果确定API很简单&#xff0c;不会有进一步扩展&#xff0c;可以考虑放在主域名下。 https://www.example.org/api/2. 版本&#xff08;Versioning&#xff09; 应该将API的版本号放入URL。 http://…...

Metabase 远程代码执行(CVE-2023-38646)

漏洞描述 Metabase是一款开源数据分析及可视化工具。它可允许用户连接至各种不同类型数据源,未经身份认证的攻击者可利用本漏洞在服务器上以运行 Metabase服务器的权限进行任意命令执行。 免责声明 技术文章仅供参考,任何个人和组织使用网络应当遵守宪法法律,遵守公共秩…...

【TiDB理论知识 07】SQL执行流程

一 DML语句读写流程 1 DML语句读流程概要 用户发出SQL 被协议层接收 Protocal Layer 通过PD获取时间戳 parse模块 解析SQL&#xff0c;通过词法解析 与 语法解析 生成AST语法树 编译SQL Compile模块 ,区分点查 与 非点查&#xff0c;生成执行计划 发送给Executor,从TIKV获…...

微服务——服务异步通讯RabbitMQ

前置文章 消息队列——RabbitMQ基本概念容器化部署和简单工作模式程序_北岭山脚鼠鼠的博客-CSDN博客 消息队列——rabbitmq的不同工作模式_北岭山脚鼠鼠的博客-CSDN博客 消息队列——spring和springboot整合rabbitmq_北岭山脚鼠鼠的博客-CSDN博客 目录 Work queues 工作队列…...

事件冒泡、事件捕获和事件委托

原文合集地址如下&#xff0c;有需要的朋友可以关注 本文地址 合集地址 什么是事件冒泡、事件捕获和事件委托&#xff1f; 事件冒泡&#xff08;Event Bubbling&#xff09;、事件捕获&#xff08;Event Capturing&#xff09;和事件委托&#xff08;Event Delegation&…...

昆明网站建设一条龙服务/百度推广多少钱

Mac 通过终端CD命令快速定位到指定文件夹 1、打开终端2、输入cd3、将想要到达的文件夹拖进终端&#xff0c;点击回车&#xff0c;就到了指定的文件夹了 phonegap下载地址&#xff1a;http://phonegap.com/install/ OK下载到zip包&#xff0c;首先我们解压一下&#xff0c;通过…...

网站需要备案吗/怎么建立自己的企业网站

小伙伴们&#xff0c;我们的行摄游记又回来啦&#xff0c;这次要去一个我向往已久的地方&#xff0c;重庆&#xff01;嘿嘿&#xff0c;吃货之魂已经燃起&#xff0c;一起来瞧瞧吧。 作为一个资深吃货&#xff0c;虎虎对重庆可是种草已久&#xff0c;各种美食我来啦&#xff01…...

wordpress主题报错/网站代发外链

PHP 安全三板斧&#xff1a;过滤、验证和转义之过滤篇 & Laravel底层SQL注入规避由 学院君 创建于4年前, 最后更新于 1年前版本号 #328413 views19 likes0 collects我们在开发应用时&#xff0c;一般有个约定&#xff1a;不要信任任何来自不受自己控制的数据源中的数据。例…...

wordpress手机版如何设置密码/八八网

一.基本信息 1.1 基本常识 1.2 事务隔离级别 1.3 事务的传播行为 A业务方法调用B业务方法&#xff0c;如果B看A没有业务方法&#xff0c;则新建一个业务方法&#xff0c;如果B看A业务方法&#xff0c;则B就加入到A的事务方法中。 1.4 事务的状态 1.5 总结...

高校网站建设的重要性/seo技术优化整站

阅读目录为什么要用xargs&#xff0c;问题的来源xargs是什么&#xff0c;与管道有什么不同xargs的一些有用的选项回到顶部为什么要用xargs&#xff0c;问题的来源 在工作中经常会接触到xargs命令&#xff0c;特别是在别人写的脚本里面也经常会遇到&#xff0c;但是却很容易与管…...

河南住房和城乡建设厅门户网站/店铺推广方案怎么写

关于Linux FTP服务错误代码500上一篇 /下一篇 2012-10-16 09:49:58/ 个人分类&#xff1a;Linux如果Linux系统中是以vsftpd架设的ftp服务器&#xff0c;在未关闭SELinux的情况下&#xff0c;登录FTP服务器&#xff0c;会出现如下错误提示&#xff1a;500 OOPS:***此错误变可以…...