Kyanos 5 分钟上手:用 watch、stat、overview 三个子命令完成网络排障
【免费下载链接】kyanosKyanos is a networking analysis tool using eBPF. It can visualize the time packets spend in the kernel, capture requests/responses, makes troubleshooting more efficient.项目地址: https://gitcode.com/GitHub_Trending/ky/kyanos
Kyanos 是一款基于 eBPF 的网络分析工具,能够在命令行中可视化数据包在内核中的耗时、抓取请求与响应,让网络问题排查更高效。本文以官方入门文档 docs/how-to.md 为主线,讲解 Kyanos 的三大核心子命令watch、stat、overview的使用方法,并结合仓库源码剖析其底层实现。读完本文,你将掌握如何快速抓取请求响应记录、查看逐节点的延迟明细,以及如何按维度做聚合统计,在几分钟内定位慢请求、大流量等网络异常。
三大子命令概览
Kyanos 主要有三个子命令,分别对应不同的排查阶段(入口定义见 cmd/root.go、cmd/watch.go、cmd/stat.go、cmd/overview.go):
- watch:按照指定条件抓取网络流量,并自动将其解析为请求-响应记录(request-response records)。适合观察单条请求的完整生命周期与延迟构成。
- stat:基于指定条件对请求-响应记录做聚合统计,输出更高层级的统计信息。适合回答"哪些连接请求数最高""哪个远端服务器平均延迟最大""哪个客户端消耗带宽最多"这类问题。
- overview:一条命令概览当前机器依赖的外部资源(如 MySQL、Redis 等中间件)。从 cmd/overview.go 可以看到,它本质上是把
group-by预置为remote-ip/protocol-adaptive的分析模式,按远端 IP + 自适应协议维度汇总。
使用 watch 抓取请求响应
最简用法:抓取所有已支持协议
最简单的用法是直接运行watch,抓取 Kyanos 当前支持的所有协议流量:
./kyanos watch目前 Kyanos 支持解析HTTP、Redis、MySQL、RocketMQ、Kafka、MongoDB、DNS七种协议(协议列表在 cmd/watch.go 的supportedProtocols中定义)。每条请求-响应记录以表格的一行呈现,可以通过方向键或j/k上下移动浏览记录,按数字键可对列排序。
每个列的含义如下(字段定义见 cmd/watch.go 与 docs/watch.md):
| 列名 | 说明 | 示例 |
|---|---|---|
| id | 表格序号 | — |
| Connection | 该请求-响应所属的连接 | 10.0.4.9:44526 => 169.254.0.4:80 |
| Proto | 请求-响应使用的协议 | HTTP |
| TotalTime | 该请求-响应总耗时(毫秒) | — |
| ReqSize | 请求大小(字节) | — |
| RespSize | 响应大小(字节) | — |
| Net/Internal | 作为客户端发送请求时为网络延迟;作为服务端接收请求时为内部处理耗时 | — |
| ReadSocketTime | 客户端从 Socket 缓冲区读取响应、服务端从缓冲区读取请求所花费的时间 | — |
[!TIP] 默认
watch收集 100 条请求-响应记录,可通过--max-records选项调整(见 cmd/watch.go)。
按 Enter 查看详情:延迟三部分拆解
按Enter进入某条记录的详情视图:
详情页分为三部分:
- 第一部分:延迟详情(Latency Details)。每个方块代表数据包经过的一个节点,如进程、网卡、Socket 缓冲区等;每个方块下方有一个延迟数值,表示从前一节点到达该节点所花费的时间。你可以清晰地看到请求从进程发出到网卡、响应从网卡复制到进程被读取的完整过程,以及每一步的延迟。
- 第二部分:请求与响应基本信息(Basic Information)。包括请求和响应的开始/结束时间、请求与响应的大小等。
- 第三部分:请求与响应具体内容(Specific Content)。分为 Request 和 Response 两个区段。超过
1024字节的内容将被截断显示,可通过--max-print-bytes调整该上限(见 cmd/watch.go)。
[!TIP] 默认的延迟视图只展示进程、网卡等节点。如果还想看到数据从网卡复制到 TCP 缓冲区以及从缓冲区读取到进程的延迟,可给 watch 加上
--trace-socket-event选项(见 cmd/watch.go),延迟可视化图中会额外出现一个 Socket 块。
从源码看,这些可观测能力来自 Kyanos 的 eBPF 探针体系:--trace-dev-event(默认开启)负责采集网卡层事件以测量网络接口耗时,--trace-ssl-event(默认开启)负责追踪 SSL 连接数据,--trace-socket-event(默认关闭)负责采集 Socket 层复制耗时(见 cmd/watch.go)。
更精确的抓取:按协议与路径过滤
只抓 HTTP 流量:
./kyanos watch http进一步收窄到某个 HTTP 路径:
./kyanos watch http --path /abc每种协议都有不同的过滤选项,完整说明见 watch 命令详解(抓取请求响应与延迟详情)。
watch 的过滤体系
watch默认抓取所有支持协议的流量,但实际排障中通常需要精确过滤。Kyanos 的过滤选项按层次分为四类,所有选项可以任意组合。
网络层(L3/L4)过滤
| 过滤条件 | 命令行参数 | 示例 |
|---|---|---|
| 本地连接端口 | local-ports | --local-ports 6379,16379只观察本地端口 6379 和 16379 上的请求-响应 |
| 远端连接端口 | remote-ports | --remote-ports 6379,16379只观察远端端口 6379 和 16379 上的请求-响应 |
| 远端 IP 地址 | remote-ips | --remote-ips 10.0.4.5,10.0.4.2只观察来自远端 IP 10.0.4.5 和 10.0.4.2 的请求-响应 |
| 客户端/服务端 | side | --side client/server只观察作为客户端发起连接或作为服务端接收连接的流量 |
这些选项在 cmd/root.go 中以 PersistentFlags 方式注册(--pids、--comm、--remote-ports、--local-ports、--remote-ips),因此对watch、stat均生效。--side参数在 cmd/common.go 的ParseSide中被解析为all/server/client三种取值。
进程/容器过滤
| 过滤条件 | 命令行参数 | 示例 |
|---|---|---|
| 进程 PID 列表 | pids | --pids 12345,12346多个 PID 用逗号分隔 |
| 进程名 | comm | --comm 'curl' |
| 容器 ID | container-id | --container-id xx |
| 容器名 | container-name | --container-name foobar |
| Kubernetes Pod 名 | pod-name | --pod-name nginx-7bds23212-23s1s.default(格式为 NAME.NAMESPACE) |
容器相关的过滤选项定义在 cmd/root.go,其注释明确说明目前只支持 TCP 和 UDP 包。Kyanos 还能展示容器网卡到宿主机网卡之间的延迟,关于容器网络的详细说明见 docs/watch.md。
请求响应通用信息过滤
| 过滤条件 | 命令行参数 | 示例 |
|---|---|---|
| 请求-响应延迟 | latency | --latency 100只观察延迟超过 100ms 的请求-响应 |
| 请求大小(字节) | req-size | --req-size 1024只观察大于 1024 字节的请求 |
| 响应大小(字节) | resp-size | --resp-size 1024只观察大于 1024 字节的响应 |
--latency与--req-size/--resp-size在 cmd/common.go 中分别被构造成LatencyFilter与SizeFilter,其底层实现位于 agent/protocol/generic_filter.go。
协议特定过滤
可通过在watch后追加协议子命令(http、redis、mysql、rocketmq、kafka、mongodb、dns)来只抓对应协议的流量,各协议过滤选项如下:
- HTTP(实现见 agent/protocol/http.go 的
HttpFilter): | 过滤条件 | 命令行参数 | 示例 | | --- | --- | --- | | 请求路径 |path|--path /foo/bar| | 请求路径前缀 |path-prefix|--path-prefix /foo/bar| | 请求路径正则 |path-regex|--path-regex "\/foo\/bar\/.*"| | 请求 Host |host|--host www.baidu.com| | 请求方法 |method|--method GET| - Redis(实现见 agent/protocol/redis..go 的
RedisFilter): | 过滤条件 | 命令行参数 | 示例 | | --- | --- | --- | | 请求命令 |command|--command GET,SET| | 请求 Key |keys|--keys foo,bar| | 请求 Key 前缀 |key-prefix|--key-prefix foo:bar| - RocketMQ(preview):
--request-codes 10,11按请求码过滤;--languages Java,Go按客户端语言过滤。 - Kafka(preview,实现见 agent/protocol/kafka/filter.go 的
KafkaFilter):--topic quickstart-events按 Topic 过滤;--producer/--consumer区分生产者/消费者请求(指定 topic 时默认均为 true);--apikeys 10,11按 Kafka API Key 过滤。 - DNS(preview,实现见 agent/protocol/dns/filter.go 的
DnsFilter):--host example.com按查询域名过滤。 - MongoDB:已支持抓取,但条件过滤仍在开发中(实现见 agent/protocol/mongodb/mongodb.go)。
- MySQL:已支持抓取,但条件过滤仍在开发中(实现见 agent/protocol/mysql/filter.go)。
例如只抓取访问/foo/bar的 HTTP 请求:
kyanos watch http --path /foo/bar[!TIP] 上述所有选项都可以组合使用。例如:
./kyanos watch redis --keys foo,bar --remote-ports 6379 --pids 12345这让你可以根据实际场景精确裁剪抓取范围,只收集最相关的请求-响应数据。
使用 stat 做聚合统计
真实场景中watch的输出往往过于细粒度,因此 Kyanos 提供了stat命令做统计分析。简而言之,stat能帮你回答这类问题:哪些连接请求数最高?哪些远端服务器平均延迟最大?哪些客户端消耗带宽最多?
明确指标与分组维度
使用stat前只需要想清楚一件事:你关心什么指标。例如要回答"我的 HTTP 请求变慢或超时,是所有服务器都慢,还是只有某一台慢",那么关心的指标就是各远端服务器(remote-ip)的响应时间,对应命令为:
./kyanos stat --metric total-time --group-by remote-ip--metric total-time表示分析请求响应的总耗时,--group-by remote-ip表示按远端 IP 分组观察响应时间。Kyanos 会把相同remote-ip的请求-响应聚合在一起并给出相关指标。更短的写法:
./kyanos stat -m t -g remote-ip其中-m是metric的简写,t是total-time的简写,-g是group-by的简写。这些参数的解析逻辑在 cmd/stat.go 的validateEnabledMetricsString与createAnalysisOptions中,聚合分类器(Classfier)的注册定义在 agent/analysis/common/types.go 与 agent/analysis/classfier.go 中。
[!TIP]如何过滤流量?
stat命令支持watch命令的全部过滤选项。
解读 stat 结果表格
输入上述命令后,默认收集 10 秒数据(可用--time修改,或按ctrl+c提前停止),随后展示结果表格:
和watch表格一样,按数字键可排序、用↑/↓或k/j选择记录。与watch不同的是,stat中的记录按--group-by维度聚合,因此第二列是分组维度名(这里是remote-ip),后续的max、avg、p50等列表示指定指标(这里是total-time)的最大值、平均值和 P50 分位值:
Colleted events are here! ┌──────────────────────────────────────────────────────────────────────────────────────────────┐ │ id remote-ip max(ms) avg(ms) p50(ms) p90(ms) p99(ms) count │ │──────────────────────────────────────────────────────────────────────────────────────────────│ │ 0 169.254.0.4 108.59 60.36 64.00 128.00 128.00 3 │ │ 1 180.101.50.242 11.56 11.56 16.00 16.00 16.00 1 │ │ 2 180.101.50.188 11.98 11.51 13.33 16.00 16.00 3 │ │ │ │ │ │ │ └──────────────────────────────────────────────────────────────────────────────────────────────┘ ↑/k up • ↓/j down 1 sort by name • 2 sort by max • 3 sort by avg • 4 sort by p50 • 5 sort by p90 • 6 sort by p99 • 7 sort by count • 8 sort by total在上例中,由于未指定分组维度,远端服务器地址(remote-ip)作为默认聚合维度(第二列)。可以看到 IP169.254.0.4的延迟指标明显异常——最大 108.59ms、平均 60.36ms,远高于另外两个 IP,据此可以快速锁定问题服务器。
在对应行按Enter可以查看该远端 IP 下具体的请求-响应列表:
Events Num: 3 ┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ id Process Connection Proto TotalTime↓ ReqSize RespSize Net/Internal ReadSocketTime │ │───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────│ │ 1 1315398<barad_agent> 10.0.4.9:38458 => 169.254.0.4:80 HTTP 108.59 564 216 107.18 1.36 │ │ 2 1315398<barad_agent> 10.0.4.9:38482 => 169.254.0.4:80 HTTP 45.89 676 216 43.83 2.00 │ │ 3 1315398<barad_agent> 10.0.4.9:38470 => 169.254.0.4:80 HTTP 26.60 588 216 25.21 1.30 │ │ │ └───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ ↑/k up • ↓/j down这里的展示格式与watch命令完全相同——每行是一条请求-响应记录,再次按Enter即可查看该请求的延迟与内容详情。
[!TIP]
stat命令能力很强,强烈建议进一步阅读 stat 命令详解(如何聚合与分析流量) 探索更多用法。
支持的指标(--metric)
| 指标 | 短标志 | 长标志 |
|---|---|---|
| 总耗时 | t | total-time |
| 响应大小 | p | respsize |
| 请求大小 | q | reqsize |
| 网络耗时 | n | network-time |
| 内部处理耗时 | i | internal-time |
| Socket 读取耗时 | s | socket-time |
从 cmd/stat.go 的SUPPORTED_METRICS可以看到这六个指标的具体含义,其统计口径对应 agent/analysis 目录下的分析模块:network-time对应客户端视角下请求离开网卡到响应到达网卡的黑盒耗时,internal-time对应服务端视角下请求进入进程到响应离开进程的处理耗时。
支持的分组维度(--group-by)
| 分组维度 | 取值 |
|---|---|
| 按连接分组 | conn |
| 远端 IP | remote-ip |
| 远端端口 | remote-port |
| 本地端口 | local-port |
| L7 协议 | protocol |
| HTTP 路径 | http-path |
| Redis 命令 | redis-command |
| 全量聚合 | none |
在 cmd/stat.go 中还可以看到,Kyanos 会为 HTTP 协议预置http-path分类器、为 Redis 预置redis-command分类器、为 MySQL 预置remote-ip分类器,从而实现"协议自适应"的分组行为。
记不住选项?用三个快捷模式
stat命令提供了三个开箱即用的快捷分析模式:
--slow:分析慢请求。快速定位哪个remote-ip的 HTTP 请求最慢:./kyanos stat http --slow--bigreq:分析大请求。找出哪个remote-ip的请求体最大:./kyanos stat http --bigreq--bigresp:分析大响应。找出哪个remote-ip的响应体最大:./kyanos stat http --bigresp
这三个模式的定义在 cmd/stat.go,并最终映射到 cmd/stat.go 中AnalysisOptions的SlowMode、BigReqMode、BigRespMode字段。
收集时长同样可用--time指定,例如--time 10让stat收集 10 秒流量;收集完成或按ctrl+c提前停止后即展示结果表格,后续操作与前面一致。
进阶:JSON 输出与更多阅读
watch还支持--json-output标志输出结构化数据,便于程序化处理(见 cmd/watch.go):
# 输出到终端 kyanos watch --json-output=stdout # 输出到文件 kyanos watch --json-output=/path/to/custom.jsonJSON 输出包含每个请求-响应对的详细字段:请求与响应的时间戳、连接信息(地址与端口)、协议特定信息、详细的延迟指标以及请求响应内容。完整字段规格与示例见 JSON 输出格式文档。
下一步
每个命令的完整细节可继续阅读:
watch命令:抓取请求-响应与延迟详情stat命令:如何聚合与分析流量
至此,你已经掌握 Kyanos 三大子命令的核心用法:用watch抓单条请求看延迟构成、用stat聚合分析定位异常维度、用overview一览外部依赖。结合文中的过滤选项与源码路径,即可在真实环境中快速开展网络排障。
【免费下载链接】kyanosKyanos is a networking analysis tool using eBPF. It can visualize the time packets spend in the kernel, capture requests/responses, makes troubleshooting more efficient.项目地址: https://gitcode.com/GitHub_Trending/ky/kyanos
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考