这篇文章主要介绍了Golang怎么使用channel实现一个优雅退出功能的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Golang怎么使用channel实现一个优雅退出功能文章都会有所收获,下面我们一起来看看吧。通过一个 os.Signal
类型的 chan
接收退出信号,收到信号后进行对应的退出收尾工作,利用 context.WithTimeout
或 time.After
等方式设置退出超时时间防止收尾等待时间过长。由于 Hertz 的 Hook 功能中的 ShutdownHook 是 graceful shutdown 的一环,并且 Hook 功能的实现也不是很难所以这里就一起分析了,如果不想看直接跳到后面的章节即可 :)Hook 函数是一个通用的概念,表示某事件触发时所伴随的操作,Hertz 提供了 StartHook 和 ShutdownHook 用于在服务触发启动后和退出前注入用户自己的处理逻辑。两种 Hook 具体是作为两种不同类型的 Hertz Engine 字段,用户可以直接以 append
的方式添加自己的 Hooks,下面是作为 Hertz Engine 字段的代码:可以看到两者都是函数数组的形式,并且是公开字段,所以可以直接 append
,函数的签名如下,OnShutdown
的函数不会返回 error 因为都退出了所以没法对错误进行处理:并且设置的 StartHook 会按照声明顺序依次调用,但是 ShutdownHook 会并发的进行调用,这里的实现后面会讲。StartHook 的执行时机触发 Server 启动后,框架会按函数声明顺序依次调用所有的 StartHook
函数,完成调用之后,才会正式开始端口监听,如果发生错误,则立刻终止服务。上面是官方文档中描述的 StartHook 的执行时机,具体在源码中就是下面的代码:熟悉或使用过 Hertz 的同学肯定知道 h.Spin()
方法调用后会正式启动 Hertz 的 HTTP 服务,而上面的 engine.Run
方法则是被 h.Spin
异步调用的。可以看到在 engine.Run
方法里循环调用 engine.OnRun
数组中注册的函数,最后执行完成完成并且没有 error 的情况下才会执行 engine.listenAndServe()
正式开始端口监听,和官方文档中说的一致,并且这里是通过 for 循环调用的所以也正如文档所说框架会按函数声明顺序依次调用。ShutdownHook 的执行时机Server 退出前,框架会并发地调用所有声明的 ShutdownHook
函数,并且可以通过 server.WithExitWaitTime
配置最大等待时长,默认为5秒,如果超时,则立刻终止服务。上面是官方文档中描述的 ShutdownHook 的执行时机,具体在源码中就是下面的代码:通过 sync.WaitGroup
保证每个 ShutdownHook 函数都执行完毕后给形参 ch
发送信号通知,免费云主机域名注意这里每个 ShutdownHook 都起了一个协程,所以是并发执行,这也是官方文档所说的并发的进行调用。服务注册与下线的执行时机服务注册Hertz 虽然是一个 HTTP 框架,但是 Hertz 的客户端和服务端可以通过注册中心进行服务发现并进行调用,并且 Hertz 也提供了大部分常用的注册中心扩展,在下面的 initOnRunHooks
方法中,通过注册一个 StartHook
调用 Registry
接口的 Register
方法对服务进行注册。取消注册在 Shutdown
方法中进行调用 Deregister
取消注册,可以看到刚刚提到的 executeOnShutdownHooks
的方法在开始异步执行后就会进行取消注册操作。讲 graceful shutdown 之前最好了解一下 Hertz Engine 的 status
字段以获得更好的阅读体验ww如上所示,status
是一个 uint32
类型的内部字段,用来表示 Hertz Engine 的状态,具体具有四种状态(Init 1, Running 2, Shutdown 3, Closed 4),由下面的常量定义。下面列出了 Hertz Engine 状态改变的时机:对状态的改变都是通过 atomic
包下的函数进行更改的,保证了并发安全。Hertz Graceful Shutdown 功能的核心方法如下,signalToNotify
数组包含了所有会触发退出的信号,触发了的信号会传向 signals
这个 channel,并且 Hertz 会根据收到信号类型决定进行优雅退出还是强制退出。如果 engine.Run
方法返回了一个错误则会通过 errCh
传入 waitSignal
函数然后触发立刻退出。前面也提到 h.Spin()
是以异步的方式调用 engine.Run
,waitSignal
则由 h.Spin()
直接调用,所以运行后 Hertz 会阻塞在 waitSignal
函数的 select
这里等待信号。三个会触发 Shutdown 的信号区别如下:syscall.SIGINT
表示中断信号,通常由用户在终端上按下 Ctrl+C 触发,用于请求程序停止运行;syscall.SIGHUP
表示挂起信号,通常是由系统发送给进程,用于通知进程它的终端或控制台已经断开连接或终止,进程需要做一些清理工作;syscall.SIGTERM
表示终止信号,通常也是由系统发送给进程,用于请求进程正常地终止运行,进程需要做一些清理工作;如果 waitSignal
的返回值为 nil
则 h.Spin()
会进行优雅退出:并且 Hertz 通过 context.WithTimeout
的方式设置了优雅退出的超时时长,默认为 5 秒,用户可以通过 WithExitWaitTime
方法配置 server 的优雅退出超时时长。将设置了超时时间的 ctx
传入 Shutdown
方法,如果 ShutdownHook 先执行完毕则 ch
channel 收到信号后返回退出,否则 Context 超时收到信号强制返回退出。以上就是 Hertz 优雅退出部分的源码分析,可以发现 Hertz 多次利用了协程,通过 channel 传递信号进行流程控制和信息传递,并通过 Context 的超时机制完成了整个优雅退出流程。说是自己实现实际上也就是代码搬运工,把 Hertz 的 graceful shutdown 及其相关功能给 PIANO 进行适配罢了ww代码实现都差不多,一些小细节根据我个人的习惯做了修改,完整修改参考这个 commit,对 PIANO 感兴趣的话欢迎 Star !关于“Golang怎么使用channel实现一个优雅退出功能”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“Golang怎么使用channel实现一个优雅退出功能”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注百云主机行业资讯频道。
这篇文章主要介绍“Python3中的if条件语句怎么使用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Python3中的if条件语句怎么使用”文章能帮助大家解决问题。一什么是if条件语句首先,我们都知道if是如果的意思…
免责声明:本站发布的图片视频文字,以转载和分享为主,文章观点不代表本站立场,本站不承担相关法律责任;如果涉及侵权请联系邮箱:360163164@qq.com举报,并提供相关证据,经查实将立刻删除涉嫌侵权内容。