关于c++:浅谈UDP数据包长度收包能力丢包及进程结构选择

130次阅读

共计 3789 个字符,预计需要花费 10 分钟才能阅读完成。

UDP 数据包长度

UDP 数据包的实践长度

udp 数据包的实践长度是多少,适合的 udp 数据包应该是多少呢?从 TCP-IP 详解卷一第 11 章的 udp 数据包的包头能够看出,udp 的最大包长度是 2^16- 1 的个字节。因为 udp 包头占 8 个字节,而在 ip 层进行封装后的 ip 包头占去 20 字节,所以这个是 udp 数据包的最大实践长度是 2^16-1-8-20=65507。

然而这个只是 udp 数据包的最大实践长度。首先,咱们晓得,TCP/IP 通常被认为是一个四层协定零碎,包含链路层、网络层、运输层、应用层。UDP 属于运输层,在传输过程中,udp 包的整体是作为上层协定的数据字段进行传输的,它的长度大小受到上层 ip 层和数据链路层协定的制约。

【文章福利】小编举荐本人的 linuxC/C++ 语言交换群:832218493!整顿了一些集体感觉比拟好的学习书籍、视频材料共享在群文件外面,有须要的能够自行添加哦!~

MTU 相干概念

以太网 (Ethernet) 数据帧的长度必须在 46-1500 字节之间,这是由以太网的物理个性决定的。这个 1500 字节被称为链路层的 MTU(最大传输单元)。因特网协定容许 IP 分片,这样就能够将数据包分成足够小的片段以通过那些最大传输单元小于该数据包原始大小的链路了。这一分片过程产生在网络层,它应用的是将分组发送到链路上的网络接口的最大传输单元的值。这个最大传输单元的值就是 MTU(Maximum Transmission Unit)。它是指一种通信协议的某一层下面所能通过的最大数据包大小(以字节为单位)。最大传输单元这个参数通常与通信接口无关(网络接口卡、串口等)。

在因特网协定中,一条因特网传输门路的“门路最大传输单元”被定义为从源地址到目标地址所通过“门路”上的所有 IP 跳的最大传输单元的最小值。

须要留神的是,loopback 的 MTU 不受上述限度,查看 loopback MTU 值:

[root@bogon ~]# cat /sys/class/net/lo/mtu

65536

IP 分包 udp 数据包长度的影响

如上所述,因为网络接口卡的制约,mtu 的长度被限度在 1500 字节,这个长度指的是链路层的数据区。对于大于这个数值的分组可能被分片,否则无奈发送,而分组替换的网络是不牢靠的,存在着丢包。IP 协定的发送方不做重传。接管方只有在收到全副的分片后能力 reassemble 并送至下层协定解决代码,否则在应用程序看来这些分组曾经被抛弃。

假设同一时刻网络丢包的概率是均等的,那么较大的 IP datagram 必然有更大的概率被抛弃,因为只有失落了一个 fragment,就导致整个 IP datagram 接管不到。不超过 MTU 的分组是不存在分片问题的。

MTU 的值并不包含链路层的首部和尾部的 18 个字节。所以,这个 1500 字节就是网络层 IP 数据报的长度限度。因为 IP 数据报的首部为 20 字节,所以 IP 数据报的数据区长度最大为 1480 字节。而这个 1480 字节就是用来放 TCP 传来的 TCP 报文段或 UDP 传来的 UDP 数据报的。又因为 UDP 数据报的首部 8 字节, 所以 UDP 数据报的数据区最大长度为 1472 字节。这个 1472 字节就是咱们能够应用的字节数。

当咱们发送的 UDP 数据大于 1472 的时候会怎么呢?这也就是说 IP 数据报大于 1500 字节,大于 MTU。这个时候发送方 IP 层就须要分片(fragmentation)。把数据报分成若干片,使每一片都小于 MTU。而接管方 IP 层则须要进行数据报的重组。而更重大的是,因为 UDP 的个性,当某一片数据传送中失落时,接管不便无奈重组数据报。将导致抛弃整个 UDP 数据报。因而,在一般的局域网环境下,将 UDP 的数据管制在 1472 字节以下为好。

进行 Internet 编程时则不同,因为 Internet 上的路由器可能会将 MTU 设为不同的值。如果咱们假设 MTU 为 1500 来发送数据的,而途经的某个网络的 MTU 值小于 1500 字节,那么零碎将会应用一系列的机制来调整 MTU 值,使数据报可能顺利达到目的地。鉴于 Internet 上的规范 MTU 值为 576 字节,所以在进行 Internet 的 UDP 编程时,最好将 UDP 的数据长度控件在 548 字节 (576-8-20) 以内。

UDP 丢包

udp 丢包是指网卡接管到数据包后,linux 内核的 tcp/ip 协定栈在 udp 数据包处理过程中的丢包,次要起因有两个:

1、udp 数据包格局谬误或校验和查看失败。

2、应用程序来不及解决 udp 数据包。

对于起因 1,udp 数据包自身的谬误很少见,应用程序也不可控,本文不探讨。

