https://blog.csdn.net/dog250/article/details/52502623

一直以来,提到这个话题,大家更多的关注的是tcpdump抓包本身的性能,比如能不能应付几十万的pps,能否在万兆网络上自运自如...我们现在知道,这些问题的答案都是否定的,即“不能”!因此你应该去关注netmap高性能抓包方案以及DPDK这样的东西...

但本文不谈这些,本文谈的是被抓取数据包以外的东西,即tcpdump对那些未被命中抓包规则的数据包性能的影响。

接口和实现

不得不说,有的时候一些教诲是错的。比如说关注接口而不关注实现。信奉此信条的,不知踩了多少坑。对于tcpdump而言,你可能只需要关注tcpdump可以抓包就好了,而不必去关注tcpdump是怎么抓包的。事实上,对于tcpdump是怎么抓包的细节,我敢肯定大多数人,包括一些老资格的高级工程师都是不知道的,大多数情况下,很多人只是知道某个接口可以完成某件事情,对于完成该事情的能力上限却没有任何认知。

在编程中我们也经常遇到这种事,比如Java中有HashMap,大多数人根本不管这个HashMap是怎么实现的,只知道它是一个高效的查询容器,Set了一个Value后,便可以通过其Key在任意时间Get出来,悲哀的是,即便在性能攸关的场景中,很多人还会无条件调用该接口,然后就出现了一个必须加班到深夜才可以排除的故障。我们知道,性能攸关的场景要求你对每一个步骤都了如指掌,这就站在了“关注接口而不是关注实现”的反面!

然而,有人说“关注接口而不是关注实现”就一定正确吗?没有!这只是在软件工程某个领域的某个细节上是正确的,可以快速开发和迭代,对于训练熟练工是好的,但是对于像我这样的人,那显然是不够的。这也是我没有掌握也没兴趣掌握各种“框架”的本质原因吧。

我来说一下我遇到过的事情。

2011年,我遇到一个性能问题,最终的瓶颈是nf_conntrack,过滤的项目太多了,但是抛开这个具体场景不说,如果你的iptables规则设置太多了,也会影响性能,这需要你对iptables的执行机制有充分的理解。

2013年,再次遇到一个性能问题,CPU,eth0网卡满载的情况下,pps急剧下降,后来发现是eth1网卡疯了导致,不断的up/down,导致路由表不断更新,我说这个eth1状态更新有问题,然而别的程序员却并不买账,eth1怎么可能影响eth0呢?想想也是哦...后来“只关注接口”的程序员试图默默重现该问题,写了一个脚本不断up/down这个eth1,然后观察eth0的变化,结果没有重现,我后来之处了问题所在:在模拟重现的过程中,你们的路由项加的太少了,加入10万条路由试试!问题的关键不在eth1的up/down,而是其up/down导致的路由表更新的锁操作。排查该问题,需要你对路由查找的算法,路由表更新的锁操作有充分的理解,只了解路由表的增删改查接口以及网卡的up/down接口是没有用的。

近日,我被要求在10万级pps(来自百万级的IP地址)不衰减的情况,同步执行tcpdump抓取特定数据包。预研阶段我认为瓶颈可能会在BPF Filter,因为几年前我曾经研究过它的执行细节,按照线性过滤的执行规则,这明显是一个O(n)算法,且还要受到CPU Cache抖动的影响....高速网络中任意的O(n)操作都会指数级拉低性能!于是我考虑采用HiPAC多维树匹配代替BPF,最终由于耗时久,动作场面大讨论没通过而作罢。本着数据说话的原则,还是花了两天时间来验证tcpdump一下子过滤几千个IP地址是不是真的影响性能,结果是,和料想的一样,真的影响性能。

感官的印象

我不想通过iperf,netperf,hping3之类的玩意儿来验证,因为这些都是基于socket的,万一在数据发送端遇到协议栈的瓶颈,就很悲哀,因此,我试图通过一种绕开发送端协议栈的发包方案,这样显然可以节省几乎一半的排查工作量。感谢有pktgen!

以下是发包脚本:

modprobe pktgen

