Alibaba Cloud Linux 2在内核版本kernel-4.19.91-21.al7开始支持TCP层的服务监控功能(TCP-RT)。

背景信息

TCP-RT本质是一种trace方式。通过在内核TCP协议栈中相应的位置设置埋点,可以在单个连接上只有一个并发请求与响应的场景下识别出请求与响应,进而获取请求在协议栈中接收的时间及服务进程处理过程中的耗时等数据信息。此外,TCP-RT还支持在内核系统中做统计分析,定期输出指定连接的统计信息。

TCP-RT适用于在一个连接上只有一个并发请求与响应的服务。例如:HTTP/1.1协议的Web服务、MySQL数据库服务、Redis服务等。

功能原理

当TCP的服务场景为一个并发的请求与响应时,各个阶段如下图所示。TCP-RT

在上图中,客户端(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文件中。 定时输出。默认为一分钟输出一次。

输出格式说明

本章节主要介绍输出的log与stats文件格式说明。
说明 下文中描述的TASK与TCP生命周期释义:
  • TASK表示一次完整的请求+响应(request+response)。
  • TCP生命周期中包含多个TASK。
  • log文件格式说明
    在log文件中,每条记录的每一列都对应了不同的信息。log文件内容示例如下图所示。log file按照每一条记录值从左到右的顺序。参数说明如下:
    • 版本号,目前为V6。
    • 记录场景标识,目前分为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总耗时。即从TCP服务收到客户端请求到收到客户端发送的ACK确认信息之间的时间间隔。单位:us
    • TASK最小的TCP RTT(Round Trip Time)。单位:us
    • TASK重传发送的TCP报文段(TCP segment)数量。
    • TASK序号。TCP建立后的第一个TASK序号为1。
    • TASK服务延时。即最后一个请求的segment到达第一个响应的segment发送之间的时间间隔。单位:us
    • TASK上送延时。即第一个请求segment到达最后一个请求segment到达之间的时间间隔。单位:us
    • TASK接收的数据量。单位:Byte
    • TASK过程是否发生接收乱序。参数值说明:1表示发生;0表示没有发生。
    • TASK过程中TCP使用的最大报文长度(MSS)。单位:Byte
    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连接可能有1个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过程中TCP使用的最大报文长度(MSS)。单位:Byte
    说明 在上表涉及TASK发送数据量的这类信息中,如果是连接的最后一个TASK,正常处理会减去关闭连接(fin)占用的一个snd_nxt值。而如果连接是异常关闭的,例如一个TASK完成之后收到了异常终止报文(reset)并且连接也是以响应reset结束的,则实际发送的数据量会大于这里显示值一个字节。正常情况下,该类值都是正确的,并且异常的情况下只误差一个字节。
  • stats文件格式说明

    按照每一条记录值从左到右的顺序。参数说明如下:

    • 记录输出时的时间戳。
    • 保留字段,目前唯一值为all
    • 端口号。
    • R记录中TASK总耗时的平均值。
    • R记录中TASK服务延时的平均值。
    • 丢包千分数(‰)。
    • RTT的平均值。单位:us
    • 请求发送的数据中,被关闭的TASK数量的千分数(‰)。
    • TASK发送的数据量的平均值。
    • TASK上送延时的平均值。
    • TASK接收的数据量的平均值。
    • 参与统计的TASK的数量。

功能使用

您可以通过以下操作使用TCP-RT。

  1. 加载与配置模块。
    您可以用以下任一方式加载与配置模块:
    • 模块加载时直接配置参数。

      例如:modprobe tcp_rt lports=80

    • 先加载模块,然后进行配置。
      1. 运行以下命令加载模块。
        modprobe tcp_rt
      2. 模块加载后,在/sys/module/tcp_rt/parameters/路径下,运行命令进行配置,参数配置说明与配置命令如下表所示。
        参数 说明 默认值 配置命令
        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
  2. 卸载模块。
    1. 运行以下命令,停用tcp-rt模块,保证不会有新的连接使用TCP-RT。
      echo 1 > /sys/kernel/debug/tcp-rt/deactivate
    2. 运行以下命令判断是否所有连接均未使用tcp-rt模块。
      lsmod
      当输出结果中tcp-rt模块Used by0时,表示没有连接使用tcp-rt
    3. 当所有连接都不使用tcp-rt模块后,运行以下命令卸载tcp-rt模块。
      rmmod tcp_rt