前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Monibuca v5 中实现热重启

Monibuca v5 中实现热重启

作者头像
我不是码神
发布2024-04-16 08:03:44
1390
发布2024-04-16 08:03:44
举报
文章被收录于专栏:流媒体技术

优雅关闭

在 v4 中关闭一个流通过改变流的生命周期实现

v4 中流有一个 G(goroutine)专门负责管理流的生命周期,并使用状态自动机来实现状态变更。

但是在退出发布者或者订阅者,仍然遇到一些问题,首先发布者和订阅者各自有自己的 G ,多数用于网络通讯。此外退出分为两种情况,一种是内部原因,比如超时,出错等。另一种是外部原因,比如用户手动关闭,连接断开等。很难优雅的统一处理。

v5 中通过第一性原理思考,移除不必要的 G,不再有管理生命周期的状态机,流和发布者变成同一个概念,实现主动被动退出的统一处理,使得代码进一步简化。

优雅关闭流和订阅者

为了尽量减少锁和 G的使用,因此选择使用动态Select方式,在 Server 层面的一个大 G 中实现,对发布者和订阅者的退出监听。下面是伪代码,为了方便理解

代码语言:javascript
复制
select {
 case <-server 退出信号:
 退出
 case <-定时器信号:
 定时任务
 case <-事件总线信号:
 事件处理
 case <-发布者 1 退出信号:
 case <-发布者 2 退出信号:
 ...
 case <-订阅者 1 退出信号:
 case <-订阅者 2 退出信号:
 ...
}

为啥优雅呢?因为在一个 G 里面处理,不需要锁,可以方便的修改发布者集合,订阅者集合,以及等待区(订阅时还没有发布者)等很多并发读写的场景。实际上你无法直接写出这个 select,因为发布者和订阅者动态添加和删除的。此时就需要用到 reflect.Select(cases) 了。

优雅关闭 Server

有了优雅关闭发布者和订阅者,那么剩下的就比较简单了,就是要优雅关闭插件。在 v4 中并不支持这种操作。为了能实现动态热更新配置等场景,优雅关闭插件就很重要,因此设计的时候就考虑到了监听和退出监听的逻辑。因此在 sever 退出的时候,需要 1. 退出所有发布者 2. 退出所有订阅者 3. 关闭所有插件的连接监听 4. 关闭 server 级的 http 和 tcp 监听

所有这些对象都包含了可以用来退出的 context

代码语言:javascript
复制
type Unit struct {
    StartTime               time.Time
    *slog.Logger            `json:"-" yaml:"-"`
    context.Context         `json:"-" yaml:"-"`
    context.CancelCauseFunc `json:"-" yaml:"-"`
}

func (unit *Unit) Stop(err error) {
    unit.Info("stop", "reason", err.Error())
    unit.CancelCauseFunc(err)
}

通过传递一个 error 对象,可以用来标记退出的原因。

Server 热重启

本文所说的热重启并非极端意义的连接保持,那种极难实现

有了以上的铺垫,就可以用一个标记为重启的 error 对象来实现 server 的重启:

代码语言:javascript
复制
func (s *Server) Run(ctx context.Context, conf any) (err error) {
    for err = s.run(ctx, conf); err == ErrRestart; err = s.run(ctx, conf) {
        s.reset()
    }
    return
}

在重启时首先会优雅关闭 server,销毁所有资源,然后重新初始化 server 对象,读取配置,初始化插件对象,监听端口。就仿佛进程重启了一样。

实现热重启的好处

进程不再需要退出,对于错误处理更友好,对于 docker 容器来说,进程退出往往就会导致 docker 实例退出。此外重启速度更快,方便快速更新配置。另一个好处是结合多实例,对于单元测试和基准测试更方便,因为单元测试的时候不能退出进程,此时就可以启动多个 server 实例,进行测试,也可以关闭这些实例,测试其他内容。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-04-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 优雅关闭
    • 优雅关闭流和订阅者
      • 优雅关闭 Server
      • Server 热重启
        • 实现热重启的好处
        相关产品与服务
        容器服务
        腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档