echo rem_device_all >/proc/net/pktgen/kpktgend_0

echo max_before_softirq 1 >/proc/net/pktgen/kpktgend_0

echo clone_skb 1000 >/proc/net/pktgen/lo

echo add_device eth2 >/proc/net/pktgen/kpktgend_0

echo clone_skb 1000 >/proc/net/pktgen/eth2

echo pkt_size 550 >/proc/net/pktgen/eth2

echo src_mac 00:0C:29:B0:CE:CF >/proc/net/pktgen/eth2

echo flag IPSRC_RND >/proc/net/pktgen/eth2

echo src_min 10.0.0.2 >/proc/net/pktgen/eth2

echo src_max 10.0.0.255 >/proc/net/pktgen/eth2

echo dst 1.1.1.1 >/proc/net/pktgen/eth2

echo dst_mac  00:0C:29:A9:F3:DD >/proc/net/pktgen/eth2

echo count 0 >/proc/net/pktgen/eth2

echo pkt_size 100 >/proc/net/pktgen/eth2

echo start >/proc/net/pktgen/pgctrl

以上脚本运行在机器A上,在与其直连的机器B上用sysstat来观察:

sar -n DEV 1

然后在机器B上执行下面的脚本:

# 此例子中,我仅仅是启2个tcpdump,每一个过滤600个IP地址,而已!循环参数可以任意调。

i=0

j=0

k=0

for ((k=1;k<2;k++)); do

src='tcpdump -i any src '

for ((i=1;i<30;i++)); do

for ((j=20;j<50;j++)); do

temp=$src" 192.$k.$i.$j or src"

src=$temp

done

done

src=$src" 192.168.11.11 -n"

echo $src

$src &

done

然后,sar的输出结果变化了吗?什么原因导致的呢?

PS:当然上面的pktgen发包方式是我默默做的,在实际中,我还是要使用程序员认可的东西,比如iperf,netperf,hping3之类低效的东西。我并不否认iperf,netperf,hping是好东西,我只是觉得它们在这个测试场景中大材小用了。

tcpdump抓包的架构

上一节的测试我希望看到此文的人自己去测试,这样感官印象更深刻些,不然太多的结果贴图,难免有凑篇幅之嫌了。

本节,我给出目前tcpdump底层pcap的抓包原理,如下图所示:

这是标准的libpcap/tcpdump的结构,一个串行的,同步的抓包结构,当然,也许你已经接触过DPDK,netmap等,这些当然比libpcap/tcpdump更加优秀,但是面临的问题是开发周期太长,以netmap为例,如果你想用它最高效的模式,那就要牺牲对传统协议栈的兼容,反之,如果你想不patch驱动,不编译内核就能用,那你得到的也仅仅是一个兼容PACKET套接字的libpcap/tcpdump的兼容方案。

另外,上述流程图中的很多细节我并没有叙述,比如缓冲区的组织形式,是使用copy还是mmap等等,但是这并不阻碍我们对其的理解,在微秒,甚至毫秒级的BPF开销下,内存操作开销真的不算什么了。

总之,和之前遇到的iptables,路由表等问题一样,抓包也是一个有其能力极限的机制,它是好东西,但不要指望它在哪里都能帮你的忙-如果不是帮倒忙的话!

我们来看一下高性能网络上的一些数据包分析的方案。比如在汇聚层,甚至核心层,我要是想对数据包进行审计,该怎么办?用tcpdump吗?....可以这么说,这个层次上,同步的抓包几乎是不可能的,一般都是使用端口镜像的方式,然后在另一台机器上去处理,这台专门处理数据包审计的机器一般都是众核机器,超多的CPU,超高的并行并发处理能力,当然,这是需要花钱的,这也是一种负责人的做法,另外一种不负责任的做法是什么呢?是类似tcpdump的做法,完全串行同步处理,这样会慢,但慢不是问题,问题是一定不能漏,这种思维其实是错误的,特别是在基于统计的互联网络上,任何事情都不精确,任何事情都不绝对。

在网络上,80%就是全部!

---------------------

作者:dog250

