TCP-RT功能的配置说明

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的服务场景为一个并发的请求与响应时,各个阶段如下图所示。

image

客户端(Client)向服务端(Server)发送的第N个请求(request)表示为ReqN,该请求由ReqN-1ReqN-2两个数据包组成。服务端收到第一个包的时间被记录为T0,第二个包的时间被记录为T1。服务端收到请求后进行处理,完成处理后会向客户端发送两个响应的数据包RspN-1RspN-2,服务端发送第一个包的时间被记录为T2。客户端收到响应包后会发送确认信息ACK给服务器,服务端收到最后一个ACK的时间被记录为T3。

TCP-RT基于以上的时间点的记录,可以计算出以下有意义的信息:

  • upload_time:用户请求上传所使用的时间。

  • process_time:服务端的处理时间。

    服务端从收到最后一个请求的数据包开始,到服务端向客户端开始发送响应的数据包为止,这段时间为服务端的处理时间。

  • download_time:数据下载时间。

    从服务端向客户端发送响应的数据包开始,到服务端收到客户端最后一个ACK为止,这段时间为数据下载时间。对于下载比较大的数据响应,该信息的获取较为重要。

信息输出说明

TCP-RT在内核态采集TCP服务的相关参数并输出,下表说明了文件的输出方式与输出时间点。

文件类型

输出方式

输出时间

log文件

debugfs的方式输出到/sys/kernel/debug/tcp-rt路径下,文件名称为rt-network-log*的文件中。该类文件特征如下:

  • 文件名称的后缀为CPU内核的序号。例如:32核的服务器,输出的log文件为rt-network-log0rt-network-log31

  • 文件大小最大为2 MB,当数据超过该限制后,旧数据会被清除。

  • debugfs方式输出的log文件是一次性的,当您读取一次文件数据后,读取部分的数据就被清除了。

  • 时间一:在TCP连接上,当上一个任务(一次请求/响应为一个任务)完成后下一个任务开始时,输出上一个任务的信息。

  • 时间二:在连接关闭时,输出信息。

    在TCP-RT输出信息之后,应用层可以立即读取到数据。

stats文件

该数据是基于端口(服务端端口或客户端端口)进行数据汇总后,输出到/sys/kernel/debug/tcp-rt路径下的rt-network-stats文件中。

定时输出。默认为一分钟输出一次。

解析模式说明

TCP-RT支持多种解析模式,用户可自行配置。具体操作,请参见功能使用

  • default:默认模式。

    基于通用TCP流进行解析,TCP流可以是HTTP、Redis、Mysql等符合请求/响应行为的协议。

  • http:HTTP增强。

    在default模式基础上,额外报告RTT和拥塞窗口信息,并且识别HTTP协议的“Expect: 100-continue”处理过程。将100-continue请求及其响应报告为一条R.C类型记录。更多信息,请参见输出格式说明

  • https:HTTPS增强。

    在http模式的基础上,额外增加了TLS部分报文解析。

    • TLS握手解析:识别TLS 1.2和TLS 1.3的握手阶段,在输出日志中标记出来。更多信息,请参见输出格式说明

      • 对TLS 1.2四次握手,产生两条R.H类型记录。

      • 对TLS 1.3三次握手,产生一条R.H类型记录,并报告握手用时。

    • “Close Notify” Alert报文解析:在输出日志中以R.A记录标记。更多信息,请参见输出格式说明

说明

tcp_rt.ko的解析模式不可配置,仅支持default模式。

输出格式说明

说明

TASK与TCP生命周期释义。

  • TASK表示一次完整的请求+响应(request+response)。

  • TCP生命周期中包含多个TASK。

log文件格式说明

