惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

V2EX - 技术
V2EX - 技术
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
T
Threat Research - Cisco Blogs
T
The Exploit Database - CXSecurity.com
S
Schneier on Security
S
Securelist
P
Privacy & Cybersecurity Law Blog
Scott Helme
Scott Helme
T
Threatpost
C
Cybersecurity and Infrastructure Security Agency CISA
L
LINUX DO - 热门话题
Cyberwarzone
Cyberwarzone
Cisco Talos Blog
Cisco Talos Blog
量子位
博客园 - Franky
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Latest news
Latest news
T
Troy Hunt's Blog
N
News | PayPal Newsroom
Google Online Security Blog
Google Online Security Blog
Apple Machine Learning Research
Apple Machine Learning Research
N
Netflix TechBlog - Medium
小众软件
小众软件
P
Palo Alto Networks Blog
Spread Privacy
Spread Privacy
C
Cyber Attacks, Cyber Crime and Cyber Security
C
Check Point Blog
aimingoo的专栏
aimingoo的专栏
WordPress大学
WordPress大学
L
Lohrmann on Cybersecurity
L
LINUX DO - 最新话题
D
Darknet – Hacking Tools, Hacker News & Cyber Security
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
The Last Watchdog
The Last Watchdog
S
Security @ Cisco Blogs
P
Privacy International News Feed
Last Week in AI
Last Week in AI
Microsoft Security Blog
Microsoft Security Blog
T
Tailwind CSS Blog
博客园_首页
云风的 BLOG
云风的 BLOG
V
Vulnerabilities – Threatpost
D
DataBreaches.Net
Recent Announcements
Recent Announcements
酷 壳 – CoolShell
酷 壳 – CoolShell
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
罗磊的独立博客
Engineering at Meta
Engineering at Meta
Forbes - Security
Forbes - Security
T
Tenable Blog

卡瓦邦噶!

服务器高性能网络调优 | 卡瓦邦噶! 为何写作 | 卡瓦邦噶! 读《金阁寺》 | 卡瓦邦噶! 雨季又来 | 卡瓦邦噶! MTU Probe 引起的初始延迟 | 卡瓦邦噶! 3.5 秒的固定延迟问题 | 卡瓦邦噶! 学习网络的一点经验 | 卡瓦邦噶! ARP 问题诊断 | 卡瓦邦噶! 网络断断续续…… | 卡瓦邦噶! Piccolo P2P 镜像分发 | 卡瓦邦噶! 一起看电影 | 卡瓦邦噶! 《征服C指针》 | 卡瓦邦噶! 我的姥姥 | 卡瓦邦噶! Python的哲学 Python 3.5的新特性 学校不教的计算机课 垃圾回收(GC)的三种基本方式 在编程中体验纯粹的快乐 从《美丽新世界》谈自由 在快钱实习 迷人的嗓音和迷人的故事——《Sleepyhead》 Python 的十个自然语言处理工具 记一个愚蠢的bug 一年炉石传说的游戏体验 《以撒的结合:重生》网页版图鉴 分清 C++的指针、引用和数组 笑话三则 自由比皇帝更伟大——《悲惨世界》笔记 Git 10 周年访谈:Linus 讲述背后故事 用 0x3f3f3f3f 设定最大int值的优点 Joel给计算机系学生的建议 一个词法分析器的简单实现 怎样才算健康的生活方式 MacVim 配置攻略 学习培训课程的视频效果好吗? 语言的控制 可悲的大多数 CSS样式思维导图 2014年终总结 奥巴马成为首位写程序的美国总统 青岛老城区的下水道好在哪里? 做优秀 UI 的七个建议(第二部分) 选择爱情的骑士 Git简明教程 Java集合总览 读 《1984》 java问答:终极父类(六)——等待/唤醒和接口 Java 问答:终极父类(五)——toString() Hyperlapse快速视频背后的技术细节 平庸之恶 Java程序员须知的七个日志管理工具 苏州 逛书摊随想 关于考试作弊 你的工作不仅仅是编程 推荐在线学习Java的英文资源 关注女性命运——《千禧年三部曲》 用好你的幻灯片——《演说之禅》 使用ReentrantLock和Lambda表达式让同步更纯净 新手学编程,从哪里开始? 程序员都是工程师吗? 不要学习代码,要学会思考 Java 问答:终极父类(四)——hashCode() Java 问答:终极父类(三)——finalize()和 getClass() 程序员职业之路的选择 我是一名摄影家 写给何小树的城市指南 为什么一些语言会比别的快? Java的常见误区与细节 跟朋友在一起玩游戏 死神永生——读《三体》 五种类型的程序员 创业圣经——读《黑客与画家》 纪念加西亚·马尔克斯 Junit中处理异常的另一种方式:catch-exception Java8采用Martin Fowler的方法创建内部DSL Linux HotSopt虚拟机GC线程的CPU占用率 J2EE概念介绍 如何成为一名黑客 Java 问答:终极父类(二)——equals()方法 为什么我喜欢Java Java 问答:终极父类(一)——clone()方法 七个改变世界的Java项目 java中默认类型转换的小问题 传统与创新 欢迎来到互联网 莫言和马尔克斯——读《生死疲劳》 位运算的妙用 读《人为什么活着》 写博客教会我的事情 中国特色操作系统 2013年总结 《永不妥协》影评 恨不相逢未嫁时——《廊桥遗梦》影评 如何优雅地使用PPT 给明年依然年轻的我们 天才与柱子 黑客守则和黑客精神 Looking for Freedom——《被解救的姜戈》 简洁之道
最近的工作感悟
laixintao · 2021-06-24 · via 卡瓦邦噶!

