当前位置: 首页 > 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 - 包含请求发送到…...

python/java环境配置

环境变量放一起 python&#xff1a; 1.首先下载Python Python下载地址&#xff1a;Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个&#xff0c;然后自定义&#xff0c;全选 可以把前4个选上 3.环境配置 1&#xff09;搜高级系统设置 2…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明

AI 领域的快速发展正在催生一个新时代&#xff0c;智能代理&#xff08;agents&#xff09;不再是孤立的个体&#xff0c;而是能够像一个数字团队一样协作。然而&#xff0c;当前 AI 生态系统的碎片化阻碍了这一愿景的实现&#xff0c;导致了“AI 巴别塔问题”——不同代理之间…...

前端开发面试题总结-JavaScript篇(一)

文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包&#xff08;Closure&#xff09;&#xff1f;闭包有什么应用场景和潜在问题&#xff1f;2.解释 JavaScript 的作用域链&#xff08;Scope Chain&#xff09; 二、原型与继承3.原型链是什么&#xff1f;如何实现继承&a…...

20个超级好用的 CSS 动画库

分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码&#xff0c;而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库&#xff0c;可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画&#xff0c;可以包含在你的网页或应用项目中。 3.An…...

群晖NAS如何在虚拟机创建飞牛NAS

套件中心下载安装Virtual Machine Manager 创建虚拟机 配置虚拟机 飞牛官网下载 https://iso.liveupdate.fnnas.com/x86_64/trim/fnos-0.9.2-863.iso 群晖NAS如何在虚拟机创建飞牛NAS - 个人信息分享...

Sklearn 机器学习 缺失值处理 获取填充失值的统计值

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 使用 Scikit-learn 处理缺失值并提取填充统计信息的完整指南 在机器学习项目中,数据清…...

MySQL体系架构解析(三):MySQL目录与启动配置全解析

MySQL中的目录和文件 bin目录 在 MySQL 的安装目录下有一个特别重要的 bin 目录&#xff0c;这个目录下存放着许多可执行文件。与其他系统的可执行文件类似&#xff0c;这些可执行文件都是与服务器和客户端程序相关的。 启动MySQL服务器程序 在 UNIX 系统中&#xff0c;用…...

Oracle实用参考(13)——Oracle for Linux物理DG环境搭建(2)

13.2. Oracle for Linux物理DG环境搭建 Oracle 数据库的DataGuard技术方案,业界也称为DG,其在数据库高可用、容灾及负载分离等方面,都有着非常广泛的应用,对此,前面相关章节已做过较为详尽的讲解,此处不再赘述。 需要说明的是, DG方案又分为物理DG和逻辑DG,两者的搭建…...

[KCTF]CORE CrackMe v2.0

这个Reverse比较古老&#xff0c;已经有20多年了&#xff0c;但难度确实不小。 先查壳 upx压缩壳&#xff0c;0.72&#xff0c;废弃版本&#xff0c;工具无法解压。 反正不用IDA进行调试&#xff0c;直接x32dbg中&#xff0c;dump内存&#xff0c;保存后拖入IDA。 这里说一下…...

年度峰会上,抖音依靠人工智能和搜索功能吸引广告主

上周早些时候举行的第五届年度TikTok World产品峰会上&#xff0c;TikTok推出了一系列旨在增强该应用对广告主吸引力的功能。 新产品列表的首位是TikTok Market Scope&#xff0c;这是一个全新的分析平台&#xff0c;为广告主提供整个考虑漏斗的全面视图&#xff0c;使他们能够…...