Golang实践之花椒直播总线系统

2023-12-08 20:10

本文主要是介绍Golang实践之花椒直播总线系统,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

总线系统大家并不陌生,各个业务团队都有自己的数据流的处理策略,一般都是基于开源的,能提供队列数据结构的产品,进行包装构建。相比较传统业务,直播场景大型活动中洪峰流量较大,因此业务形态上有约20%左右的处理,都采取了异步化。早期内部也有多套解决方案,队列存储部分有基于redis,nsq,kafka的。异步任务消费过程有cron消费,deamon消费,自研发的processWorker(使用php,基于父子进程方式,进行进程管理的工具)。子团队根据需要和技术栈选择和自行维护。如何针对各个业务线有一个统一的异步处理系统,是花椒系统研发团队需要面临的问题,我们不是要造一个队列服务,而是要基于花椒现有的应用,提供一个统一的队列资源管理,运维,监控系统。并且针对不同技术栈的团队进行定制。提供统一友好的可视化服务。目前服务上线以来,已经迁移和承接了花椒直播大部分的异步任务。由于整套服务由于依赖了一些自研发的根据内部场景定制的服务治理等工具,暂时没有对外开源。考虑在Gopher China之后进行开源。

需求分析

  1. 如何做到让公司的所有子系统,微服务中涉及的异步任务能够可衡量,可控制,使用成本低,科学扩容,并且扩容对业务透明。

  2. 如何让异步任务更方便调试,从加入,消费,处理,都能够显示的给出,出现的问题报错也能显示的说明。

  3. 能够让公司所有业务统一接入,统一管理,而不是分别构建很多子队列系统,分开运维,监控。

  4. 对PHP业务要友好,公司的主要线上队列服务使用php,用法是基于php的配置管理+进程管理框架(processWorker)+redis,能快速替换该方案,否则推广是一个问题。(当然现在java,golang也占一部分)

Pepperbus设计

基于以上需求,我们展开对总线队列的设计。

  1. 首先存储选型,大趋势来说,肯定是插件化的,无论提供什么样底层存储,应用层提供统一接口。这一点设计上上很容易做到。

  2. 第二,入口的通信协议,一定要对调用端友好,因为团队并不想花很多时间,去实现各个语言的总线sdk,所以入口协议我们选择了redis协议,无论长连接还是短连接,连接池,异常处理等细节在各种语言上已经很完备了,只需在逻辑层简单封装即可。既数据生产(add job),采用redis协议。

  3. 最后,最重要的就是任务管理,一种模式是开进程,消费总线使用的存储中的数据,过程计时打点,同时总线系统提供必要的进程管理功能(SDK).因为我并不想让业务接入各种数据打点的sdk,想从总线上直接获取第一手的数据采集,针对php的场景,很自然想到了,能否直接与fastcgi进行通信,通信的响应时间,其实就是对于任务的处理时间,同时基于这种方式,可以直接享受到php-fpm可以动态的更新代码的红利。我们异步任务的脚本,也能平滑动态进行更新。当然后期针对fpm的数据转发和通信,包括php-fpm和脚本各种执行时间的配置,我们有过不少的挫折,但后来都迎刃而解。团队之前本身也是负责360的长连接相关技术,对于网络的处理还是有一定的经验的~

  4. 最后就是针对其他语言,直接提供http接口的任务转发。这样一来,方便debug这一条需求也能覆盖住,其实后续所有的异步任务,对于订阅者来说,都是从post请求等获取,理论上本地可以通过curl命令调试异步任务。当然我们提供了一个丰富的dashboard可以完成这个工作,并且测试环境可以获取历史数据,进行重放,减少大家构建请求的时间。不要惊奇,只要sdk控制好超时,用什么协议传数据,都是无所谓的。

  5. 业务驱动的Dashboard,队列增删查改,trouble shooting,重放,报警,监控。重新封装一套总线服务的目的,就是要解决业务痛点,最大程度的减少使用复杂度,提供更多有意义的信息。项目成功这一非硬核环节很重要。要好用,要好用,要好用。

系统架构图

架构描述

  1. 业务服务器可以与bus总线实例混合部署也可以独立部署,混合部署时可以优先访问本地总线服务器,独立分离部署可以与总线服务用域名进行通信

  2. 总线服务器与php-fpm交互可以通过本地也可以通过网络

业务处理流程图说明

  1. 业务服务器将任务加入到总线服务

  2. 总线服务存储任务到存储

  3. 将总线任务传输给cgi进程

  4. cgi进程返回处理结果

  5. 总线移除处理任务

  • 业务服务器可以与bus总线实例混合部署也可以独立部署,混合部署时可以优先访问本地总线服务器,独立分离部署可以与总线服务用域名进行通信

  • 总线服务器与php-fpm交互可以通过本地也可以通过网络

  • 总体架构图:

pepper_bus_overview

整体架构图

调用部署

pepper_bus_overview_1