我在 Shopee 维护一个 Service Mesh 系统,大部分的 RPC 调用要经过这个系统,这个系统每分钟要处理上千万的请求。我们在本文中就把它叫做 Oitsi 系统吧,方便描述一些。干的事情其实和 Istio 是差不多的。

Oitsi 将对 RPC 调用设置了很多错误码,类似于 HTTP 协议的 404, 502 等等。Application 报出来的错误码在一个区间,Oitsi 内部产生的错误在另一个区间,比如 0-1000,类似于 System Internal Error. 监控这些错误码可以让我们知道这个系统的运行情况。

这个系统自从接手之后就有一个问题,就是它每时每刻都在报出来很多内部错误,比如发生内部超时,路由信息找不到,等等,每分钟有上万个错误。然而,系统的运行是完全正常的。

Oitsi 系统在正常情况下的错误

从这个脱敏之后的监控可以看到,经常有一些错误一下子动辄上万,除了图中几 K 的那些错误,在 1K 以下有更多密集的错误,只不过它们都被其他巨量的错误给拉平了,在这张图不明显。

这就给我们造成了很多问题:到底是 Oitsi 真出了问题,还是属于“正常的错误”?很难判断,每次发生这种情况都费时费力。大部分情况都是排查一番,然后发现是用户“滥用”造成的问题,不需要关心。而它又掩盖了很多真实的问题,比如一个新的版本发布之后偶尔会有一些内部的错误,是不应该发生的,却被真实的问题掩盖住了。基于这样的监控数据我们也无法设置告警,因为这些噪音太多了,即使有告警,也和没有一样。

这让我想起之前在蚂蚁的工作,我们有类似的问题。我有一年多的时间都在一个叫做“故障定位”的项目上。在蚂蚁我们也有很多告警(99%的)都是无效的,给 On Call 的同事带来很多噪音和打扰。在蚂蚁的思路是:开发一个“智能系统”(AI Ops),当告警发生的时候,自动地判断这个告警是不是噪音,是不是真正的问题,问题出在了哪里。拿到 Oitsi 的例子上说,当现在一个错误的数量突增,那么这个智能故障定位系统就去检查 Oitsi 的一些指标是否正常,导致告警的服务具体是什么,它之前是不是一直有类似的监控曲线模式,如果有,说明它一直在发生,是正常的,我们可以不管。