来源:CSDN

原文:https://blog.csdn.net/dog250/article/details/52502623

版权声明:本文为博主原创文章,转载请附上博文链接!

------------------------------

tcpdump丢包分析

https://blog.csdn.net/blade2001/article/details/41543297

tcpdump丢包分析

  通过tcpdump抓包时,结束后tcpdump会给出如下统计信息:
  1552 packets captured
  1586 packets received by filter
  34 packets dropped by kernel
  
  其中“captured”的计数指的是应用层捕获到的数据,“received by filter”和“dropped by kernel”的计数由内核维护,应用层通过getsockopt来获取。收到一个包,“received by filter”会加1,如果sock的接收buffer被填满时,则把这个数据包丢弃,将“dropped by kernel”加1。
  if (atomic_read(&sk->sk_rmem_alloc) + skb->truesize >= (unsigned)sk->sk_rcvbuf){
   spin_lock(&sk->sk_receive_queue.lock);
   po->stats.tp_drops++;
   spin_unlock(&sk->sk_receive_queue.lock);
  }
  通过调节/proc/sys/net/core/rmem_default和/proc/sys/net/core/rmem_max能够改变sk_rcvbuf的大小。
  
  正常“captured”加上“dropped by kernel”应该等于“received by filter”的大小,有的时候出现不等的情况应该是还有一些数据包在sk_rcvbuf中,还没有被应用层收到的原因。

丢包原因:
经过google以及分析,造成这种丢包的原因是由于libcap抓到包后,tcpdump上层没有及时的取出,导致libcap缓冲区溢出,从而覆盖了未处理包,此处即显示为dropped by kernel,注意,这里的kernel并不是说是被linux内核抛弃的,而是被tcpdump的内核,即libcap抛弃掉的

解决方法:
 根据以上分析,可以通过改善tcpdump上层的处理效率来减少丢包率,下面的几步根据需要选用,每一步都能减少一定的丢包率
 1. 最小化抓取过滤范围,即通过指定网卡,端口,包流向,包大小减少包数量
 2. 添加-n参数,禁止反向域名解析
 3. 添加-B参数,加大OS capture buffer size
 4. 指定-s参数, 最好小于1000
 5. 将数据包输出到cap文件
 6. 用sysctl修改SO_REVBUF参数,增加libcap缓冲区长度:/proc/sys/net/core/rmem_default和/proc/sys/net/core/rmem_ma
 
-B buffer_size
Set the operating system capture buffer size to buffer_size, in units of KiB (1024 bytes).
-n
Don't convert addresses (i.e., host addresses, port numbers, etc.) to names.
-s snaplen
--snapshot-length=snaplen
Snarf snaplen bytes of data from each packet rather than the default of 65535 bytes. Packets truncated because of a limited snapshot are indicated in the output with ``[|proto]'', where proto is the name of the protocol level at which the truncation has occurred. Note that taking larger snapshots both increases the amount of time it takes to process packets and, effectively, decreases the amount of packet buffering. This may cause packets to be lost. You should limit snaplen to the smallest number that will capture the protocol information you're interested in. Setting snaplen to 0 sets it to the default of 65535, for backwards compatibility with recent older versions of tcpdump.

http://blog.tianya.cn/blogger/post_read.asp?BlogID=227219&PostID=16646525
http://blog.csdn.net/cszhouwei/article/details/17798271

https://blog.csdn.net/dog250/article/details/52502623

转载于:https://www.cnblogs.com/e-shannon/p/10689289.html