首先介绍通用的 udp 丢包检测办法,应用 netstat 命令,加 -su 参数。

netstat -su

Udp:

2495354 packets received

2100876 packets to unknown port received.

3596307 packet receive errors

14412863 packets sent

RcvbufErrors: 3596307

SndbufErrors: 0

从下面的输入中,能够看到有一行输入蕴含了 ”packet receive errors”,如果每隔一段时间执行 netstat -su,发现行首的数字一直变大,表明产生了 udp 丢包。

上面介绍一下应用程序来不及解决而导致 udp 丢包的常见起因:

1、linux 内核 socket 缓冲区设的太小 # cat /proc/sys/net/core/rmem_default

cat /proc/sys/net/core/rmem_max

能够查看 socket 缓冲区的缺省值和最大值。

rmem_default 和 rmem_max 设置为多大适合呢?如果服务器的性能压力不大,对解决时延也没有很严格的要求,设置为 1M 左右即可。如果服务器的性能压力较大,或者对解决时延有很严格的要求,则必须审慎设置 rmem_default 和 rmem_max,如果设得过小,会导致丢包,如果设得过大,会呈现滚雪球。

2、服务器负载过高,占用了大量 cpu 资源,无奈及时处理 linux 内核 socket 缓冲区中的 udp 数据包,导致丢包。

一般来说,服务器负载过高有两个起因:收到的 udp 包过多;服务器过程存在性能瓶颈。如果收到的 udp 包过多,就要思考扩容了。服务器过程存在性能瓶颈属于性能优化的领域,这里不作过多探讨。

3、磁盘 IO 忙

服务器有大量 IO 操作,会导致过程阻塞,cpu 都在期待磁盘 IO,不能及时处理内核 socket 缓冲区中的 udp 数据包。如果业务自身就是 IO 密集型的,要思考在架构上进行优化,正当应用缓存升高磁盘 IO。

这里有一个容易漠视的问题:很多服务器都有在本地磁盘记录日志的性能,因为运维误操作导致日志记录的级别过高,或者某些谬误忽然大量呈现,使得往磁盘写日志的 IO 申请量很大,磁盘 IO 忙,导致 udp 丢包。

对于运维误操作,能够增强经营环境的治理,避免出错。如果业务的确须要记录大量的日志,能够应用内存 log 或者近程 log。

4、物理内存不够用,呈现 swap 替换

swap 替换实质上也是一种磁盘 IO 忙,因为比拟非凡,容易被忽视,所以单列进去。

只有布局好物理内存的应用,并且正当设置零碎参数,能够防止这个问题。

5)磁盘满导致无奈 IO

没有布局好磁盘的应用,监控不到位,导致磁盘被写满后服务器过程无奈 IO,处于阻塞状态。最基本的方法是布局好磁盘的应用,避免业务数据或日志文件把磁盘塞满,同时增强监控,例如开发一个通用的工具,当磁盘使用率达到 80% 时就继续告警,留出短缺的反应时间。

UDP 收包能力测试

测试环境

处理器:Intel(R) Xeon(R) CPU X3440 @ 2.53GHz,4 核,8 超线程,千兆以太网卡,8G 内存

模型 1

单机,单线程异步 UDP 服务,无业务逻辑,只有收包操作,除 UDP 包头外,一个字节数据。

测试后果

景象:

1、单机 UDP 收包解决能力能够每秒达到 150w 左右。

2、解决能力随着过程个数的减少而加强。

3、在解决达到峰值时,CPU 资源并未耗尽。

论断:

1、UDP 的解决能力还是十分可观的。

2、对于景象 2 和景象 3,能够看出,性能的瓶颈在网卡,而不在 CPU,CPU 的减少,解决能力的回升,来源于丢包(UDP_ERROR)个数的缩小。

模型 2

其余测试条件同模型 1,除 UDP 包头外,一百个字节数据。

测试后果

景象:

1、100 个字节的包大小,比拟合乎平时的业务情景。

2、UDP 的解决能力还是十分可观,单机峰值能够达到每秒 75w。

3、在 4,8 个过程时,没有记录 CPU 的占用状况(网卡流量耗尽),不过能够必定的是,CPU 未耗尽。

4、随着过程个数的回升,解决能力没有显著晋升,然而,丢包(UDP_ERROR)的个数大幅降落。

模型 3

单机,单过程,多线程异步 UDP 服务,多线程共用一个 fd,无业务逻辑,除 UDP 包头外,一个字节数据。

测试后果:

景象:

1、随着线程个数的减少,解决能力不升反降。

论断:

1、多线程共用一个 fd,会造成相当大的锁争用。

2、多线程共用一个 fd,当有包来时,会激活所有的线程,导致频繁的上下文切换。

最终论断:

1、UDP 解决能力十分可观,在日常的业务情景中,UDP 个别不会成为性能瓶颈。

2、随着过程个数的减少,解决能力未显著回升,然而丢包个数显著降落。

3、本次测试过程中,瓶颈在网卡,而不在 CPU。

4、采纳多过程监听不同端口的模型,而不是多过程或多线程监听同一个端口。

总结

正文完
 0