这样做了一年,效果还是不怎么样。我倒是发现,很多告警的规则本身就有问题,比如一个请求量每分钟只有两位数的服务,领导的要求是 “1分钟发现故障,5分钟定位故障”,不要说自动定位,就算是人去判断都不靠谱。为了达成这个目标,监控团队设置了很多非常敏锐的告警,交给定位团队说:“我们负责发现问题,你们负责定位问题。如果出问题了,1分钟之内有告警触发,那么我们的工作就达标了。但是至于没有问题我们也触发了很多噪音告警,就是你们的工作了。”  它们的 KPI 确实是完成了,只要有故障必定有告警。但事实是,在很多情况下,告警发出来,大家打开监控,盯着监控:“再等等看,看下一分钟,有请求进来了,服务没问题!”

所以这一年工作里,我有一个想法,就是在源头解决问题比使用高级的魔法系统去解决问题要简单、彻底很多。我们真的需要这么多人来开发一个“魔法系统”来帮我们诊断这种问题吗?

比如监控配置的不对,那就优化监控。监控为什么配置的不对?监控系统太难用,UI 让人捉摸不透,配置了告警无法调试,监控只能保存7天的数据,不能基于历史的监控数据配置告警。很多人为了“规则”,对服务配上了告警然后就走了,至于后面告警触发了,也不去响应。

回到 Oitsi 的问题上,我找了几个服务,发现这些 Oitsi 内部错误上并不能完全说是“正常的错误”,毕竟它是错误,没有错误会是正常的。只能说它没有导致线上问题而已。它们是可以被修复的。于是一个月前,我决定从源头去解决这些问题。把所有不应该报告出来的错误都消灭掉。

乍一看这么多错误数,用那么多团队在用,看起来是难以管理的,性价比非常低的工作。但是毕竟也没有人催我要快点完成,我可以一点一点去做。做一点错误就少一些(只要我解决问题的速度比新的问题出现的速度快)。

于是我按照下面的流程开始处理:

  1. 在 Jira(我们内部的工单系统)建立一个专题 tag,叫做 oitsi-abuse, 后面的工单可以关联这个 tag, 这样,可以在处理的时候方便参考之前的 Case;
  2. 创建一个监控,专门针对错误做一个面板,点击面板右侧的 Legend 可以直接跳到服务的监控面板,在服务的监控面板上显示下游,并且关联 CMDB 的 PIC(Person in charge).
  3. 这样,我从错误数最高的服务开始,查看监控,看下游服务,以及机器上的日志,看相关的错误码是什么时候开始的,到底是什么引起的,确定了是服务的问题就创建工单给这个服务的负责人,然后跟他联系,说明这个有什么问题,会对我们的监控、告警造成什么影响,需要修复。
  4. 等他确认问题,然后要求提供一个 ETA (预计修复的时间),把 ETA 写到工单中,到了时间去检查确认。
  5. 如果是 Oitsi 本身的问题,去找 Oitsi 开发同事排查问题。
  6. 等所有的问题都解决了的话,对错误设置告警,一有错误就去联系开发。一般情况下,都是他们做的配置变更或者发布引起了问题。这样对于业务其实是更加健康的,我们发现问题的能力更强了。

就这样,其实这样坐下来就发现只有那么几类问题,排查的速度越来越快。中间还发现一个库,它会去对 Oitsi 服务做心跳检查,这个检查设置不当会有一些错误。很多引用了这个库的应用都有一直在报错误的问题。但是我们系统本身其实已经做了探活可以保证心跳之类的问题了,沟通之后这个库的心跳检查行为可以下线。于是库发布了新的版本,我找所有的引用者去升级版本,很多错误一下子就消失了,非常有成就感。

