本文主要是介绍(一)从零到一:设计通用型埋点方案的实践与思考,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
引言
埋点,顾名思义即是在业务代码逻辑中上报某一标识和该标识相关的数据,与业务流程解耦,用于监控或者数据分析。在现代软件开发中,埋点已成为优化用户体验、支持业务决策的关键工具。
本文将从「业务需求初期设计埋点」到「后期重构」的角度,阐述如何设计通用型的埋点方案,希望能为读者提供实用的参考和避坑指南。
1. 起步阶段:初始埋点设计
1.1 业务流程
在业务发展初期,我们的流程相对简单,主要包含两个阶段:stage1和stage2。我们需要记录这两个阶段的耗时、结果,以及整个流程的总耗时。
1.2 数据结构设计
为了存储埋点数据,我们在数据库中设计了如下的数据表结构:
字段 | 类型 | 说明 |
---|---|---|
id | bigInt | 数据库主键 |
business_id | bigInt | 业务ID |
stage1_time | int | 阶段1处理时长(单位:毫秒) |
stage1_success | int | 阶段1是否成功,枚举值:1:成功、0:失败 |
stage2_time | int | 阶段2处理时长(单位:毫秒) |
stage2_success | int | 阶段2是否成功,枚举值:1:成功、0:失败 |
answer_success | int | 请求是否成功(超时或者异常视为失败,返回即算成功),枚举值:1:成功、0:失败 |
这种设计简单直接,适合初期业务规模较小时使用。
2. 业务发展带来的挑战
2.1 架构变化
随着业务发展,我们采用了链路编排的方式执行请求。整个流程由多个node节点组成,每个node节点包含多个handler执行器,按照不同的策略类型处理具体的业务逻辑。
2.2 埋点方式的调整
考虑到埋点不在核心业务链路上,我们采用了事件驱动的异步上报方式记录埋点信息,但仍然使用MySQL数据库存储。
2.3 数据结构的膨胀
随着链路编排节点的增多,埋点数据也随之增加。新的数据结构变得更加复杂,包含了更多的监控参数:
字段 | 中文解释 | 归类 |
---|---|---|
businessId | 业务ID | 业务基础参数 |
question | 问题 | |
answer | 最终答案 | |
qa_intervals | 调用总时长 | |
answer_success | 调用是否成功 | |
dialog_time | 对话时间 | |
traceId | 追踪ID | 监控基础参数 |
userIP | 用户IP | |
serverIP | 服务器IP | |
fail_reason | 失败原因 | |
stage1_start_time | 阶段一开始时间 | 阶段一监控参数 |
stage1_end_time | 阶段一结束时间 | |
stage1_answer | 阶段一答案 | |
stage1_time | 阶段一时长 | |
stage1_success | 阶段一是否成功 | |
stage2_start_time | 阶段二开始时间 | 阶段二监控参数 |
stage2_end_time | 阶段二结束时间 | |
stage2_response_time | 阶段二响应时间 | |
stage2_answer | 阶段二答案 | |
stage2_time | 阶段二总时长 | |
stage2_success | 阶段二是否成功 |
2.4 现有方案的局限性
此时,大家可以明显发现,随着业务发展,编排节点增多,埋点数量呈现线性增长,如果继续采用这种数据结构存储,每在编排中接入一个节点到埋点中,数据表就新增若干个字段,这是最直接的致命缺点,数据表将野蛮无限增加字段。
现有方案有以下缺点:
- 数据表字段呈线性增长,每增加一个编排节点就需要新增多个字段,不可持续。
- 监控代码侵入业务逻辑,难以适应流程编排的灵活性。
- 数据库字段设计不通用,链路节点记录不详细,难以快速定位问题。
- 链路监控无法降级,难以应对高流量场景(如618/双十一大促)。
- 事件驱动异步方式可能存在性能瓶颈,未经过压测验证。
代码参考:
3. 重构:设计新的埋点方案
3.1 埋点的定位与要求
在设计新方案前,我们明确了全链路埋点的定位:
(1)链路闭环:监控埋点虽与外部存在调用关系,但调用逻辑和链路编排由自身控制,可自己形成闭环,无需第三方回执确认
(2)用户群体:链路埋点面向产研和运营观看数据,不对外面向商家和用户使用。
(3)大促降级:埋点监控不影响主流程执行,不侵入业务逻辑代码,尽最大努力保证埋点记录。但必要情况下,可通过细粒度开关和全局开关进行埋点降级,影响是数据看板和数据分析会缺失降级后的数据。
(4)快速定位问题:埋点监控需要记录详细的调用留痕,链路编排存在多个node节点,每个node节点会存在一个或多个handler,埋点监控需要记录到handler级别,且每一步发生的错误和异常需要记录,且留存现场,方便排查。
(5)数据分析:可供运营、产品进行多指标数据分析,如耗时、成功率、PV、UV等。
3.2 新方案设计
基于以上定位和之前方案的缺点,我们设计了新的埋点方案:
- 流程编排自动/手动上报:
- 利用node编排时自动在handler执行前后进行埋点上报。
- 保留手动上报入口,以应对特殊情况。
- 异步上报:
- 通过消息队列(MQ)统一发送和消费,利用MQ的积压和并行消费能力实现异步解耦。
- 数据存储:
- 使用Elasticsearch按季度创建索引模板。
- 只保留近6个月数据,每日离线推送至大数据平台备份。(假设每条请求对应20条链路日志,每日用户提问1W条,每日链路日志总数则为20W条,每季度约1800W)
3.3 新的数据结构
新方案采用通用字段设计,实现横向扩展而非列向扩展:
中文说明 | 字段 | 说明 |
---|---|---|
接入方式 | accessType | |
接入系统 | accessSystem | |
追踪ID | traceId | |
业务ID | businessId | |
埋点标识(如类名) | eventTrackSign | 唯一标识当前埋点 |
埋点状态 | eventTrackStatus | 开始、结束或为空 |
节点类型 | handlerType | 枚举:串行、并行 |
节点超时设置 | handlerTimeOut | |
埋点结果 | eventTrackResult | 枚举:成功、失败 |
失败原因 | failReasonCode | 枚举:code码 |
现场信息 | context_info | |
埋点类型 | eventTrackType | 枚举:手动、自动 |
时间 | time | 毫秒级时间戳 |
新方案与旧方案相比有很多优点,对比如下:
方面 | 旧方案 | 新方案 |
---|---|---|
扩展性 | 列向扩展,字段增长快 | 横向扩展,通用字段设计 |
灵活性 | 固定字段,难以适应业务变化 | 通用字段,易于适应不同业务场景 |
性能 | 可能存在性能瓶颈 | 使用MQ和Elasticsearch,性能更好 |
数据分析 | 直接查询即可 | 需要额外的数据处理步骤,但更灵活 |
降级能力 | 无 | 支持细粒度和全局降级 |
问题定位 | 难以快速定位问题 | 详细记录每个handler,易于问题定位 |
代码侵入性 | 高,散布在业务逻辑中 | 低,主要通过自动上报实现 |
存储成本 | 随业务增长线性增加 | 通过定期清理和离线备份控制成本 |
到这里,重构后的方案就介绍完了,这里有一点值得注意,新的数据结构由于是通用字段设计,对于原始数据需要多一步数据处理的步骤进行数据分析与统计,不过这并不是太大问题,只要有原始数据存在,就可以针对业务所需要的数据指标做灵活的聚合统计。
4. 结论和最佳实践
经过从初始设计到系统重构的全过程,我们总结出了以下几点关键的最佳实践,希望能为同行提供有价值的参考:
- 设计通用字段 通用字段设计是提高埋点系统灵活性和可扩展性的关键。它让我们能够适应不断变化的业务需求,而不必频繁修改数据结构。
- 异步解耦 利用消息队列进行异步上报是一个明智之选。这不仅能显著减少对主业务流程的影响,还能提高系统的整体性能和稳定性。
- 分层存储策略 采用Elasticsearch进行实时存储,辅以大数据平台进行离线备份,是一种平衡查询性能和存储成本的有效方法。这种策略让我们能够快速检索近期数据,同时保证长期数据的完整性。
- 推进自动化埋点 尽可能实现自动化埋点,可以大幅减少代码侵入性。这不仅提高了开发效率,还降低了人为错误的可能性。
- 预留降级机制 为高流量场景预留降级开关是非常必要的。这确保了在极端情况下,核心业务不会受到埋点系统的影响,从而保证了整体服务的可靠性。
- 全面详细的记录 记录足够详细的信息是快速定位和解决问题的基础。在实践中,我们发现全面的日志记录能够大大缩短问题排查的时间。
- 定期评估与优化 随着业务的不断发展,定期评估埋点系统的效果和性能变得尤为重要。我们建立了一个季度评估机制,确保埋点系统能够及时进行优化和调整。
通过这次从初始设计到重构的过程,我们不仅解决了当前面临的问题,还为未来的业务扩展奠定了坚实的基础。这个过程让我们深刻认识到,一个优秀的埋点系统应该是灵活的、高效的、可扩展的,同时又不应该对主业务造成明显影响。
感谢阅读~
感谢大家的观看!!!创作不易,如果觉得我写的好的话麻烦点点赞👍支持一下,谢谢!!!
相关文章已在掘金发布,体验更佳!!
这篇关于(一)从零到一:设计通用型埋点方案的实践与思考的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!