下午15:17的那场故障
下午15:17,正值交易高峰期,支付核心链路P99延迟从80ms飙升至2.3s。
用户投诉如潮水涌入,监控大盘却一片"正常"------因为CPU小于70%,内存小于80%,HTTP 5xx错误率小于0.1%。
这就是没有可观测性的代价:系统在崩溃,而你一无所知。
在金融行业,我们无法承受这种"盲跑"。可观测性,不是可选项,而是生存底线。为什么需要可观测性?本质上就是人类想要掌控系统的健康状况。工程师总是担心系统不可用,为了掌控系统,所以可观测性应运而生。就好比中医的望闻问切,来判定一个人的健康状态一样。只能看到各项指标正常,才能比较放心,晚上才能睡个安稳觉。
可观测性的三大基石
那问题来了,怎么判断系统可观测呢?业界公认的三大基石:日志、调用链、指标。咱们一个一个聊。
日志:最原始但也最真实
日志本来是散落在各个系统之间的,最原始的方式是什么?tail、cat、grep、awk这些老古董。你得一台服务器一台服务器登录进去,手工翻日志。
但这太分散了,根本不利于操作。你想想,线上几十台甚至上百台服务器,出了问题你怎么找?来回切屏幕切到眼花,还容易漏掉关键信息。
所以需要把它们收集到一起。这时候Filebeat、Logstash就派上用场了,它们负责收集、转换、格式化日志,最后写到Elasticsearch的索引里。再开发一个界面来管理这些索引,维护它们的归档、查询等工作------这个界面就是Kibana。
说实话,刚开始用ELK的时候,我也觉得麻烦。又要装Filebeat,又要配Logstash,索引还得规划。但用习惯了之后,你会发现真香。出问题时,在Kibana里输入个关键字,几秒钟就能把相关日志全捞出来,比以前效率高太多了。
金融级挑战:从关键词到规则的跨越
但在金融场景,普通的日志查询很快就遇到瓶颈了。支付失败可能表现为"余额不足""风控拦截""渠道超时""账户冻结""限额超限"等数十种语义,你不可能把所有关键词都记住。
我们的解决方案是:通过结构化日志加业务状态码标准化,将"支付异常"抽象为统一字段。比如所有支付相关的错误,都必须包含errorCode、errorType、bizType这些标准字段,这样规则就可以复用了。
同时,金融系统对日志合规性要求极高。所有涉及资金流转的操作,日志必须保留至少5年,而且要能随时审计。这就要求我们在日志采集的最开始,就做好分类、脱敏、归档的规划,不能事后补救。
调用链:给请求装个GPS
微服务时代,一个请求的生命周期变得特别复杂。从用户点击按钮开始,请求可能经过Nginx、业务网关、微服务前台、微服务中台、各种中间件,最后才返回结果。这一条逻辑线是否正常、性能如何,得有办法追踪啊。
因此从流量入口(东西流量)进入系统大门开始,就需要给它打个标记。这个标记叫TraceId,而且要尽可能早地生成。同时要采集你能想到的各种信息:PC还是手机端、uid、ip、设备号、时间、请求报文等等。
这个TraceId会穿透整个微服务系统。为了更精细化,还需要在每个微服务模块中增加SpanId(南北流量)。每一次请求,我们巴不得从Nginx、业务网关、微服务前台、微服务中台、中间件,到最后的返回信息(成功、失败、http状态码、业务状态码、业务报文),都装上透视眼。
这里也产生了很多工具,比如早期大众点评的Cat,现在字节码增强的Agent工具,最典型的就是SkyWalking了。
有了调用链之后,你在SkyWalking里看报表,跟踪慢接口,一目了然。哪个环节慢了?是数据库查询的问题,还是第三方接口超时?一查便知。
金融级挑战:TraceId的全链路保障
但在金融场景,调用链有个致命问题:TraceId透传在异步线程、消息队列消费、定时任务中极易断裂。
你想想,一笔支付请求进来,可能触发异步风控校验、发送MQ通知、定时对账任务。如果TraceId在某个环节断了,整条链路就追踪不下去了。出了问题,你连完整的调用路径都看不到,怎么排查?
我们的解决方案是改造SkyWalking Agent,强制在MDC(Mapped Diagnostic Context)中注入bizId加traceId。不管是主线程还是异步线程,不管是HTTP调用还是MQ消费,都必须携带这两个标识。这样一来,哪怕是跨了三天的异步对账任务,我们也能追溯回当初的那笔交易。
金融系统还有个特点:资金流必须百分百可追溯。监管部门随时可能要求你提供某笔交易的完整调用链,从用户发起请求,到最终扣款成功,中间经过了哪些系统、哪些节点,每个节点的耗时多少,都要清清楚楚。这不是"最好有",而是"必须有"。
指标:从微观到宏观的跨越
有了日志和调用链,够了吗?
没有!
你可以在Kibana查日志,在SkyWalking看调用链,但这还是太微观了。它们回答不了一些更感性的问题:
系统健康吗?调用慢不慢?有没有异常?哪个系统有异常?什么原因?多长时间能恢复?怎么恢复?
解决了一次又一次线上故障后,你还会进一步提问:下次能提前知道吗?有没有自动巡检功能?能不能先于用户发现,降低影响面?能不能一经发现,很快就能恢复?
为了解决这些问题,就需要规则。怎么制定规则?对了,指标就要上场了。
指标本质上是时间维度的一个原子化的度量。比如说,某台服务器的某一刻,CPU利用率多少、内存占用大不大、网络IO多不多、磁盘空间如何?这就是Google提出的USE方法论------四大度量。
这是最基本的一些指标,每一台服务器都需要安装。当每一台服务器都安装了这些指标采集器后,这些数据会汇总到Prometheus中。Prometheus是一个时间序列的指标存储、查询工具。
拉模式还是推模式?这不是技术问题
Prometheus采用的是拉模式,固定时间比如15秒采集一次。
为什么是拉,而不是推?很多文章没有讲清楚,我告诉你,本质上不是技术的原因,是业务的原因。
第一,推的话你是一个指标一个指标地推,零零散散。
第二,业务上需要一个不间断的时间区间,才能画出图形或者制定规则。
所以拉模式一次性取出若干指标,而且时间间隔能够得到保证。想象一下,你要画一条CPU使用率的曲线,如果数据点时断时续,这图还怎么看?
为了监控,每台服务器都需要安装Exporter(导出器),然后Prometheus统一进行拉取并装进它的TSDB时间序列存储里。
Grafana:让数据会说话
进入Prometheus后,又是个黑盒?怎么办?别急,有Grafana!
很多优秀的工程师都提供了Node-Exporter的Grafana模板,界面很科技、很炫,看上去很牛逼。但在我看来,炫不炫不是重点,功能也并没有增加多少,也仅仅是能够看清某一时刻服务器的状态而已。
Grafana的真正价值在于:它是故障出现后的分析平台,是故障发生时的报警依据。你可以在上面设置各种Dashboard,监控不同维度的指标,一旦数据异常,立马就能发现。
金融级挑战:秒级交易下的监控盲区
但Prometheus默认15秒采集一次,在金融场景下有个大问题:盲区太大。
金融系统是秒级交易,高峰期一秒钟可能有几千笔订单。15秒的采集间隔意味着什么?意味着中间可能有几万笔交易,你完全看不到。如果在这个盲区内出现了短暂的流量尖刺或者性能抖动,等到下一次采集时,问题可能已经过去了,但用户已经受影响了。
我们把核心服务的指标采集频率提升到2秒一次。别小看这个改动,对存储和计算的压力是成倍增加的。但没办法,金融系统容不得盲区。
还有一个更隐蔽的问题:固定阈值告警在金融场景下经常误报。比如你设置"交易量每分钟超过10000就报警",听起来合理吧?但双十一零点、发工资日、节假日,交易量本来就会暴涨,这时候报警就是误报。
我们引入了动态基线告警:系统会自动学习历史数据的波动规律,计算出每个时间段的正常基线。只有当实际值显著偏离基线时,才触发报警。这样一来,市场正常波动不会误报,真正的异常却能及时发现。
重头戏来了:报警!
好了,经过这么多铺垫,终于可以讲到重头戏了------报警!
报警怎么报?想一想,系统由多台服务器组成,由多个中间件组成,有数据库、缓存、文件系统、网关、容器化、分布式调度、服务治理等等。某一个系统出现亚健康或者不可用,就需要报警。
报警分级:红黄蓝三色体系
我们在实践中总结出了一套分级体系:
红色报警:中间件或者虚拟机宕机类,要立即处理。比如数据库挂了、Redis不可用了、核心服务宕机了。这种情况不能等,必须马上响应。这对应的是资金损失风险,影响交易能不能完成。
黄色报警:性能跟不上了,IO流量过大、CPU利用率高、内存上升快,要尽快处理。这种还没到生死存亡的地步,但也不能拖太久。对应的是用户体验受损,交易变慢、响应变慢。
蓝色报警:磁盘涨幅过大,预计3天后就满了,要清理或者加磁盘,要安排后处。这种属于预警,给你时间从容处理。对应的是运维成本上升,提前规划资源。
以上是运维需要关注的硬件、中间件指标。
业务报警:更贴近实际场景
还有业务系统要注意的:接口过慢、数据库慢查询、微服务宕机了,怎么发现这些问题?
往往都散落在日志、调用链、指标里,但需要工程师根据日常工作去抽象。比如:
- 日志中包含"支付异常"
- HTTP接口产生500错误
- HTTP请求超过3秒
- 数据库慢SQL
抽象出这些规则后,对它们进行统一的报警。
自研报警引擎:为什么要自己造轮子?
在日志、调用链、指标这三类基础设施之外,还需要开发一套报警引擎。
AlertManager也可以用,但不够定制化。比如我们需要:
- 避免重复处理:同一个问题别反复报
- 处理报警毛刺:偶尔抖动一下不算故障
- 报警收敛:同一类问题合并通知
- 分级通知:红色报警打电话,黄色报警发短信,蓝色报警发邮件
- 值班轮转:自动分配责任人
- 升级机制:超时未处理自动升级
报警的开发,绝对不是可有可无的。没有它,你就没办法回答系统是否健康、是否能正常运转,没办法巡检。夸张点说,你睡觉都不踏实。
我们的实践成果:金融级可观测性的效果验证
我服务的公司是一家金融企业,对各项要求都比较高。我们自研了一套报警系统,经过两年多的迭代优化,取得了比较明显的效果。
先看几个关键数据:
| 指标 | 优化前 | 优化后 | 提升幅度 |
|---|---|---|---|
| 故障发现时间 | 15分钟 | 3分钟 | 降低80% |
| 报警误报率 | 35% | 低于5% | 降低85% |
| 核心链路覆盖率 | 60% | 100% | 提升40% |
| 自动恢复率 | 20% | 60% | 提升3倍 |
这些数字背后,是无数个深夜的故障复盘,和对"规则"的极致打磨。
具体来说:
覆盖范围:
- 各类中间件10多项(MySQL、Redis、Kafka、RabbitMQ、Elasticsearch等)
- 监控虚拟机300多台
- 每天处理上万条报警规则
核心能力:
- 报警收敛:同一类问题合并通知,避免报警风暴
- 毛刺过滤:短暂抖动不触发报警,减少误报
- 分级通知:红色报警打电话,黄色报警发短信,蓝色报警发邮件
- 值班轮转:自动分配责任人,清晰责任边界
- 升级机制:超时未处理自动升级到上级
这套系统是我们团队一点一点摸索出来的。踩过很多坑,比如一开始报警太频繁,运维同学的手机一天到晚响个不停,后来加了收敛机制才好转。也试过报警规则设置得太宽松,结果真出问题时没及时发现,导致故障扩大。
写在最后:从经验到能力的跨越
我发现现在讲可观测性这块内容的人不多,要么讲得很零散,要么不够落地。所以我想把我的工作实践,结合金融企业的实际场景,把怎么想的、怎么做的、达到了什么效果,毫无保留地脱敏后分享出来。
可观测性不是买几个工具就能解决的,它需要你对业务的深刻理解,对系统的全面把控,和一次又一次故障中积累的经验。
但更重要的是:把经验沉淀为规则,把规则固化为系统,把系统转化为能力。
这,才是金融级可观测性的真正护城河。
希望这篇文章能帮助大家理清可观测性的大局观,知道在实际工作中方方面面该怎么处理。如果你也在做可观测性相关的工作,欢迎一起交流探讨。