《性能之巅》第十章 网络
章节概述:
- 在系统日益分布式(尤其云计算环境)下,网络在性能方面愈发关键,任务包括改进网络延时、吞吐量,消除丢包引发的延时异常。网络分析涉及硬件(物理网络组件如网卡、交换机等)和软件(内核协议栈如TCP/IP 及相关协议行为)。因网络易因性能差受责,本章旨在挖掘实际情况、排除网络责任以推进分析。由五部分构成:
-
- 背景:介绍网络术语、基本模型和关键性能概念。
- 架构介绍:讲解硬件网络组件和网络栈。
- 方法:阐述性能分析的观察法和实验法。
- 分析:说明Linux和Solaris系统中的网络性能工具和实验。
- 调优:讲解可调节参数范例。
10.1术语
-
- 接口:“接口端口”指网络物理连接器;“接口”或“连接”指操作系统可见且可配置的网络接口端口逻辑实例。
- 数据包:通常指IP级可路由的报文。
- 帧:物理网络级报文,如以太网帧。
- 带宽:对应网络类型的最大数据传输率,单位b/s ,如10GbE是10Gb/s的以太网。
- 吞吐量:当前两个网络端点间的数据传输率,单位b/s或B/s 。
- 延时:一个报文往返端点时间或建立连接时间(如TCP握手),不含后续数据传输时间。 其他术语会在本章贯穿,也可参考第2和3章术语部分。
10.2 模型
10.2.1 网络接口
-
- 网络接口是网络连接的操作系统端点,是系统管理员可配置和管理的抽象层。它被映射到物理网络端口,端口连接网络,有分离的传输和接收通道 。
10.2.2 控制器
-
- 网络接口卡(NIC)为系统提供一个或多个网络端口,设有网络控制器,即端口与系统I/O传输通道间传输包的微处理器 。控制器可作为独立板卡或内置于系统主板。
10.2.3 协议栈
-
- 网络通信由协议栈组成,每层实现特定目标。TCP/IP已成为标准,了解OSI模型也有帮助,如OSI会话层常以BSD套接字形式出现在TCP/IP栈里 。
10.3 概念
10.3.1 网络和路由
-
- 网络是由网络协议地址相连的主机组,分多个网络是出于扩展性等原因。广播报文可通过子网隔离。路由管理报文跨网络传递,路由包地址信息在IP数据包头中 。有单播(一对一)和多播(一对多)传输 。
10.3.2 协议
-
- 网络协议如IP、TCP、UDP是系统与设备通信必要条件。不同协议版本(如IPv4和IPv6 )因内核代码路径不同有不同性能特性。系统可调参数也影响协议性能。包长影响性能,TCP/IP和以太网包长54 - 9054B 。
10.3.3 封装
-
- 封装在负载前后添加元数据(包头、包尾 ),增加报文长度和传输开销。
10.3.4 包长度
-
- 包长受网络接口最大传输单元(MTU)限制,以太网多设为1500B ,也支持近9000B的巨型帧,可提高网络吞吐、降低延时。但老旧硬件和错误配置防火墙会影响巨型帧接收,为避免问题,许多系统用1500 MTU 。网络接口卡功能(如TCP卸载、大块段卸载 )提升了1500 MTU帧性能 。
10.3.5 延时
- 主机名解析延时:与远程主机建立连接时,主机名解析为IP地址过程所需时间,如DNS解析,最坏情况超时需几十秒,禁用可避免该延时。
- ping延时:用ping命令测量ICMP echo请求到echo响应的时间,衡量主机间网络跳跃的往返延时,简单易用,许多操作系统默认响应。接收端ICMP echo请求常做中断处理,发送端测量含内核上下文切换等时间 。
- 连接延时:传输数据前建立网络连接的时间,对于TCP连接即TCP握手时间,从客户端发送SYN到接收SYN - ACK的时间 。类似ping延时,但包含更多建立连接及重传丢包的内核代码运行时间 。
- 首字节延时:从连接建立到接收第一个字节数据的时间,包括远程主机接受连接、调度线程及发送首个字节等时间,涵盖目标服务器处理延时 。
- 往返时间:网络包在两个端点往返所需时间。
- 连接生命周期:网络连接从建立到关闭的时间,一些协议支持长连接策略以减少系统开销和连接延时。
10.3.6 缓冲
- 发送端和接收端的缓冲可使网络吞吐量保持高速率,较大缓冲能缓解往返延时影响 。TCP利用缓冲和可变发送窗口提升吞吐量,网络套接字及应用程序也可能利用缓冲 。外部网络组件(如交换机、路由器 )使用高缓冲可能导致缓冲膨胀问题,影响性能,Linux 3.x内核有相关解决功能 。缓冲由端点提供效果最佳,遵循端到端原则。
10.3.7 连接积压队列
- TCP的积压队列用于暂存SYN请求,当连接请求过多超过处理能力,积压队列满会丢弃客户端SYN包,其重传会增加连接时间 。测量积压队列导致的丢包可衡量网络连接饱和度。
10.3.8 接口协商
- 网络接口通过与对端自动协商工作于不同模式,如以太网带宽有10、100、1000、10000MB/s 等,双工模式有半双工和全双工 。网络接口通常用较低速率协商,全双工可双向同时传输利用全部带宽,半双工仅单向传输 。
10.3.9 使用率
- 网络接口使用率用当前吞吐量除以最大带宽计算,全双工下分别计算每个方向使用率,以该方向当前吞吐量除当前协商带宽 。网络接口使用率达100%会成瓶颈。一些操作系统性能统计按包报告,因包长度可变,难以通过吞吐量或使用率建立包与字节数联系 。
10.3.10 本地连接
- 同一系统的两个应用程序间的网络连接为本地连接,使用虚拟网络接口(回送接口 )。分布式应用程序环境中同主机的组件(如Web服务器、数据库服务器、应用服务器 )通过本地连接通信 。
- 通过IP用本地套接字(UNIX域套接字UDS )通信,UDS省略TCP/IP内核代码及协议封装开销,性能更好 。对于TCP/IP套接字,内核检测到本地连接可短路TCP/IP栈以提高性能,在Solaris系统中称为TCP融合 。
10.4 架构
10.4.1 协议
- TCP
-
- 性能特性:传输控制协议,用于建立可靠网络连接。利用缓冲和可变窗口在高延时网络提供高吞吐量,通过阻塞控制避免过度发送。特性包括可变窗口(根据接收方意愿调整发送量)、阻塞避免(防止网络阻塞)、慢启动(小阻塞窗口开始递增) 、选择性确认(减少重要重传)、快速重传(重传确认非连续包)、快速恢复(检测重复确认后恢复性能) 。
- 重要内容
-
-
- 三次握手:主机间建立连接需三次握手,服务器监听,客户端发起连接 。
- 重复确认检测:发送方根据接收方确认包判断包是否丢失,用于快速重传和恢复 。
- 阻塞控制(Reno和Tahoe ):BSD 4.3引入算法,Reno在三次重复确认时减半阻塞窗口等;Tahoe触发快速重传等 。部分系统可选择算法调优。
- Nagle算法:推迟小尺寸包传输,减少网络小包数量,系统可提供禁用参数 。
- 延时ACK:推迟最多500ms发送ACK,合并多个ACK及控制报文,减少网络包数量 。
- SACK与FACK:SACK允许接收方通知发送方收到非连续数据块;Linux默认支持FACK(基于SACK扩展 ),更好控制未完成数据传输,提高性能 。
-
-
- UDP
-
- 性能特性:用户数据报协议,用于发送网络数据报文。协议头简单短小,降低计算和长度开销;无状态,降低连接与传输控制开销;无重新传输,增加连接延时,不保证数据可靠,可能丢失或乱序,不适合多数连接,缺乏阻塞避免 。一些服务(如某些版本NFS )可按需选用TCP或UDP,广播、多播服务只能用UDP 。
10.4.2 硬件
- 接口:物理网络接口发送接收帧,处理传输错误,分电学、光学或无线类型,对应第2层网络标准 。不同接口带宽不同(如以太网有1GbE、10GbE等 ),带宽越高延时越低、成本越高。接口使用率用吞吐量除以协商带宽衡量,多接口全双工时各通道需分别研究 。
- 控制器:物理网络接口由控制器提供,集成于系统板或扩展卡,由微处理器驱动,通过I/O传输通道(如PCI )接入系统,可能成为网络吞吐量瓶颈 。
- 交换机、路由器
-
- 交换机:为连入主机提供专用通信路径,允许多主机同时传输,取代集线器,避免“载波侦听多路访问/碰撞检测”冲突问题 。
- 路由器:在网络间传递数据包,用网络协议和路由表确定最佳路径,平衡负载,因多个路径存在,数据包可能乱序,可能受网络拥塞影响 。
- 其他:网络设备还包括集线器、网桥、中继器、调制解调器等,可能影响网络性能 。
10.4.3 软件
- 网络栈
-
- 网络通信软件包含网络栈、TCP和设备驱动程序。现代内核中网络栈多线程,传入包可由多个CPU处理,可基于IP地址哈希或就近CPU原则分配 。Linux和Solaris系统有不同框架支持该行为。
- Linux
-
- TCP、IP及通用网络驱动软件是内核核心组件,设备驱动程序为附加模块,数据包以struct sk_buff数据类型在内核组件间传递 。
- 数据包高处理率可通过多个CPU处理包和TCP/IP栈实现,如Linux 3.7内核有多种方式:
-
-
- RSS(接收端缩放):现代NIC支持多队列,根据包哈希(如IP地址、TCP端口号 )置入不同队列,由不同CPU处理,同一连接包可由同一CPU处理。
- RPS(接收数据包转向):针对不支持多队列NIC的RSS软件实现,短中断服务例行程序按包头字段哈希映射数据包到CPU。
- RFS(接收转向):类似RPS,但偏向之前处理套接字的CPU,提高CPU缓存命中率和内存本地性。
- 加速接收数据流转向:支持该功能NIC的RFS硬件实现,用流信息更新NIC确定中断哪个CPU 。
- XPS(传输数据包转向):支持多传输队列NIC,允许多个CPU传输队列 。缺乏CPU负载均衡策略时,NIC可能中断同一CPU致其使用率100%成瓶颈,可通过如RFS实现的缓存一致性等策略,或irqbalancer进程分配中断请求给CPU提升网络性能 。
-
- Solaris
-
- 套接字层是内核的sockfs模块,TCP、UDP和IP协议合并为ip模块,数据包以消息块mblk_t穿过内核 。
- GLDv3软件利用垂直视野(每CPU同步机制 )提升性能,用序列化队列(squeue)处理每个连接 。激活IP fanout可在多个CPU间负载均衡传入数据包 。Erik Nordmark在Solaris IP Datapath Refactoring项目中简化网络栈内部结构 。
- TCP
-
- 积压队列:突发连接由积压队列处理,有SYN积压队列(处理TCP握手完成前未完成连接 )和侦听积压队列(处理等待应用程序接收的已建立会话 ) 。早期内核单队列易受SYN洪水攻击,双队列可优化处理,队列长度可调整 。
-
- 缓冲:利用套接字的发送和接收缓冲提升数据吞吐量。写通道中,数据缓存在TCP发送缓冲区,再送IP发送,TCP尽量按MSS长度发送段避免IP分段 。发送和接收缓冲区大小可调,更大尺寸以消耗更多内存为代价提升吞吐性能,Linux内核可基于连接活跃度自动增加缓冲区 。
- 网络设备驱动
-
- 网络设备驱动有环形缓冲区,用于在内核内存与NIC间收发数据包 。随着10GbE引入,利用中断结合模式(如动态轮询 ),中断仅在计时器激活或达到一定数据包数量时发送,减少内核与NIC通信频率,缓冲更多发送,提升吞吐量,牺牲一定延时 。
10.5 方法
本章论述网络分析和调优的多种方法,这些方法可单独或混合使用,建议使用顺序为性能监测、USE方法、静态性能调优和工作负载特征归纳 。
- 工具法:遍历可用工具,检查关键指标,可能忽略工具不可见或低可见度问题,操作较费时。用于网络通信时,可检查netstat -s(查高流量重传和乱序数据包 )、netstat -i(查接口错误计数器 )、ifconfig(仅限Linux,查“错误”“丢弃”“超限” )、吞吐量(Linux用ip(8) ,Solaris用nicstat(1)或dladm(1M) )、tcpdump/snoop(短期使用查网络使用者和可消除操作 )、dtrace/stap/perf(查应用程序与线路选中数据 ) 。发现问题需检查工具各字段了解更多上下文。
- USE方法:定位瓶颈和跨组件错误,对每个网络接口及传输(TX)、接收(RX)方向,检查使用率(接口忙于收发帧时间 )、饱和度(接口负载、额外队列、缓冲或阻塞程度 )、错误(接收校验错误等,传输延时碰撞 ) 。操作系统监控工具一般不直接提供使用率,可用当前吞吐量除以协商带宽计算。实施网络带宽限制环境中,使用率或需按应用限制测量,饱和度可通过网络接口、内核统计信息及TCP层重传统计信息衡量。USE方法可用于网络控制器与处理器间传输通道,基于网络接口统计信息和网络拓扑推测指标 。
- 工作负载特征归纳:做容量规划、基准测试和负载模拟时,分析应用负载特征重要。网络工作负载基础属性包括网络接口吞吐量(RX和TX,B/s )、网络接口IOPS(RX和TX,帧/秒 )、TCP连接率(主动和被动,连接数/秒 ) 。这些特征随时间变化,需随时间推移监测。高级工作负载特征归纳可涵盖平均数据包大小、协议类型、活跃端口、使用网络的进程等信息 。
- 延时分析:研究不同网络延时有助于理解和表述网络性能,常见网络延时包括系统调用发送/接受延时、系统调用连接延时、TCP连接初始化时间、TCP首字节延时、TCP连接持续时间、TCP重传输、网络往返时间、中断延时、跨栈延时等 。延时可通过单位时间间隔平均(隔离中间网络差别 )、完整分布(直方图或热度图 )、每操作延时(列出事件源与目的IP地址 )展示,TCP重传输可能导致延时异常值,可用完整分布或每操作延时跟踪发现 。
- 性能监测:发现当前问题及随时间推移的行为模式,捕捉最终用户数量、定时活动、应用程序活动变化。关键网络指标有吞吐量(网络接口每秒接收与传输字节数 )、连接数(TCP每秒连接数 )、错误(丢包计数器 )、TCP重传输、TCP乱序数据包 。使用网络带宽限制环境中,需收集应用的限额统计数据 。
- 数据包嗅探:也称数据包捕捉,从网络捕捉数据包检查协议报文头和数据,CPU和存储系统开销高,可能是观察性分析最后手段。内核可能利用环形缓冲区减少开销,如Linux的PF_RING选项 。数据包捕捉日志可创建于服务器端用其他工具分析,日志包含时间戳、数据包(协议头和负载数据 )、元数据(数据包数量、丢包数量 ) 。捕捉实现通常允许用户提供过滤表达式和内核过滤以减少系统开销 。
- TCP分析:除延时分析中介绍内容外,还可调查TCP发送/接收缓冲使用、TCP积压队列使用、积压队列导致的内核丢包、阻塞窗口大小(包括零长度通知 )、TCP TIME - WAIT间隔中接收到的SYN 。服务器频繁用相同源和目的IP地址连接另一服务器同一目标端口时,客户端源端口(短暂端口 )受操作系统参数限制,可能出现新连接与处于TIME - WAIT的TCP会话关联而被拒的问题,Linux内核尝试重用或回收连接避免此问题 。
- 挖掘分析:挖掘处理数据包的层次直至网络接口驱动,按需研究内核网络栈内部运行,用于检查网络可调参数是否需调整、确认内核网络性能特性是否生效、解释内核丢包 ,常采用动态跟踪审查内核网络栈函数执行,操作耗时 。
- 静态性能调优:注重解决配置完成环境中的问题,对网络性能,检查网络接口数量、最大速度、协商速度、双工模式、MTU、链路聚合、设备驱动及IP/TCP层可调参数、非默认值参数、路由配置、默认路由、数据路径组件吞吐量、数据转发、系统是否作路由器、DNS设置、网络接口固件和设备驱动及内核TCP/IP栈性能问题、软件施加的网络吞吐量限制等 。这些问题答案可能揭示被忽视的配置选择,网络吞吐量受限问题与云计算尤其相关 。
- 资源控制:操作系统按连接类型、进程或进程组设置控制限制网络资源,包括网络带宽限制(内核针对不同协议或应用程序的允许带宽 )、IP服务品质(网络组件应用的网络流量优先排序,如IP报文头业务类型位 ) 。网络可能存在高低优先级混合流量,资源控制方案可节流低优先级流量,为高优先级流量提供更好性能 。
- 微基准测试:许多基准测试工具可用于网络,调查分布式应用程序环境吞吐量问题时,可确认网络能否达到预期吞吐量,未达到时用其调查网络性能,一般比应用程序简单易测。可测试要素包括方向(发送或接收 )、协议(TCP或UDP及端口 )、线程数、缓冲长度、接口MTU长度 。高速网络接口(如10Gb/s )可能需多个客户线程驱动达到最大带宽 ,10.7.1节会介绍网络微基准测试工具iperf 。
10.6 分析
介绍基于Linux和Solaris操作系统的网络性能分析工具,使用策略参考前文,工具列表如下:
Linux | Solaris | 描述 |
netstat | netstat | 多种网络栈和接口统计信息 |
sar | - | 统计信息历史 |
ifconfig | ifconfig | 接口配置 |
ip | dladm | 网络接口统计信息 |
nicstat | nicstat | 网络接口吞吐量和使用率 |
ping | ping | 测试网络连通性 |
traceroute | traceroute | 测试网络路由 |
pathchar | pathchar | 确定网络路径特征 |
tcpdump | snoop/tcpdump | 网络数据包嗅探器 |
Wireshark | Wireshark | 图形化网络数据包检查器 |
DTrace, perf | DTrace | TCP/IP栈跟踪:连接、数据包、丢包、延时 |
10.6.1 netstat
- 功能:基于不同选项,netstat命令可报告多种网络统计数据。
- Linux系统
-
- 选项功能:默认列出连接的套接字;-a列出所有套接字信息;-s提供网络栈统计信息;-i显示网络接口信息;-r列出路由表;-n不解析IP地址为主机名;-v(可用时)显示冗长详细信息 。
- 接口统计信息示例:数据包括网络接口、MTU及接收(RX - )和传输(TX - )指标,如OK(成功传输数据包 )、ERR(错误数据包 )、DRP(丢包 )、OVR(超限 ) 。丢包和超限是网络接口饱和指针,可结合USE方法检查 。-c连续模式与 -i 一起使用,每秒输出累积计数器及数据包速率数据 。
- 网络栈统计数据示例:输出多项按协议分组的网络数据(多来自TCP ),部分指标如比接收总包数更高速的包转发率(检查服务器是否应转发数据包 )、开放的被动连接(监视客户端连接负载 )、比发送的段数更高的数据报重传数(指示网络不稳定 )、套接字缓冲导致的数据包从接收队列删除(网络饱和标志 ) 。部分统计信息名称拼写有误,可从/proc/net/snmp和/proc/net/netstat读取,也用于SNMP管理信息库(MIB ) 。netstat按时间间隔连续输出累计计数器,后期处理可计算计数速率 。
- Solaris系统
-
- 接口统计信息示例:数据包括网络接口、MTU、网络、接口地址及Ipkts(输入数据包 )、Ierrs(输入数据包错误 )、Opkts(输出数据包 )、Oerrs(输出数据包错误 )、Collis(碰撞数据包 )、Queue(队列,常为零 ) 。提供时间间隔参数时按时间总结接口,-I选项可指定显示接口 。
- 网络栈统计数据示例:输出多种按协议分组的网络统计信息,许多名称基于SNMP网络MIB 。值得关注指标类似Linux,如tcpListenDrop和tcpListenDropQ0(显示套接字监听积压队列和SYN积压队列丢弃数据包 ) 。报告可从kstat、libkstat接口查阅 。提供时间间隔可输出系统启动至今总结及按时间间隔总结(仅显示该间隔统计信息,速率易见 ) 。
10.6.2 sar
- 功能:系统活动报告工具,可观测当前活动,能配置保存和报告历史统计数据。
- Linux版本:提供网络统计信息,选项及对应统计信息如下:
-
- -n DEV:网络接口统计信息,如rxpck/s(接收数据包/秒 )、txpck/s(传输数据包/秒 )等。
- -n EDEV:网络接口错误,像rxerr/s(接收数据包错误/秒 )等。
- -n IP:IP数据报信息,包括irec/s(输入数据报文/秒 )等。
- -n EIP:IP错误统计,如idisc/s(输出的丢弃报文/秒 ) 。
- -n TCP:TCP统计信息,有active/s(新的被动TCP连接/秒 )等。
- -n ETCP:TCP错误统计,如retrans/s(TCP段重传/秒 ) 。
- -n SOCK:套接字使用,包括totsck(TCP使用的总数据包 )等 。
- Solaris版本:不提供网络统计信息,可使用netstat(1M)、nicstat(1)和dladm(1M)替代 。
10.6.3 ifconfig
- 功能:可手动设置网络接口,列出接口当前配置,辅助静态性能调优。
- Linux版本:已被ip(8)命令淘汰,可显示网络接口设置,如网卡硬件地址、IP地址等,计数器与netstat -i命令一致,txqueuelen(发送队列长度 )可优化,对延迟敏感设备设较小值可防高速传输拥塞 。
- Solaris版本:功能逐渐被ipadm(1M)和dladm(1M)命令取代 。
10.6.4 ip
- 功能:Linux的ip(8)命令可配置网络接口和路由,观测其状态与统计信息。
- 统计信息:能显示连接统计信息,除接收(RX)和传输(TX)字节数(与netstat -i一致 ),还方便观测吞吐量,但不支持按时间间隔输出(可利用sar ) 。
10.6.5 nicstat
- 功能:最初基于Solaris系统编写的开源工具,输出网络接口统计信息,如吞吐量、使用率等,适用于USE方法。
- 输出信息:包括自系统启动以来总结及按时间间隔总结的数据,字段有接口名称(Int)、最大使用率(%Util)、反映接口饱和度统计信息(Sat)等 ,支持多种选项,如 -z忽略数值为0的接口,-t显示TCP统计信息 。
10.6.6 dladm
- 功能:在Solaris系统中,dladm(1M)命令可提供接口统计信息(数据包和字节率、错误率、使用率 ),显示物理接口状态 。
- 输出信息:dladm show - link输出接口接收和传输字节总和等,dladm show - link -S可显示千字节速率、数据包率及%Util列;dladm show - phy可显示物理接口状态(如速率、双工模式 ) ,检查接口是否协商到最高速率有助于静态性能调优 。
10.6.7 ping
- 功能:发送ICMP echo请求测试网络连通性。
- 输出信息:输出显示每个往返时间、包丢失率等统计信息,因时间戳由ping命令自己计算,包含处理网络I/O的CPU代码路径时间 。在Solaris中,路由器处理ICMP数据包优先级可能较低,延时可能比正常情况高 。
10.6.8 traceroute
- 功能:发送一系列数据包探测到主机当前路由,利用数据包协议生存时间(TTL)让网关按顺序发送ICMP超时响应报文 。
- 输出信息:显示每一跳响应的三个RTT值,可用于估计网络延时,路径可作为静态性能调优研究对象,网络动态变化可能降低其有效性 。
10.6.9 pathchar
- 功能:类似于traceroute,通过多次重复发送不同长度网络数据包并统计分析,确定每一跳带宽 。
- 现状:很难找到在现代操作系统上工作的版本,运行耗时,虽有减少时间的方法但仍不太实用 。
10.6.10 tcpdump
- 功能:捕捉并检查网络数据包,可输出数据包信息到标准输出或写入文件供后续分析 。
- 输出信息:输出显示数据包时间(毫秒精度 )、源和目标IP地址、TCP报头值等 。可使用选项深入分析,如 -n避免解析IP地址为主机名,-e显示链路层报头 ,在性能分析中,可按时间差(-ttt)或自第一个数据包时间(-tttt)显示 ,还可用表达式过滤数据包(参考pcap - filter(7) ) 。因对CPU和存储开销大,尽量短时间使用,Solaris系统可添加该工具 。
10.6.11 snoop
- 功能:Solaris系统中默认的数据包捕捉和检查工具,工作模式类似tcpdump,能捕捉数据包到文件供后续检查,数据包捕捉文件遵从RFC 1761标准 。
- 使用示例:如捕捉ixgbe0接口数据到/tmp文件,可使用命令
snoop -d ixgbe0 > /tmp/out.snoop
。输出显示已接收数据包,可用安静模式(-q)阻止输出避免网络数据拥塞 。可通过多种选项检查数据包,如 -e -l显示详细信息,-v打印冗长输出,-s设置折断长度截短数据包 ,还可用表达式过滤数据包以提高效率 。
10.6.12 Wireshark
- 功能:图形化的数据包捕捉和检查工具,过去称作Ethereal,可从tcpdump或snoop的转储文件导入数据包,能识别网络接口及相关数据包,翻译数百种协议包头,适用于深层次网络分析 。
10.6.13 DTrace
- 功能:可在内核和应用程序内部检查网络事件,如套接字连接、套接字I/O、TCP事件、数据包传输、积压队列丢包、TCP重传等,支持工作负载特征归纳和延时分析 。
- provider列表:不同层次有稳定和不稳定的provider,应用层稳定的是app,不稳定的是pid等;系统调用层不稳定的是syscall等 。使用稳定provider更可取,若不可用,可使用不稳定的,但需常更新脚本适配软件改动 。
- 套接字连接
-
- 出站连接计数:用
dtrace -n 'syscall::connect:entry {@[execname] = count();}'
可计算connect()系统调用次数,还可输出如PID、进程参数及connect()参数等其他细节 。 - 入站连接计数:通过
dtrace -n 'syscall::accept:return {@[execname] = count();}'
可统计accept()调用次数及相关进程接收连接数 。 - 跟踪特定进程连接:如跟踪ssh进程的connect(),用
dtrace -n 'syscall::connect:entry /execname == "ssh"/ { ustack(); }'
,还能检查相关参数,由soconnect.d脚本实现 。
- 出站连接计数:用
- 套接字I/O
-
- 关联数组跟踪:跟踪
syscall::socket:return
建立关联数组(如is_socket[pid,arg1] = 1;
),对比后续I/O系统调用确认套接字文件描述符,注意清除syscall::close:entry
的值 。 - VFS跟踪:若DTrace版本支持,可通过
fds[].fi_fs
状态跟踪套接字I/O,如用dtrace -n 'syscall::read:entry,syscall::recv:entry /fds[arg0].fi_fs == "sockfs"/ { @[probefunc] = count(); }'
按execname计数套接字读取 ,用类似命令可计数套接字写入 。同时需注意操作系统可能使用系统调用变种(如ready() ),需跟踪 ,还可跟踪系统调用返回值检查I/O长度 。
- 关联数组跟踪:跟踪
- 套接字延时
-
- 连接延时:同步系统调用下,是connect()消耗时间;非阻塞I/O时,是执行connect()至poll()或select()(或其他系统调用)报告套接字就绪的时间 。
- 首字节延时:从执行connect()或从accept()返回,到第一个字节数据由I/O系统调用从套接字接收的时间 。
- 套接字持续时间:同一个文件描述符从socket()到close()的时间,可从connect()或accept()开始计时 ,可通过命令或脚本在系统调用层或其他网络栈层执行测量 。
- 套接字内部活动:在Linux中,用
dtrace -ln 'fbt::sock*:entry'
可列出以sock_开头的函数,单独跟踪这些函数及其参数和时间戳,有助于了解套接字行为 。 - TCP事件
-
- tcp provider探针:稳定的tcp provider有多个探针,如
accept-established
(接收入站连接 )、connect-request
(启动出站连接 )等 ,通过dtrace -n 'tcp::accept-established { @[args[3]->tope_saddr, args[3]->tope_lport] = count(); }'
可跟踪主机接收TCP连接及远程IP地址和本地端口情况 。 - fbt provider跟踪:类似套接字,可用fbt provider跟踪TCP内核运行,列出
dtrace -ln 'tcp:::'
可查看相关探针,用fbt provider跟踪能发掘更多内核代码细节 。
- tcp provider探针:稳定的tcp provider有多个探针,如
- 数据包传输:当tcp provider无法触及或不可用时,可用fbt provider调查内核内部运行 。如在Linux中,用
dtrace -n 'fbt::ip_output:entry { @[stack(100)] = count(); }'
跟踪ip_output(),用dtrace -n 'fbt::tcp_sendmsg:entry { @["TCP send bytes"] = quantize(arg3); }'
统计TCP发送长度 ,可使用单命令或脚本调查TCP重传和积压队列丢包等问题 。
重传输跟踪
- 功能:研究TCP重传输有助于调查网络健康状况,DTrace能以较低系统开销实时检查重传输 。
- Linux 3.2/6版本内核脚本示例:使用脚本跟踪tcp_retransmit_skb()函数,输出包含时间、目的IP地址及内核栈跟踪信息,有助于解释重传输原因 ,还可独立跟踪每个内核栈函数了解更多细节 。
- SmartOS脚本示例:针对SmartOS开发的脚本输出显示TCP重传输目的IP地址及内核TCP状态 。
积压队列丢包
- 功能:通过脚本判断积压队列调优是否必要及有效 。
- 脚本原理:该脚本利用获取TCP状态的fbt provider和丢包计数的mib provider 。
- 示例输出分析:输出显示缓存的进程ID(cpid)、当前套接字积压队列最大长度(max_q)以及积压队列长度分布图 。如PID 11504有34个积压队列丢包,最大积压队列长度为128,多数时间队列长度为0,可能需增加队列长度;而另一个示例中积压队列常达极限128,意味着应用程序过载且资源(通常是CPU)不足 。通常在丢包发生时调整积压队列,netstat -s中的tcpListenDrops可观测丢包,此DTrace脚本可预测丢包并在问题出现前调整 。
更多跟踪
- 高级网络跟踪脚本列表:表10.8列出众多DTrace脚本,涵盖socket、IP、TCP、UDP、ICMP等不同层次和协议 。如soconnect.d跟踪客户端套接字connect(),显示进程和主机;tcpaccept.d是入站TCP连接摘要等 。这些脚本可在《Network Lower-Level Protocols》中DTrace章节找到,也可在互联网获取 。此外,《DTrace》书中的Application Level Protocols章节还提供了跟踪NFS、CIFS、HTTP等协议的脚本 。但部分动态跟踪脚本与特定内核内部结构紧密相关,需随内核版本更新维护,部分脚本基于特定DTrace provider,可能特定操作系统暂无可用版本 。
10.6.14 SystemTap
- 功能:在Linux系统中可动态跟踪文件系统事件,如需转换之前的DTrace脚本,可参考第4章4.4节及附录E 。
10.6.15 perf
- 功能:作为第6章介绍的LPE工具包中的工具,能提供静态和动态跟踪网络事件功能,可确定导致内核网络活动的栈跟踪,通过后期处理可开发更高级工具 。
- 示例:用
perf probe --add='tcp_sendmsg'
添加新事件,perf record -e probe:tcp_sendmsg -aR -g sleep 5
记录事件,perf report --stdio
显示调用图(栈跟踪 ),输出展示了导致内核调用tcp_sendmsg()并由TCP连接发送数据的sshd栈跟踪 。此外,还有如skb_free_skb
等预定义网络跟踪点事件,可用于套接字缓存事件和网络设备相关的网络调查 。
10.6.16 其他工具
- Linux工具
-
- strace(1):跟踪套接字相关系统调用并检查使用选项,但系统开销较高 。
- lsof(8):按进程ID列出包括套接字细节在内的打开文件 。
- ss(8):提供套接字统计信息 。
- nfsstat(8):获取NFS服务器和客户机统计信息 。
- iftop(8):按主机(嗅探)总结网络接口吞吐量 。
- /proc/net:包含许多网络统计信息文件 。
- Solaris工具
-
- truss(1):跟踪套接字相关系统调用并检查使用选项,系统开销较高 。
- pfiles(1):按进程检查使用中的套接字,包括选项和套接字缓存大小 。
- routeadm(1M):检查路由和IP转发状态 。
- nfsstat(1M):提供NFS服务器和客户机统计信息 。
- kstat:提供源自网络栈和网络设备驱动的统计信息(很多在源代码外无文档 ) 。
- 其他:还有许多基于SNMP或定制代理软件的网络监测解决方案 。
10.8 调优
网络调优通常基于已调整好的可调节参数和能动态响应工作负载的网络栈,需先理解网络使用情况,借助前文工具进行工作负载特征分析和静态性能调优,不同操作系统版本参数有别,需参考对应文档 。
10.8.1 Linux
- 参数查看与设置:可用sysctl(8)命令查看和设置可调参数,写入/etc/sysctl.conf,也可在/proc文件系统中读写(位于/proc/sys/net下 ) 。如通过
sysctl -a | grep tcp
可查看TCP相关参数,内核(3.2.63)中有63个含tcp的可调参数,net下更多,涉及IP、Ethernet、路由和网络接口 。 - 套接字和TCP缓冲
-
- 设置最大套接字缓冲:所有协议类型读(rmem_max)和写(wmem_max)的最大套接字缓冲大小可设置,如
net.core.rmem_max = 16777216
,对于10GbE连接,数值可能需设为16MB或更高 。 - 启用TCP接收缓冲自动调整:
tcp_moderate_rcvbuf = 1
。 - TCP读写缓冲自动调优参数:
net.ipv4.tcp_rmem
和net.ipv4.tcp_wmem
分别设置读、写缓冲相关参数,每个参数有最小、默认和最大字节数,默认值自动调整,提高吞吐量可增加最大值 。
- 设置最大套接字缓冲:所有协议类型读(rmem_max)和写(wmem_max)的最大套接字缓冲大小可设置,如
- TCP积压队列
-
- 半开连接积压队列:
tcp_max_syn_backlog = 4096
。 - 侦听积压队列:
net.core.somaxconn = 1024
,两者数值或许需从默认值调高,如4096和1024或更高,以应对突发负载 。
- 半开连接积压队列:
- 设备积压队列:增加每CPU的网络设备积压队列长度,如
net.core.netdev_max_backlog = 10000
,对于10GbE的NIC,可能需增加到10000 。 - TCP阻塞控制
-
- 查看可用算法:
sysctl net.ipv4.tcp_available_congestion_control
,当前可用cubic reno
。 - 添加新算法:如添加htcp算法,可执行相关命令
modprobe tcp_htcp
等 。 - 选择算法:
net.ipv4.tcp_congestion_control = cubic
。
- 查看可用算法:
- TCP选项:如SACK和FACK扩展相关参数,
net.ipv4.tcp_sack = 1
等,可在高延时网络中提高吞吐量,但以一定CPU为代价 。tcp_tw_reuse
可使两个主机在安全连接(如Web服务器和数据库服务器 )间重用TIME - WAIT会话,避免达到16b的TIME - WAIT会话临时端口极限;tcp_tw_recycle
也是重用方法,但安全性不如前者 。 - 网络接口:可使用ifconfig(8)增加TX队列长度,如
ifconfig eth0 txqueuelen 10000
,对于10GbE NIC可能必需,可添加到/etc/rc.local以便启动时应用 。 - 资源控制:控制组(cgroups)的网络优先级(net.prio)子系统能对进程或进程组出站网络通信应用优先级,照顾高优先级网络通信(如生产负载 ),配置优先级数值会翻译为IP ToS水平或类似方案并包含于数据包中 。
10.8.2 Solaris
- 参数设置与查看:参数设置或查看可由ndd(1M)命令完成,也可通过/etc/system设置由ndd(1M)查看,现正迁移到ipadm(1M)命令(统一灵活的管理IP栈属性工具 ) ,如用
ipadm show - prop
可列出相关属性 。通常需参考对应版本的《Solaris Tunable Parameters Reference Manual》,确定参数能否修改及修改前是否需被供应商禁止 。 - 缓冲
-
- 设置多种可调参数:如
ndd -set /dev/tcp tcp_max_buf 16777216
等,tcp_max_buf
是setsockopt()能设置的最大套接字缓冲,tcp_cwnd_max
是TCP阻塞窗口最大值,tcp_xmit_hiwat
和tcp_recv_hiwat
用于设置网络设备发送和接收TCP窗口大小,在ipadm(1M)中对应send_maxbuf
和recv_maxbuf
。
- 设置多种可调参数:如
- TCP积压队列
-
- 调整积压队列参数:如
ndd -set /dev/tcp tcp_conn_req_max_q0 4096
,q0
参数对应半开队列,q
参数对应监听积压队列,两者数值或许需从默认值调高,如4096和1024或更高,以应对突发负载 。
- 调整积压队列参数:如
- TCP选项
-
- 调优参数:
tcp_smallest_anon_port
可降低到10000,提高可用临时端口范围;tcp_time_wait_interval
可由默认的60000降低(单位毫秒 ),但RFC 1122禁止重用TIME - WAIT会话,此参数可能被禁止;tcp_iss_incr
降低有助于内核检测新会话并自动重用TIME - WAIT会话(已添加到Illumos内核 );tcp_slow_start_initial
通常设为允许的最大值,可使TCP会话更快达到高输出 。
- 调优参数:
- 网络设备
-
- 激活IP扇出:
ndd ip:ip_squeue_fanout=1
,可将网络负载分布到所有CPU提高性能,默认关联处理创建连接的CPU,可能导致负载分配不均,使部分CPU使用率达100%成瓶颈 。
- 激活IP扇出:
- 资源控制:dladm(1M)工具可设置网络接口属性(如maxbw设最大带宽 ),应用到虚拟接口(如云计算客户租户 )使其成为控制流量的机制 ;flowadm(1M)工具提供更精细控制,能定义流、分配传输(TCP)和端口,包含maxbw和priority属性,优先级可设为“低”“正常”“高”或“实时” ,基于Solaris的系统还有IP QoS(IPQoS),由ipqosadm(1M)设置 。
10.8.3 配置
- 以太网巨型帧:若网络基础架构支持,将默认MTU从1500增加到9000左右可提高网络吞吐性能 。
- 链路聚合:多个网络接口可组合合并带宽成一个接口,需交换机支持并配置才能正常工作 。
- 套接字选项:应用程序可用setsockopt()调优缓冲区大小,增加到系统极限可提高网络吞吐性能,此方法对Linux和Solaris操作系统通用 。