这项工作的进度比我想象中的要快,一个多月,联系了 20 多个团队。虽然说也遇到了一些很扯的事情,明明是服务 A 的问题,就直接让我去找下游,让我们排查半天,最后又说回来找服务 A 负责人,拉了个群,摆出来日志,才承认是自己的问题,开始排查。但是大部分团队都非常配合,说明问题之后马上去排查,发现问题下一个版本就修复了。如此默契的合作让我感到惊讶又幸福!现在,系统错误维持在 200 以下了,并且现有的错误都已经找到了根因,还有3个服务待修复。最晚的会在 2 个周之后发布修复。可以预见到在不远的未来,这个系统将会成为一个 0 错误的系统!

今天系统报出的错误,还是有一些服务在一直报错,不过已经大大减少了。

这项工作虽然不涉及任何的 KPI 之类的,也没有什么技术含量,还都是一些“沟通”的工作,但是却带给我很大的成就感。我相信它也会在未来节省我很多时间。比如说我们评估系统的 SLI 和 SLO,由于 false alarm 太多,导致要花很多工作确定 down time 有多少,现在直接通过监控就可以确定了。

这项工作带给我的一些感想:

  1. 从源头解决问题最彻底;
  2. 不要害怕沟通;
  3. 错误的发生都有原因,排查下去,零就是零,一就是一(从这个 Case 看,也确实所有的错误都可以被解决的);
  4. 每个公司都有脏活,累活(毕业去的第一家公司维护爬虫,也有很多脏活、累活),这些都需要有人去做;

需要补充一下,我并不是完全否定做故障定位的思路。毕竟之前在蚂蚁,有四五个组在做相同的东西,我们(和其他做一样东西的组)尝试过非常多的思路,也有很多人因为这些晋升了(你说去联系了无数个团队,排查了很多问题,这有什么 impact 呢?你说自己做了一个“智能定位”系统,晋升就稳了吧。)。印象比较深刻的是有个项目制定了上千个(他们称为)决策树,简单来说就是:如果发生这个,就去检查这个。颇有成效,很多配置不当的告警就被这种规则给过滤掉了(虽然我觉得直接改报警要好一些)。我非常佩服他们的毅力。

说了这么多湿货,再说点干货。我们其实还有一个问题没有解决。如果读者有思路,欢迎评论:

在 Service Mesh 中,所有的服务都是通过 Agent 来调用的。比如 App1 要调用 App2,它会把请求发到本地的 Agent 中,由 Agent 去调用 App2 所在机器的 Agent.

这里,超时的问题就难处理。比如我们设置了 1s 超时。假如说 server 端的 Application 超时了,那么 Server 段的 Agent 可以报告一个应用超时错误,不算做我们 Oitsi 系统错误。但是对于客户端的 Agent 呢?它无法知道到底是 Server 的应用超时了,还是 Server 的 Agent 超时了。所以对于 Server 超时的情况下,客户端的 Agent 总会报出一个内部超时错误。

这种错误,我们当前还是无法区分是否是由应用引起的。

有关这个超时问题,可以看下我们在 Twitter 上的讨论:https://twitter.com/laixintao/status/1407885941541203973


2021年07月09日更新:

有关错误的告警和噪音问题,Cloudflare 提出了一种方法,通过 SLO 来监控错误:Smart(er) Origin Service Level Monitoring。为了避免噪音,这里监控的目标是 burn rate, 即 SLO 被消耗的速度。为了减少这个速度带来的噪音,需要达到两个条件才能 fire 告警:

  1. short indicator
  2. long indicator

短时间内 burn rate 上升很快,会触发 short indicator, 而又需要持续一些时间,才能触发 long indicator.


2021年10月1日更新:

看了一篇类似的文章:Embrace the Grind

piglei 的翻译:《拥抱磨砺