你有没有遇到过这样的问题 ?
你刚入职新公司,负责一个了后端服务,一切都很顺利~
在一个星期五下午 5 点,还有一个小时你就下班了,但这时~麻烦来了,你的上游突然气势汹汹地找你😡,问你的接口为什么调用超时?
你慌了😩但强作镇定查看监控,发现自己服务的接口耗时正常
在你刚想回怼他之前你突然想到公司的监控 仅能监控到服务端应用的耗时, 可中间内核和网络的耗时没有监控!
于是你们谁也说服不了谁👿, 接下来开始互相扯皮甩锅,最后问题不了了之。。。
反过来,你调用下游接口超时,但对方监控显示并没有超时,于是又开始新的扯皮流程,不同的是你站在了另一边...
所以要解决这个问题该怎么办呢?
tcpdump 抓包! 但 tcpdump 最大的一个劣势就是排查:太 慢 了。
比如说你现在需要排查一个线上问题:
a. 首先你需要在生产环境安装一个 tcpdump 💤,
b. 然后找到出现问题的服务端的 ip 和 port👁👁
c. 然后自己写过滤表达式(可能你忘了怎么写,花了 5min 在搜索~😂)
d. 费了九牛二虎之力你终于从生产机器上下载下来一个数百 MB 的 pcap 文件💤
e. 然后安装 tcpdump 客户端(如果你还没安装的话)💤
f. 加载 pcap 文件让你的 CPU 风扇狂转 😡
g. 几分钟后你睁大双眼👁👁人肉确认你想要的那个接口在不在这这个 pcap 文件里,因为包含了太多无效信息,可不幸的是你发现根本没有🤡。。。
h. 然后你重新开始抓包,检查自己的 tcpdump 命令是否写对... 😔
让运维装监控啊! 幸好现在出现了eBPF这一强大的技术,可以深入采集内核打点实现全栈的可观测性。 现在的 skywalking 、pixie 、deepflow 等都有着不错的产品。
但这可不容易!上述这些监控要么需要很高的内核版本(5.x),要么只能监控 K8s 的流量,要么会产生每小时 TB 级的监控数据需要很重的存储依赖。
那么有没有一款轻量级、兼容低版本内核、并且能高效率的排查 网络问题的工具呢?
kyanos 来了!
kyanos 是我开源的一个命令行工具👉kyanos 仓库地址👈,它支持最低 3.10 版本的内核,不需要安装任何依赖就可运行,你需要做的只是下载它的可执行文件(Release 下载地址)。
那么 kyanos 的功能是什么?
在详细介绍之前,上一个例子让大家了解 kyanos
你不需要了解任何过滤语法,你只需要执行一行命令(kyanos stat http ...
),kyanos 就能找到最慢的几个 HTTP 请求,并且发现它们耗时详情(想一想如果使用 tcpdump 会花费多少时间):
这里一行命令就找到了几个最慢的请求。
如果你想打印请求响应的内容怎么办呢?,你可以这样:
可以看到请求响应内容直接打印出来了。
kyanos 不仅仅安装特别方便,而且用起来特别符合咱们业务开发的排查模式~ 因为 kyanos 不是基于数据包维度的,这种粒度太细。通常包含大量无效信息,不适合快速排查问题,而 kyanos:完全无侵入,基于七层协议维度,能够过滤大量无效信息,保留对排查问题最有价值的信息。
那么 kyanos 它具体能够做什么呢? kyanos 的主要功能包括两点:
1 、 抓取各种协议( HTTP 、MySQL 、Redis 等)的请求响应。
2 、 通过聚合 1 中抓取的流量进行更高维度的分析。
这里我不做过多介绍,直接上例子!🤞
watch 命令可以使用各种过滤条件抓取各种协议( HTTP 、MySQL 、Redis 等)的请求响应。你不需要了解任何过滤表达式的知识就能轻松抓取你想要的任何请求响应进行分析。
比如你有一个 Spring Cloud 应用,监控告警发现访问远程一个接口 /foo/bar 有时候有一些 p99 尖刺(比如超过了 1s 的请求),说明有一些长尾请求,这时你该如何确定问题的根因呢?
很简单,通过 kyanos 的 watch 命令查看那些超过 1s 耗时的请求具体耗时在哪:
kyanos watch http --pid {your_pid} --latency 1000 --path /foo/bar
它会输出类似下面的结果:
可以看到 watch 会输出下面几个部分:
可以看到 kyanos 不仅支持请求响应的内容抓取,甚至把网络和内核的耗时都计算出来了,对排查问题是非常有帮助的!
目前 watch 支持 HTTP 、MySQL 和 Redis 协议流量的抓取(这当然不会是全部,后续会支持更多),并且支持各种过滤条件, 更多见 Github 文档:Kyanos 命令详解 Watch 部分
仅有 watch 命令只能提供一个细粒度分析的视角,Stat 则提供了更为灵活和高维度的分析能力,简单来说就是将请求响应的指标按照一些维度聚合起来,比如我想知道哪些远程 ip 的接口最慢,就通过聚合相同 ip 的请求响应来获取最慢的远程 ip 。
所以它能回答下面这些问题:
帮我找到现在这台机器上调用的哪些远程 ip 的 HTTP 接口最慢?
一行命令搞定:./kyanos stat http --side client -i 5 -m n -l 10 -g conn
,每 5 秒输出请求响应在网络中的耗时最长的前 10 个 HTTP 连接,输出如下:
结果输出找到了两个连接,还有耗时的 avg 、max 、pxx 等信息。
我的机器出口流量非常大,到底哪些 HTTP 请求造成的?
一行命令搞定:./kyanos stat http --side client -i 5 -m p -s 10 -g none
, 每 5 秒按输出响应大小最大的前 10 个 HTTP 请求响应, 输出如下:
可以看到结果中包含了响应的大小的 avg 、max 、pxx 等,还包含了 HTTP 请求的 path 信息。
使用 stat 命令的一般步骤
--metrics
指定。kyanos 支持以下指标的聚合。观测指标 | flag |
---|---|
总耗时 | t |
响应数据大小 | p |
请求数据大小 | q |
在网络中的耗时 | n |
从 Socket 缓冲区读取的耗时 | s |
--group-by
或者 -g
指定 。比如我们关注不同远程服务提供的服务质量是否有差异,就可以指定-g remote-ip ,这样请求响应的统计信息就会按照不同的远程 ip 地址聚合,最终我们将会得到一个不同远程 ip 的耗时情况,更容易看出哪个远程服务存在问题。kyanos 支持以下聚合方式:聚合维度 | 值 |
---|---|
最细的粒度,只聚合到单个连接 | conn |
远程 ip | remote-ip |
远程端口 | remote-port |
本地端口 | local-port |
连接协议 | protocol |
最粗粒度,聚合所有的请求响应 | none |
更完整的使用说明见 Github: https://github.com/hengyoush/kyanos
stat 通过 watch 观察的结果,根据用户指定的聚合维度聚合(--group-by 参数),最后按照用户最关心的指标输出(--metrics 参数).
如果要用 tcpdump 该花多少时间啊,使用 kyanos 几秒就搞定了!
啊其实有些标题党了~😄, kyanos 其实还不能真正取代 tcpdump ,比如 kyanos 目前支持的应用层协议比较有限,对于网络环境更加复杂的部署的支持还有待改进,但总的来说,其确实能提高咱们业务开发的排查效率👍。
我为什么这么自信呢?因为我是用 kyanos 真正解决过问题 的,看过我文章的朋友可能知道我是搞 Redis 的(专栏:Redis 疑难杂症 - 烈香的专栏,我的 Blog:烈香的 Blog),kyanos 帮我解决了一个非常诡异的 Redis 客户端超时但 Redis 服务端没有任何异常的问题(这个解决过程我近期会发一篇文章出来,感兴趣的朋友可以关注我哦~),这个问题在 30min 内排查出来定位到原因,kyanos 通过这一次真正验证了自身价值。所以我敢开源出来,我相信 kyanos 也能帮助到大家~
最后的最后可不可以点一个 star 鼓励我,哼,别逼我求你😡 Kyanos
我是烈香,我们下篇文章再见~
1
Kinnice 65 天前
ssl/tls 支持怎么样?一般服务间调用都是带 ssl/tls, 裸协议很少了。
|
2
hengyoush123 OP @Kinnice 感谢回复,后面会支持,这个没问题的
|
3
est 65 天前
用爱发电还是会有小动作?服务器敏感肌也能用吗?
|
4
hengyoush123 OP @est 当然是为爱发电啊😂
|
5
xiaomoxian 65 天前 via Android
配享太庙的
|
6
buf1024 65 天前
看完描述,远没大鲨鱼方便。
|
7
jorneyr 65 天前
能否支持每一次通讯的数据,例如 MySQL 每一次的数据,而不是耗时超过 1S 等这种超过阈值的。
我的目的是分析各种数据库 JDBC 驱动里使用哪些 SQL 语句,目前使用 Wireshark 抓包分析。 |
8
povsister 65 天前
老实说每次看到这种,我就想真的想,弄个 daemonset 丢 prod 里,对外暴露 grpc 供平台使用。
然后有问题的话直接从平台上开搞。现在 prod 环境最多也就拿个 shell 看看,还是 pod 里的,还是 non-root 。想摸机器的 shell 门都没有,更不要说上去跑命令抓包下回来分析了 |
9
hengyoush123 OP @jorneyr 用 watch 就可以,比如: kyanos watch mysql --local-ports 3306
|
10
Ansen 65 天前 via iPhone
感谢,明天用用看
|
11
defaw 65 天前
做的很好,但是更多时候 tcpdump 是用来抓取一些网络层的细节而不是应用层
|
12
jorneyr 65 天前
@hengyoush123 谢谢,后面试试。
|
13
yanghanlin 65 天前
看起来是通过将内核 BTF 打包进应用实现对低版本内核兼容的,请教下是需要针对每个发行版、每个版本的内核都构建一份 BTF 吗?可以利用现有的一些工作如 BTFHub https://github.com/aquasecurity/btfhub 吗?
|
14
hengyoush123 OP @yanghanlin BTFHub https://github.com/aquasecurity/btfhub 就是用了 btfhub 上的 btf 文件
|
15
ZiLong 65 天前
看起来很棒
|
16
churchmice 65 天前 via Android
很显然 tcpdump 可以查看更多的问题,你这玩意的应用范围有限
整这么个标题党真的不好 |
17
hengyoush123 OP @churchmice 感谢回复。首先我承认标题有些夸张,“很显然 tcpdump 可以查看更多的问题” 这一点我不太认同,tcpdump 能够在几秒中之内告诉我哪一个 HTTP 请求最慢吗?慢在网络还是内核? 所以 tcpdump 关注的点和 kyanos 不太一样,它们解决的问题也不一样,kyanos 更多的是偏向排查问题的视角。
|
18
musi 65 天前 via iPhone
我选择 tcpdump 拖进大鲨鱼
电脑卡让公司换高配电脑 运维不让抓包就甩锅给运维 我这是在帮公司解决问题公司不配合那就没办法了,又不是我的问题 |
19
Yien 65 天前 via Android
赞到爆炸💥
|
20
lekai63 65 天前 via iPhone
op 你这个支不支持 macos 呢?
|
21
hengyoush123 OP @lekai63 macos 还不支持
|
22
yanghanlin 65 天前
@hengyoush123 #14 那想再请教一下,为什么把 BTF 放到仓库而不是在构建过程中从 BTFHub 下载呢?
|
23
putyy 65 天前
不错 赞👍🏻
|
24
fenglangjuxu 65 天前
牛逼 plus
|
25
Vegetable 64 天前
正常来说应用层都是有日志的,用到 tcpdump 的时候都不是在排查这类问题
|
26
spartacussoft 64 天前
tcpdump(libpcap)是抓包用途,不是协议分析器。
我不明白你是造新的抓包,还是造新的分析功能软件。 拿着自己的分析功能和别的抓包功能比较,比较个毛线啊。 我觉得你不如给大鲨鱼开发个基于 swagger 路由的统计插件(其实它本身也有 http 路径统计功能) |
27
archxm 64 天前
我还是更能适应扯皮
|
28
sankooc 64 天前
不错 不错 学习下
|
29
CpchengToken 64 天前
收藏夹请~
|
30
VVVYGD 64 天前
配享太庙
|
31
hengyoush123 OP @yanghanlin 1. 构建的时候再下载太慢了,等后面内核部分稳定了再考虑 2. 我本地网络环境不是很好,BTFHUB 仓库没完整 clone 成功
|
32
himcheobeolx 63 天前
有用,star 了
|
33
Dganzh 63 天前
这里的 http 包含 http2 ?
|
34
Charlie17Li 61 天前 via iPhone
好强,点个 star 支持下
|