从非功能性需求角度看 dynamic tracing, static tracing, error logging 和 domain event

175 阅读3分钟
从功能性的角度来说,这四个东西可以抽象为一个概念:“event”。他们都提供了 observability这样的能力。但是从非功能性的角度来说,却又很多的不同。

什么是 dynamic tracing

所谓dynamic tracing,就是在写这段代码的时候并没有想好要跟踪哪些东西。所以dynamic tracing就是补丁,在层与层的连接处插入截获代码,从而实现dynamic tracing。这里的埋点实际上就是对下层的函数调用。

实现技术:机器码改写插入,比如gdb插入中断指令

实现技术:lib替换,比如 ltrace

实现技术:字节码改写,比如jvm上aop实现

实现技术:tcpdump

什么是 static tracing

程序员在写代码的时候主动加的埋点。参见:Hacking Linux USDT with Ftrace

实现技术:system tap 机器码 NOP 留白

实现技术:dtrace USDT 机器码 NOP 留白:USDT Providers Redux

实现技术:statsd,相当于udp消息队列作为了ring buffer

什么是 error logging

Basics of the Unix Philosophy
One of Unix's oldest and most persistent design rules is that when a program has nothing interesting or surprising to say, it should shut up. Well-behaved Unix programs do their jobs unobtrusively, with a minimum of fuss and bother. Silence is golden.

只在真正出错 ,需要人工介入定位问题的时候才输出error log。每天error log就是一个给rd/op的工单。是从自动化流程分叉出人工介入的流程的起点。

什么是 domain event

类似”订单下单“,”行程结束“这样的事件消息,通过kafka这样的消息管道,把业务功能”异步“地组装到了一起完成了一个业务流程。domain event是自动化流程的衔接方式之一(另外一种是同步rpc)。

非功能性挑战

dynamic tracing:可丢,使用ring buffer。从api调用到cpu指令数,各个层面都可以trace,非常海量。越底层的api的dynamic tracing,越是只能按需开启,无法常态化。随着机器越来越快,很多之前无法常态化开启的统计,现在也可以了(比如常态化tcpdump,监控mysql)。一般只提供计数和延迟分布的统计。非功能性挑战主要是尽可能低的消耗。

static tracing:可丢,使用ring buffer。业务主动加的埋点。对于本层添加的埋点(比如你是电商业务,同时使用了mysql。mysql里的埋点就是跨层埋点,而你自己添加的”反作弊命中了“这样的埋点就是本层埋点)一般来说可以做到全开。比dynamic tracing会多非常多的维度信息(比如城市,客户属性,订单类型等等),需要多维分析和统计的能力。一般除了提供计数和延迟分布之外,还会加一下uv统计,占比之类的特殊聚合。现在很火的rpc链路追踪就是static tracing,只是除了统计之外,还提供采样或者全量的逐条的详情。


error logging:尽量不丢,使用持久化的ring buffer(一般实现是日志文件rotation)。需要逐条的详情信息。能够处理异常情况下的突增(预留容量,选择性丢弃)。错误日志本身也是一种static tracing。但不是所有的static tracing都是error logging。如何做到统计和详情之间的关联也是很大的挑战。

domain event:不能丢,和业务rpc做到可用性绑定。如果写入event失败,则rpc处理失败。比如你基于订单已下单的事件做金额返还,哪怕只有万分之一的差错率。对于每天一千万单来说,也是每天一千个潜在用户会打电话投诉。这个对于客服来说是不可承受的工作压力。

落盘日志文件作为常见的error logging的通道,很难满足domain event的不可丢需求,也很难满足static tracing的数据量和选择性的需求,更加无法满足dynamic tracing的需求。