项目依赖的其他组件

  • dashboard: 提供用户管理的web ui。

  • gokeeper: 提供配置管理服务。

用户使用演示

产品需求走查

1. 后台整体情况,可以按系统进行区分

2. 队列列表管理

3.队列实时监控,可以进行重放清理等设定,新版已经支持灰度重放等。同时会实时显示请求延时,如图:第一列90%的请求在2146ms内完成。

4.显示错误日志查看,可以定位到具体消息id,如果php报错,也会正常展示。

5.方便的测试dashboard,可以将测试历史数据和本地保存的线上历史数据,直接加入bus,拿到异步处理结果

6. 对集群使用的存储进行监控(目前支持pika和redis),扩容对业务透明

最后感谢整个花椒系统开发团队,弟兄们都很给力,用不到一个月时间完成了总线核心的开发。

github:

@youlu-cn 

@specode 

@qudexin1986

@johntech-o

也许你还会喜欢:

  • GO vs PHP ,谁更适合创业公司的中台搭建?

重磅活动预告

Gopher Meetup 北京站即将开启。来自探探、美团、阿里巴巴、蚂蚁金服的大咖讲师讲带来 Go 开发领域的一线实践经验分享,尽在11月30日,IFC国际财源中心!

Go中国

扫码关注

国内最具规模和生命力的 Go 开发者社区

欢迎投稿,请联系:

situzhihui@163.com

这篇关于Golang实践之花椒直播总线系统的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/471182

相关文章

golang版本升级如何实现

《golang版本升级如何实现》:本文主要介绍golang版本升级如何实现问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录golanwww.chinasem.cng版本升级linux上golang版本升级删除golang旧版本安装golang最新版本总结gola

Spring WebFlux 与 WebClient 使用指南及最佳实践

《SpringWebFlux与WebClient使用指南及最佳实践》WebClient是SpringWebFlux模块提供的非阻塞、响应式HTTP客户端,基于ProjectReactor实现,... 目录Spring WebFlux 与 WebClient 使用指南1. WebClient 概述2. 核心依

MyBatis-Plus 中 nested() 与 and() 方法详解(最佳实践场景)

《MyBatis-Plus中nested()与and()方法详解(最佳实践场景)》在MyBatis-Plus的条件构造器中,nested()和and()都是用于构建复杂查询条件的关键方法,但... 目录MyBATis-Plus 中nested()与and()方法详解一、核心区别对比二、方法详解1.and()

Spring Boot @RestControllerAdvice全局异常处理最佳实践

《SpringBoot@RestControllerAdvice全局异常处理最佳实践》本文详解SpringBoot中通过@RestControllerAdvice实现全局异常处理,强调代码复用、统... 目录前言一、为什么要使用全局异常处理?二、核心注解解析1. @RestControllerAdvice2

golang中reflect包的常用方法

《golang中reflect包的常用方法》Go反射reflect包提供类型和值方法,用于获取类型信息、访问字段、调用方法等,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值... 目录reflect包方法总结类型 (Type) 方法值 (Value) 方法reflect包方法总结

Spring事务传播机制最佳实践

《Spring事务传播机制最佳实践》Spring的事务传播机制为我们提供了优雅的解决方案,本文将带您深入理解这一机制,掌握不同场景下的最佳实践,感兴趣的朋友一起看看吧... 目录1. 什么是事务传播行为2. Spring支持的七种事务传播行为2.1 REQUIRED(默认)2.2 SUPPORTS2

Java中的雪花算法Snowflake解析与实践技巧

《Java中的雪花算法Snowflake解析与实践技巧》本文解析了雪花算法的原理、Java实现及生产实践,涵盖ID结构、位运算技巧、时钟回拨处理、WorkerId分配等关键点,并探讨了百度UidGen... 目录一、雪花算法核心原理1.1 算法起源1.2 ID结构详解1.3 核心特性二、Java实现解析2.

MySQL 中 ROW_NUMBER() 函数最佳实践

《MySQL中ROW_NUMBER()函数最佳实践》MySQL中ROW_NUMBER()函数,作为窗口函数为每行分配唯一连续序号,区别于RANK()和DENSE_RANK(),特别适合分页、去重... 目录mysql 中 ROW_NUMBER() 函数详解一、基础语法二、核心特点三、典型应用场景1. 数据分

Golang如何对cron进行二次封装实现指定时间执行定时任务

《Golang如何对cron进行二次封装实现指定时间执行定时任务》:本文主要介绍Golang如何对cron进行二次封装实现指定时间执行定时任务问题,具有很好的参考价值,希望对大家有所帮助,如有错误... 目录背景cron库下载代码示例【1】结构体定义【2】定时任务开启【3】使用示例【4】控制台输出总结背景

Golang如何用gorm实现分页的功能

《Golang如何用gorm实现分页的功能》:本文主要介绍Golang如何用gorm实现分页的功能方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录背景go库下载初始化数据【1】建表【2】插入数据【3】查看数据4、代码示例【1】gorm结构体定义【2】分页结构体