zt:tcpdump抓包对性能的影响相关推荐

  1. tcpdump抓包对性能的影响

    from:http://blog.csdn.net/dog250/article/details/52502623?ref=myread 一直以来,提到这个话题,大家更多的关注的是tcpdump抓包本 ...

  2. Linux基础急速入门:用 TCPDUMP 抓包

    简介 tcpdump是一个用于截取网络分组,并输出分组内容的工具.凭借强大的功能和灵活的截取策略,使其成为类UNIX系统下用于网络分析和问题排查的首选工具 tcpdump 支持针对网络层.协议.主机. ...

  3. tcpdump抓包分析 https://www.01hai.com/note/av263669

    转:tcpdump抓包分析(强烈推荐) 内容预览: 转自:https://mp.weixin.qq.com/s?__biz=MzAxODI5ODMwOA==&mid=266...~ .,表示没 ...

  4. Wireshark抓包以及tcpdump抓包

    tcpdump抓包命令 tcpdump 的抓包保存到文件的命令参数是-w xxx.cap 抓eth1的包 tcpdump -i eth1 -w /tmp/xxx.cap,.cap文件可以用wiresh ...

  5. tcpdump抓包,并保存为文件

    首选介绍一下tcpdump的常用参数 tcpdump采用命令行方式,它的命令格式为: tcpdump [ -adeflnNOpqStvx ] [ -c 数量 ] [ -F 文件名 ] [ -i 网络接 ...

  6. tcpdump抓包分析(强烈推荐)

    https://blog.csdn.net/wojiuguowei/article/details/102475262 1 起因 前段时间,一直在调线上的一个问题:线上应用接受POST请求,请求bod ...

  7. 转:tcpdump抓包分析(强烈推荐)

    时间:2017-11-13 19:50:17      阅读:26788      评论:0      收藏:0      [点我收藏+] 标签:部分   cpp   序列   客户   类型   增 ...

  8. 关于fi dd ler 手机抓包 网卡地址地址_大年别闲着,跟我来学tcpdump抓包

    快过年了,首先祝福大家新年好,猪年吉祥,阖家团圆,万事如意!在吃喝玩乐睡之余是不是还觉得很闲?很闲?别慌,不怕的,正好可以利用这段时间学点技术提升自己,今天虫虫就给大家奉上新年技术第一波,tcpdum ...

  9. 服务器专栏——服务器抓包-tcpdump抓包

    文章目录 1.确认服务器网卡有IP地址: 2.服务器抓包-tcpdump抓包命令 1.确认服务器网卡有IP地址: linux系统:ifconfig,查看网卡ip 1.如果网卡没有ip则不能使用含有此网 ...

最新文章

  1. MetaSploit攻击实例讲解------攻击445端口漏洞(kali linux 2016.2(rolling))(详细)
  2. SQLyog连接Mysql8.0提示 Authentication plugin ‘caching_sha2_password‘ cannot be loaded
  3. echarts x和数据对应_echarts 折线图动态x轴及数据
  4. (转)基于即时通信和LBS技术的位置感知服务(一):提出问题及解决方案
  5. System.Timers.Timer 嵌套 System.Windows.Forms.Timer的问题
  6. oracle找到表的位置,查看Oracle表中的指定记录在数据文件中的位置
  7. [KMP]一本通(http://ybt.ssoier.cn:8088) 1698:字符串匹配
  8. python使用shell命令_python 调用shell命令的方法
  9. 我是如何拿到百度计算机视觉暑期实习offer的?百度面经(成功上岸!已拿offer)
  10. dispatcher在java中什么含义_java-我可以使用在DispatcherServlet上下文中声...
  11. mysql查询字段数据是否有空格_mysql查询条件字段值末尾有空格也能查到数据问题...
  12. 多路测温系统C51语言,51单片机多路DS18B20温度测量程序
  13. Java常用框架介绍
  14. 忘记了mysql的root密码(分享:重置密码过程)
  15. 【FINAL】NOI
  16. SMT表面贴片工序详解
  17. JavaScript面试问题:事件委托和this
  18. seo (百度百科 仅截取小部分)
  19. Android 混淆机制详解
  20. 咸鱼前端—js 函数

热门文章

  1. JAVA imread_利用Matlab中的imread怎么读取图片
  2. 一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字
  3. C++ 中 freopen()函数的用法
  4. js中prototype,constructor的理解
  5. [GO]append的扩容
  6. Leetcode题解(十三)
  7. MVVM中数据验证之 ViewModel vs. Model
  8. [导入]Reporting Services 5: Extensions Custom Report Item
  9. 望图知意-Yahoo VS 3721
  10. Drools集成SpringBoot