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、采纳多过程监听不同端口的模型,而不是多过程或多线程监听同一个端口。
总结