在log文件中,每条记录的每一列都对应了不同的信息。log文件内容示例如下图所示。image按照从左到右的顺序,每一列参数说明如下:

  • 版本号,目前为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记录。

  • TASK发送的数据量。单位:Byte。

  • TASK总耗时。单位:us。

    即第一个请求segment到达与最后一个响应的segment被ack之间的时间间隔。

  • TASK最小的TCP RTT(Round Trip Time)。单位:us。

  • TASK重传发送的TCP报文段(TCP segment)数量。

  • TASK序号。TCP建立后的第一个TASK序号为1。

  • TASK服务延时。单位:us。

    最后一个请求的segment到达第一个响应的segment发送之间的时间间隔。

  • TASK上送延时。单位:us。

    第一个请求segment到达最后一个请求segment到达之间的时间间隔。

  • TASK接收的数据量。单位:Byte。

  • TASK过程是否发生接收乱序。参数值说明:

    • 1:发生。

    • 0:没有发生。

  • TASK过程中TCP使用的最大报文长度(MSS)。单位:Byte。

  • TASK结束时的平滑RTT,http、https解析模式下生效(仅tcprt支持,版本号为V7)。单位:us。

  • TASK结束时的拥塞窗口,http、https解析模式下生效(仅tcprt支持,版本号为V7)。单位:segments。

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中含有Close NotifyAlert报文,该TASK不会计入Alert报文引入额外耗时(即最后一个响应数据包与Alert包之间的用时)。

R.H

说明

仅tcprt支持,版本号为V7。

https解析模式下可能出现,R记录末尾可能附加额外内容。

表示TASK属于TLS握手阶段。若是TLS 1.3(三次握手),日志末尾将报告握手耗时,单位:us。

末尾附加内容格式为H <time>。例如H 151878表示握手用时 151878 us。

R.F

说明

仅tcprt支持,版本号为V7。

开启first_frame后出现(具体操作,请参见功能使用),R记录末尾可能附加额外内容。

表示TASK触发按字节数的完成时间统计。根据配置文件定义的字节数阈值阶梯,划分每个TASK响应数据流,统计各阶梯的数据量与完成时间,附加于记录末尾,单位分别为bytes和us。

末尾附加内容格式为F <n> [bytes time]。例如F 6 7240 214 63698 311 98436 358,表示共有6个数字,7240、63698、98436 Bytes 对应的总耗时依次为214 us、311 us、358 us。

P

该记录是TASK正常启动和关闭的记录,每个TCP服务可以有多个P记录。P是V6版本中新增的记录,表述的是客户端对外请求时的信息。只有配置了选项pportspports_range时才有该记录。

  • TASK发送的数据量。单位:Byte。

  • TASK总耗时。从本地服务器发送数据开始到最后一次收到对端响应的时间。单位:us。

  • TASK最小的TCP RTT(Round Trip Time)。单位:us。

  • TASK重传发送的TCP报文段(TCP segment)数量。

  • TASK序号。TCP建立后的第一个TASK序号为1。

  • TASK服务时间。即从请求发送完成到收到第一个响应的时间。单位:us。

  • TASK响应接收时间。从接收到第一个响应包到最后一个响应包之间的时间。单位:us。

  • TASK接收响应的总大小。单位:Byte。

  • TASK过程是否发生接收乱序。参数值说明:

    • 1:发生。

    • 0:没有发生。

  • TASK过程中TCP使用的最大报文长度(MSS)。单位:Byte。

E

该记录是TCP被关闭的记录。每个TCP连接都有1个E记录,配置了选项pportspports_range的连接也会有该记录。

  • 最后一个TASK的序号。

  • TCP生命周期中发送的数据量。单位:Byte。

  • TCP发送响应但是没有收到ACK的数据量。参数值说明:没有则为0。单位:Byte。

  • TCP生命周期中接收的数据量。单位:Byte。

  • TASK重传发送的TCP报文段(TCP segment)数量。

  • TCP生命周期中最小的TCP RTT(Round Trip Time)。单位:us。

N

该记录是在TASK请求接收报文段(segment)过程中,TCP被关闭场景下的记录。每个TCP连接可能有一个N记录或没有。

  • 最后一个TASK的序号。

  • 最后一个TASK的耗时,因为是被关闭,所以只有接收时间,没有发送时间。单位:us。

  • TCP生命周期中接收的数据量。单位:Byte。

  • TASK过程是否发生接收乱序。参数值说明:1表示发生;0表示没有发生。

  • TASK过程中TCP使用的最大报文长度(MSS)。单位:Byte。

