TCP-RT是一款TCP监控工具,采用内核埋点技术识别TCP连接中的请求与响应,捕获请求接收及服务处理时间等相关信息。TCP-RT适用于单个连接上仅存在一个并发请求与响应的场景(例如HTTP/1.1、MySQL、Redis等服务),要求系统为Alibaba Cloud Linux 2(内核4.19.91-21.al7及以上版本)或Alibaba Cloud Linux 3。Alibaba Cloud Linux 3(内核5.10.134-17及以上版本)提供了新版本的TCP-RT,在继承了原版本特性的基础上增加了对HTTP/TLS协议的支持。
为便于区分,在涉及新老版本功能差异时,将以tcp_rt.ko代指老版本,tcprt代指新版本。二者核心差异在:
tcp_rt.ko:以内核模块形式使用。
tcprt:通过
systemctl
配合配置文件使用,新增若干功能。
建议您优先使用tcprt。
功能原理
当TCP的服务场景为一个并发的请求与响应时,各个阶段如下图所示。
客户端(Client)向服务端(Server)发送的第N个请求(request)表示为ReqN,该请求由ReqN-1
和ReqN-2
两个数据包组成。服务端收到第一个包的时间被记录为T0,第二个包的时间被记录为T1。服务端收到请求后进行处理,完成处理后会向客户端发送两个响应的数据包RspN-1
和RspN-2
,服务端发送第一个包的时间被记录为T2。客户端收到响应包后会发送确认信息ACK给服务器,服务端收到最后一个ACK的时间被记录为T3。
TCP-RT基于以上的时间点的记录,可以计算出以下有意义的信息:
upload_time:用户请求上传所使用的时间。
process_time:服务端的处理时间。
服务端从收到最后一个请求的数据包开始,到服务端向客户端开始发送响应的数据包为止,这段时间为服务端的处理时间。
download_time:数据下载时间。
从服务端向客户端发送响应的数据包开始,到服务端收到客户端最后一个ACK为止,这段时间为数据下载时间。对于下载比较大的数据响应,该信息的获取较为重要。
信息输出说明
TCP-RT在内核态采集TCP服务的相关参数并输出,下表说明了文件的输出方式与输出时间点。
文件类型 | 输出方式 | 输出时间 |
log文件 | 以
|
|
stats文件 | 该数据是基于端口(服务端端口或客户端端口)进行数据汇总后,输出到/sys/kernel/debug/tcp-rt路径下的 | 定时输出。默认为一分钟输出一次。 |
解析模式说明
TCP-RT支持多种解析模式,用户可自行配置。具体操作,请参见功能使用。
default:默认模式。
基于通用TCP流进行解析,TCP流可以是HTTP、Redis、Mysql等符合请求/响应行为的协议。
http:HTTP增强。
在default模式基础上,额外报告RTT和拥塞窗口信息,并且识别HTTP协议的“Expect: 100-continue”处理过程。将100-continue请求及其响应报告为一条
R.C
类型记录。更多信息,请参见输出格式说明。https:HTTPS增强。
在http模式的基础上,额外增加了TLS部分报文解析。
tcp_rt.ko的解析模式不可配置,仅支持default模式。
输出格式说明
TASK与TCP生命周期释义。
TASK表示一次完整的请求+响应(request+response)。
TCP生命周期中包含多个TASK。
log文件格式说明
在log文件中,每条记录的每一列都对应了不同的信息。log文件内容示例如下图所示。按照从左到右的顺序,每一列参数说明如下:
版本号,目前为V6或V7。
V6:默认版本号。
V7:对R类型记录,特定配置下可能出现额外内容,标记为V7。具体包括:
http、https解析模式下R日志版本为V7,因为末尾带有附加字段。
R日志扩展格式下,版本为V7,包括R.C、R.Z、R.A、R.H、R.F,具体含义见下表。
记录场景标识,目前分为R、E、W、N、P五种类型。
R:请求到本地服务器的情况下,在一个TCP服务中完成一次请求+响应产生一条该记录。
E:连接关闭的情况下,产生一条该记录。
W:连接在发送数据过程中被关闭的情况下,产生一条该记录。
N:连接在接收数据过程中被关闭的情况下,产生一条该记录。
P:本地服务器请求对端服务器的情况下,在一个TCP服务中完成一次请求+响应产生一条该记录。
TASK开始时间,开始时间的秒部分。
TASK开始时间,开始时间的微秒部分。
TCP连接的对端IP地址。
TCP连接的对端端口。
TCP连接的本地IP地址。
TCP连接的本地端口。
以上参数后面衔接不同记录场景标识的不同参数。说明如下表所示。
记录场景标识 | 参数说明 |
R | 该记录是TASK正常启动和关闭的记录,每个TCP连接可以有多个R记录。
|
R.C | 说明 仅tcprt支持,版本号为V7。 http、https解析模式下可能出现,格式同R记录。 表示TASK为“Expect: 100-continue”引入(该TASK不带有应用数据)。 |
R.Z | 说明 仅tcprt支持,版本号为V7。 https解析模式下可能出现,格式同R记录。 表示TASK属于TLS 1.3 0RTT握手。 |
R.A | 说明 仅tcprt支持,版本号为V7。 https解析模式下可能出现,格式同R记录。 表示TASK中含有 |
R.H | 说明 仅tcprt支持,版本号为V7。 https解析模式下可能出现,R记录末尾可能附加额外内容。 表示TASK属于TLS握手阶段。若是TLS 1.3(三次握手),日志末尾将报告握手耗时,单位:us。 末尾附加内容格式为 |
R.F | 说明 仅tcprt支持,版本号为V7。 开启 表示TASK触发按字节数的完成时间统计。根据配置文件定义的字节数阈值阶梯,划分每个TASK响应数据流,统计各阶梯的数据量与完成时间,附加于记录末尾,单位分别为bytes和us。 末尾附加内容格式为 |
P | 该记录是TASK正常启动和关闭的记录,每个TCP服务可以有多个P记录。P是V6版本中新增的记录,表述的是客户端对外请求时的信息。只有配置了选项
|
E | 该记录是TCP被关闭的记录。每个TCP连接都有1个E记录,配置了选项
|
N | 该记录是在TASK请求接收报文段(segment)过程中,TCP被关闭场景下的记录。每个TCP连接可能有一个N记录或没有。
|
W | 该记录是在TASK响应发送的报文段(segment)过程中,TCP被关闭场景的记录。每个TCP连接可能有1个W记录或没有。
|
扩展日志类型以
R.x
格式标记,其中x
可以是单个字符(如上表),也可以是多个字符的组合。比如R.AF
即表示A
和F
同时生效。R.A
和R.C
类型日志,以响应数据量为判据,因此可能存在少量误判。在上表涉及TASK发送数据量的这类信息中,如果是连接的最后一个TASK,正常处理会减去关闭连接(fin)占用的一个
snd_nxt
值。而如果连接是异常关闭的,例如一个TASK完成之后收到了异常终止报文(reset)并且连接也是以响应reset
结束的,则实际发送的数据量会大于这里显示值一个字节。正常情况下,该类值都是正确的,并且异常的情况下只误差一个字节。
关于功能原理部分所示的三个时间阶段。
R记录报告总时间(T0至T3)、上送延时(upload_time,T0至T1)、服务延时(process_time,T1至T2)。数据下载时间(download_time)可由上述信息计算得出:
download_time = 总时间 - upload_time - process_time
stats文件格式说明
按照从左到右的顺序。每一列参数说明如下:
记录输出时的时间戳。
保留字段,目前唯一值为
all
。端口号。
R记录中TASK总耗时的平均值。
R记录中TASK服务延时的平均值。
丢包千分数(‰)。
RTT的平均值。单位:us。
请求发送的数据中,被关闭的TASK数量的千分数(‰)。
TASK发送的数据量的平均值。
TASK上送延时的平均值。
TASK接收的数据量的平均值。
参与统计的TASK的数量。
tcprt与tcp_rt.ko版本差异
比较项 | tcprt | tcp_rt.ko |
日志文件路径 | 相同 | |
日志格式 | tcprt对日志格式有扩展,原格式保持兼容。 | |
功能管理 |
|
|
功能配置 | 配置文件:
| 模块参数:
|
系统要求 | Alibaba Cloud Linux 3(内核版本 |
|
功能 |
| 仅支持default解析模式。 |
功能使用
您可以根据实际使用场景选择以下操作使用TCP-RT。
tcprt
Alibaba Cloud Linux 3(内核5.10.134-17及以上版本)。
tcp_rt.ko
Alibaba Cloud Linux 2(内核4.19.91-21.al7及以上版本)。
Alibaba Cloud Linux 3。
因为二者共享相同的日志文件路径,所以不能同时开启,只能使用其中之一。
tcprt
安装与配置。
安装tcprt。
sudo yum install -y tcprt
配置tcprt。
打开
/etc/tcprt-bpf/tcprt.yaml
文件。sudo vim /etc/tcprt/tcprt.yaml
按
i
键进入编辑模式,根据需要进行配置。配置项分为三部分,global、per-port、init,说明如下。
global
参数
说明
可选值
默认值
peer
默认的tcprt端口匹配模式。
false:匹配本地端口。
true:匹配对端端口。
true/false
空
stats
是否开启stats日志输出。
enable/disable
disable
stats_interval
stats输出时间间隔。单位:s。
整数
60
first_frame_bytes
完成时间统计字节数阶梯阈值。单位:byte。
整数列表,最大长度为4
空
per-port。
以列表表示,默认为空,一个元素对应一项端口配置。
参数
说明
可选值
默认值
port
端口号或端口范围。
整数,表示端口号。
逗号分隔的两个整数,表示端口范围,范围为闭区间。
无
peer
该端口(或端口范围)的匹配模式。
true/false
global的peer配置
mode
协议解析模式。default效果与tcp_rt.ko一致。
default/http/https
default
first_frame
是否开启按字节数的完成时间统计。
enable/disable
disable
init。
参数
说明
可选值
默认值
log_buf_num
log文件的子缓冲区个数。
整数
8
log_buf_size
log文件的子缓冲区大小,单位:byte。
每一个log文件最大大小为
log_buf_num * log_buf_size
。整数
262144
stats_buf_num
stats文件的子缓冲区个数。
整数
8
stats_buf_size
stats文件的子缓冲区大小,单位:byte。
stats文件最大大小为
stats_buf_num * stats_buf_size
。整数
16384
配置完成后按
Esc
键,输入:wq
后按Enter
键,保存配置。启动服务,自动解析配置文件。
sudo systemctl start tcprt
设置开机自动(如有需要)。
sudo systemctl enable tcprt
卸载tcprt。
sudo yum remove tcprt
输入
y
按回车键,完成卸载。
配置文件举例tcprt
peer配置为false,表示默认采用本地端口匹配。添加了两项端口配置。
443端口精确匹配:启用HTTPS解析,匹配本地端口。开启“first_frame”功能(即按字节的完成时间统计),数据量阈值阶梯依次为100/2000/20000字节。
56789~56800端口范围匹配:采用默认TCP解析,匹配对端端口。
stats功能关闭。
log文件和stats缓冲区大小采用默认配置。
global:
peer: false
stats: disable
stats_interval: 60
first_frame_bytes: [100, 2000, 20000, 0]
per-port:
-
port: 443
mode: https
first_frame: enable
-
port: 56789,56800
mode: default
peer: true
init:
log_buf_num: 8
log_buf_size: 262144
stats_buf_num: 8
stats_buf_size: 16384
字节数完成时间是通过ACK包统计的,实际数据传输中,一次ACK可能对应大量数据(比如几十KB),因此日志中输出的数据量可能超过文件中的Bytes阈值配置。
tcp_rt.ko
加载与配置模块。
您可以用以下任一方式加载与配置模块。
模块加载时直接配置参数。
在加载tcp_rt模块的同时,将模块配置作为命令参数一并输入。
例如加载tcp_rt模块,并配置lports为80。
sudo modprobe tcp_rt lports=80
查看配置是否生效。
sudo cat /sys/module/tcp_rt/parameters/lports
先加载模块,然后进行配置。
运行以下命令加载模块。
sudo modprobe tcp_rt
模块加载后,在/sys/module/tcp_rt/parameters/路径下,运行命令进行配置。
例如用下面命令配置监控本地80端口。
sudo sh -c 'echo 80 > /sys/module/tcp_rt/parameters/lports'
查看配置是否生效。
sudo cat /sys/module/tcp_rt/parameters/lports
更多参数配置说明与配置命令如下表所示。
参数
说明
默认值
配置命令
stats
是否输出stats。取值范围:
0:否。
1:是。
0
echo 0 > stats
stats_interval
stats输出时间间隔。单位:s。
60
echo 60 > stats_interval
lports
控制采集的本地服务器端口,最多6个。
无
echo 80,800,8080 > lports
pports
TCP连接的对端端口。
无
echo 80,800,8080 > pports
lports_range
本地服务器端口范围,两个为一组,配置命令中表示80-100和1000-2000。
无
echo 80,100,1000,2000 >lports_range
pports_range
TCP连接的对端端口范围,两个为一组,配置命令中表示80-100和1000-2000。
无
echo 80,100,1000,2000 >pports_range
log_buf_num
每一个log文件最大大小为
log_buf_num * 256 k
。只在加载模块的时候可以配置。8
modprobe tcp_rt log_buf_num=10
stats_buf_num
每一个stats文件最大大小为
stats_buf_num * 16 k
。只在加载模块的时候可以配置。8
modprobe tcp_rt stats_buf_num=10
卸载模块。
运行以下命令,停用
tcp-rt
模块,保证不会有新的连接使用TCP-RT。sudo echo 1 > /sys/kernel/debug/tcp-rt/deactivate
运行以下命令判断是否所有连接均未使用
tcp-rt
模块。lsmod
当输出结果中
tcp-rt
模块Used by
为0
时,表示没有连接使用tcp-rt
。当所有连接都不使用
tcp-rt
模块后,运行以下命令卸载tcp-rt
模块。sudo rmmod tcp_rt
常见问题
日志文件大小与配置参数不一致
ls -l
等命令显示文件大小超过配置值,这是正常现象。日志文件位于/sys
虚拟文件系统下,ls -l
结果不代表真实大小(也不占磁盘空间)。实际上,这里相当于累积的总日志量,保持递增。若想检查日志真实大小,可以将日志重定向到文件后查看。
下图展示了在默认配置(2 M)下的示例。可以看到,使用cat
将日志内容重定向到文件后,其实际大小约为2 M,符合预期。