W

该记录是在TASK响应发送的报文段(segment)过程中,TCP被关闭场景的记录。每个TCP连接可能有1个W记录或没有。

  • 最后一个TASK的响应已发送数据量。单位:Byte。

  • 最后一个TASK的耗时,因为是被关闭,所以发送时间是不完整的。单位:us。

  • 最后一个TASK最小的TCP RTT(Round Trip Time)。单位:us。

  • 最后一个TASK重传发送的TCP报文段(TCP segment)数量。

  • 最后一个TASK的序号。

  • 最后一个TASK服务延时。单位:us。

  • 最后一个TASK上送延时。单位:us。

  • 最后一个TASK发送响应但是没有收到ACK确认信息的数据量。参数值说明:没有则为0。单位:Byte。

  • TASK过程是否发生接收乱序。参数值说明:

    • 1:发生。

    • 0:没有发生。

  • 最后一个TASK过程中TCP使用的最大报文长度(MSS)。单位:Byte。

说明
  • 扩展日志类型以R.x格式标记,其中x可以是单个字符(如上表),也可以是多个字符的组合。比如R.AF即表示AF同时生效。

  • R.AR.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的数量。

tcprttcp_rt.ko版本差异

比较项

tcprt

tcp_rt.ko

日志文件路径

相同

日志格式

tcprt对日志格式有扩展,原格式保持兼容。

功能管理

systemctl

modprobe/rmmod

功能配置

配置文件:

/etc/tcprt-bpf/tcprt.yaml

模块参数:

/sys/module/tcp_rt/parameters/*

系统要求

Alibaba Cloud Linux 3(内核版本 5.10.134-17及以上)。

  • Alibaba Cloud Linux 2(内核版本4.19.91-21.al7及以上)。

  • Alibaba Cloud Linux 3。

功能

  • 除default外,支持http、https解析模式。

  • 支持first_frame功能。

仅支持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

  • 安装与配置。

    1. 安装tcprt。

      sudo yum install -y tcprt
    2. 配置tcprt。

      1. 打开/etc/tcprt-bpf/tcprt.yaml文件。

        sudo vim /etc/tcprt/tcprt.yaml
      2. 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

      3. 配置完成后按Esc键,输入:wq后按Enter键,保存配置。

      4. 启动服务,自动解析配置文件。

        sudo systemctl start tcprt
      5. 设置开机自动(如有需要)。

        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

  • 加载与配置模块。

    您可以用以下任一方式加载与配置模块。

    • 模块加载时直接配置参数。

      1. 在加载tcp_rt模块的同时,将模块配置作为命令参数一并输入。

        例如加载tcp_rt模块,并配置lports为80。

        sudo modprobe tcp_rt lports=80
      2. 查看配置是否生效。

        sudo cat /sys/module/tcp_rt/parameters/lports
    • 先加载模块,然后进行配置。

      1. 运行以下命令加载模块。

        sudo modprobe tcp_rt
      2. 模块加载后,在/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

  • 卸载模块。

    1. 运行以下命令,停用tcp-rt模块,保证不会有新的连接使用TCP-RT。

      sudo echo 1 > /sys/kernel/debug/tcp-rt/deactivate
    2. 运行以下命令判断是否所有连接均未使用tcp-rt模块。

      lsmod

      当输出结果中tcp-rt模块Used by0时,表示没有连接使用tcp-rt

    3. 当所有连接都不使用tcp-rt模块后,运行以下命令卸载tcp-rt模块。

      sudo rmmod tcp_rt

常见问题

日志文件大小与配置参数不一致

ls -l等命令显示文件大小超过配置值,这是正常现象。日志文件位于/sys虚拟文件系统下,ls -l结果不代表真实大小(也不占磁盘空间)。实际上,这里相当于累积的总日志量,保持递增。若想检查日志真实大小,可以将日志重定向到文件后查看。

下图展示了在默认配置(2 M)下的示例。可以看到,使用cat将日志内容重定向到文件后,其实际大小约为2 M,符合预期。

image