netstat -s统计输出的所有字段详细解释

今天工作上碰到一个问题需要知道udp的丢包数据。实际上我不相信能简单地得到udp的丢包精确数据。理由是,网卡负载太高时有些包连网卡都没收到,根本不可能来得及汇报给内核。另外,如果是路由器把udp丢了,那udp的目的端机器当然更不可能感知到有丢包了。

这时,同事说netstat -us (–statistic)可以看到udp的丢包。这里的u选项指的是只展示udp相关的统计,s选项自然表示的是统计了。如果不用u选项,则出显示所有统计数据。下面是我的机器上的输出。

Ip:
    203440255187 total packets received
    0 forwarded
    0 incoming packets discarded
    201612429535 incoming packets delivered
    1064529177 requests sent out
    15 fragments dropped after timeout
    3058122492 reassemblies required
    1230296840 packets reassembled ok
    15 packet reassembles failed
Icmp:
    14869220 ICMP messages received
    3965512 input ICMP message failed.
    ICMP input histogram:
        destination unreachable: 6054246
        timeout in transit: 687
        echo requests: 8570532
        echo replies: 243755
    12913011 ICMP messages sent
    0 ICMP messages failed
    ICMP output histogram:
        destination unreachable: 4097869
        time exceeded: 5
        echo request: 244605
        echo replies: 8570532
IcmpMsg:
        InType0: 243755
        InType3: 6054246
        InType8: 8570532
        InType11: 687
        OutType0: 8570532
        OutType3: 4097869
        OutType8: 244605
        OutType11: 5
Tcp:
    111681768 active connections openings
    4186820 passive connection openings
    24951865 failed connection attempts
    55064041 connection resets received
    275 connections established
    1033901799 segments received
    1776166765 segments send out
    12156205 segments retransmited
    6705 bad segments received.
    106348033 resets sent
Udp:
    198894689917 packets received
    472986510 packets to unknown port received.
    1146976531 packet receive errors
    116750744 packets sent
    110301286 receive buffer errors
    0 send buffer errors
UdpLite:
TcpExt:
    423 invalid SYN cookies received
    693 packets pruned from receive queue because of socket buffer overrun
    19 packets pruned from receive queue
    11309370 TCP sockets finished time wait in fast timer
    106 packets rejects in established connections because of timestamp
    10210477 delayed acks sent
    20811 delayed acks further delayed because of locked socket
    Quick ack mode was activated 8856 times
    17118697 packets directly queued to recvmsg prequeue.
    301717551 bytes directly in process context from backlog
    152118951904 bytes directly received in process context from prequeue
    104771733 packet headers predicted
    15179703 packets header predicted and directly queued to user
    218747377 acknowledgments not containing data payload received
    102637644 predicted acknowledgments
    7293 times recovered from packet loss by selective acknowledgements
    Detected reordering 40 times using FACK
    Detected reordering 27 times using SACK
    Detected reordering 1088 times using time stamp
    476 congestion windows fully recovered without slow start
    5287 congestion windows partially recovered using Hoe heuristic
    236 congestion windows recovered without slow start by DSACK
    151673 congestion windows recovered without slow start after partial ack
    1 timeouts after reno fast retransmit
    4 timeouts after SACK recovery
    10540 timeouts in loss state
    7232 fast retransmits
    649 forward retransmits
    1871 retransmits in slow start
    11612658 other TCP timeouts
    TCPLossProbes: 93185
    TCPLossProbeRecovery: 14667
    2431 packets collapsed in receive queue due to low socket buffer
    8814 DSACKs sent for old packets
    3350 DSACKs received
    1 DSACKs for out of order packets received
    90851 connections reset due to unexpected data
    214 connections reset due to early user close
    352 connections aborted due to timeout
    TCPDSACKIgnoredNoUndo: 1571
    TCPSpuriousRTOs: 7
    TCPSackShifted: 94
    TCPSackMerged: 131
    TCPSackShiftFallback: 21183
    TCPTimeWaitOverflow: 1876775
    TCPRcvCoalesce: 15711184
    TCPOFOQueue: 3194
    TCPChallengeACK: 2337394
    TCPSYNChallenge: 13608
    TCPSpuriousRtxHostQueues: 1982796
IpExt:
    InBcastPkts: 46443933
    InOctets: 44312451521655
    OutOctets: 1915626725817
    InBcastOctets: 6827280595

喂,要是转载文章。麻烦贴一下出处 ykyi.net 采集爬虫把链接也抓走

这里面确实有两个疑似表示udp的丢包数的数据:

Udp:
    1146976531 packet receive errors
    110301286 receive buffer errors

于是,当然首先是看linux man page。结果netstat的man手册里居然没有这些字段的介绍。
跟住,问google。没想到,答案就是netstat -s的输出并没有准确的文档(pooly documented)。
这里有个贴子问了相同的问题 https://www.reddit.com/r/linux/comments/706wsa/detailed_explanation_of_all_netstat_statistics/
简单地说,回贴人告诉他,“别用netstat,而是用nstat和ip tools”“这是个不可能的任务,除非看完成吨源代码”。
blablabla …
事实上,看了google到的一些贴子后,还是大概知道了真相。

    1146976531 packet receive errors

这一句对应关于UDP的一个RFC标准的文档 中定义的字段 udpInErrors。

“The number of received UDP datagrams that could not be
delivered for reasons other than the lack of an application
at the destination port.”
udpInErrors表示操作系统收到的不能被投递的UDP包,不能投递的原因除了没有应用程序开启了对应的端口。

而这一行

    110301286 receive buffer errors

这一行对应 nstat -a -z (下文会再提到nstat)输出中的 UdpRcvbufErrors 字段。我没有找到RFC关于UdpRcvbufErrors字段的定义。
IBM官网上有个网页简单介绍了UdpRcvbufErrors: Number of UDP buffer receive errors. (UDP的缓冲收到错误的次数)。
再结合这篇文章: 为何udp会被丢弃Why do UDP packets get dropped。我非常有信心的认为 UdpRcvbufErrors 表示的是操作系统的内核tcp栈给udp socket分配的缓冲出错(缓冲满)的次数。至于网卡自己的缓冲,和操作系统的缓冲是两回事。网卡的缓冲出错不会被计入这个计数。udp经过的路由的丢包数当然只能够查看对应的路由器的统计数据了。

另外,因为netstat已经被废弃,不建议使用。而是用 nstat 和 ss 这两个新命令代替。
nstat的输出相当于netstat -s的输出。但nstat会输出比netstat -s更多的字段信息,且绝大多数字段名对应到RFC标准中用的字段名。

可任意转载本文,但需要注明出处!!!谢谢

Why do UDP packets get dropped: https://jvns.ca/blog/2016/08/24/find-out-where-youre-dropping-packets/
1: https://tools.ietf.org/html/rfc4113
2: https://www.ibm.com/support/knowledgecenter/STXNRM_3.13.4/coss.doc/deviceapi_response_2.html

服务器端的tcp有大量TIME_WAIT怎么办

公司的群里讨论tcp的TIME_WAIT的问题。TIME_WAIT这个状态可是面试时经常问的知识点啊。
讨论的问题是:有一个服务器,它对外网提供服务,同时它作为客户端连接很多后端的其它服务器。这位同事连后端其它服务器时用了短tcp连接。结果出现了大量的tcp TIME_WAIT状态,吞吐量上不去,怎么办?

先说结论:
1. 如果该服务器要处理外网IP的入流量,那最好的办法应该是用tcp长链接改造它与后端服务器的连接。如果用中间件,比如上zeromq那更省心了。
2. 如果不想做改动,并且在应用层确认已经交互已经完成,则可以用shutdown()直接发RST结束tcp会话,而不走正常的4次挥手。查阅shutdown系统调用的文档获知如何发RST。
3. 如果该服务器不需要处理处网IP请求的话,那么,启用port reuse 即打开net.ipv4.tcp_tw_reuse不会有太大问题(如果处理外网请求就有问题,和NAT相关,见https://vincent.bernat.im/en/blog/2014-tcp-time-wait-state-linux),或者更好的,把/proc/sys/net/ipv4/tcp_fin_timeout改小,改成1或者2。让TIME_WAIT只保持很短的时间。

首先,需要知道一个tcp会话由 src_ip, src_port, dest_ip, dest_port 四元组确定。
我们公司的IDC环境中, 上述的服务器作为客户端再发起tcp连接联后端服务器,则 src_ip 固定了, dest_ip是后端服务器的ip, port是后端服务器监听端口。这样只有 src_port 是可变化的,但port只有16个bits还不能用well-known ports,这样就更少了。

再说,主动关闭时,tcp连接需要进入TIME_WAIT状态,保持两倍MSL时长,是为了处理两种情况:
1) 让当前这个会话的迷路包在网路中消失。这样不会干扰到新建的会话。
2) 确保主动关闭方的FIN-ACK包,如果丢失的话,还能重发。
1981年的TCP RFC上把MSL设成两分钟,https://tools.ietf.org/html/rfc793

Maximum Segment Lifetime, the time a TCP segment can exist in
the internetwork system. Arbitrarily defined to be 2 minutes.

MSL设置这么长,因为以前的网络环境差啊。不过现在因为移动互联网,比较差的网络状态也是非常常见的。但RFC允许实现方减少MSL值。事实上linux的MSL写死在代码中为1分钟并且不可在运行期配置。
如果tcp连接的双方都在性能高速稳定的内网中,这个MSL就太长了。

调试时,还发现如果port用完了,connect的时候内核代码会用自旋锁忙等检查port资源。有linux内核开发基础的开发者都知道spin_lock的时候是不会让出cpu的,于是cpu全被spin_lock吃掉了。一直要等到有port被释放。再后来又发现,如果scoket没有设定SO_REUSEADDR选项,则connect()系统调用会返回EADDRINUSE。

tcp的连接双方都是确定且长期的,用什么tcp短连接呢??改造吧~~~

Linux 如何知道有哪些硬件,该装哪个驱动

Linux 如何知道有哪些硬件,该装哪个驱动

公司明文不准安装虚拟机了,被查到就是死罪。于是我在自己的笔记本上安装了Debian Linux。

结果无线网卡识别不了~~

次奥~

怎么破呢?

这么破:

# lspci

该命令列出了所有PCI总线上的硬件设备,稍微看看就能看到自己的无线网卡了。

05:00.0 Network Controller: Atheros Communication Inc. AR9287 Wireless Network Adaptor (PCI-Express)(rev 01)

注意前面的坐标05:00.0,再到/sys下面找对应哪个驱动:

find /sys | grep drivers.*05:00.0

/sys/bus/pci/drivers/ath9k/0000:05:00.0

其实,还有更简单的办法:

#lspci -v 

就搞定了。

用lsmod 和 dmesg | grep ath9k 可以看到网卡对应模块的一些信息.

再编辑 /etc/network/interface

auto wlan0

iface wlan0 inet dhcp

wpa-ssid Tencent-FreeWiFi

wpa-psk xxxxxx

最后: iwconfig wlan up

搞定!!!

怎么知道gcc搜索头文件的路径

每个C/C++程序员都知道,对于#include directive,一般,以双引号引用的头文件是程序号自定义的头文件。而用尖括号引用的头文件是系统的头文件或其它库文件。

更详细的,编译器先在当前目录找用双引号""引用的头文件,如果找不到再到系统目录找这个头文件。而对于尖括号引用的头文件,编译器就只在系统文件中搜索了。

那么,到底是在哪些目录中搜索头文件呢?

可以用cpp查看,如下:

root@vicarious:/home/kamus/projs/horoscope/boost# cpp -v
Using built-in specs.
COLLECT_GCC=cpp
Target: x86_64-linux-gnu
Thread model: posix
gcc version 4.7.2 (Debian 4.7.2-5)
COLLECT_GCC_OPTIONS='-E' '-v' '-mtune=generic' '-march=x86-64'
 /usr/lib/gcc/x86_64-linux-gnu/4.7/cc1 -E -quiet -v -imultiarch x86_64-linux-gnu - -mtune=generic -march=x86-64
ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../x86_64-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/lib/gcc/x86_64-linux-gnu/4.7/include
 /usr/local/include
 /usr/lib/gcc/x86_64-linux-gnu/4.7/include-fixed
 /usr/include/x86_64-linux-gnu
 /usr/include
End of search list.

 

一般编写makefile时给gcc指定 -I选项,-I的参数代表的目录是搜索系统头文件时使用的目录。可以试试# cpp -I/tmp -v 

/tmp目录会被添加为搜索系统头文件时的第一个目录。

如果想要添加搜索双引号""引用的头文件使用的目录呢,用 -iquote 选项指定更多的目录。

copyright ykyi.net

Linux的环境变量LD_DEBUG调试so的加载

一个稍微有经验的Linux程序员都知道使用LD_LIBRARY_PATH 来临时设置加载器搜索动态链接库so的路径顺序。但另一个不为人知的环境变量是LD_DEBUG。这个变量可以提供非常详细的加载动态链接库的信息。

 

可以把LD_DEBUG设成以下值:

export LD_DEBUG=files     # 显示库的依赖性和加载的顺序

export LD_DEBUG=bindings  # 符号绑定

export LD_DEBUG=libs   # 显示加载器查找库时使用的路径的顺序

export LD_DEBUG=versions  # 版本依赖性

export LD_DEBUG=help  # LD_DEBUG的帮助信息

 

试一下把LD_DEBUG设成以上值之一,再随便运行一个程序试试。

一个试验:

root@vicarious:/home/kamus/projs/horoscope/bins# export LD_DEBUG=libs

root@vicarious:/home/kamus/projs/horoscope/bins# vim my.conf

     24360:   find library=libm.so.6 [0]; searching

     24360:   search cache=/etc/ld.so.cache

     24360:     trying file=/lib/x86_64-linux-gnu/libm.so.6

     24360:

     24360:   find library=libtinfo.so.5 [0]; searching

     24360:   search cache=/etc/ld.so.cache

     24360:     trying file=/lib/x86_64-linux-gnu/libtinfo.so.5

     24360:

     24360:   find library=libselinux.so.1 [0]; searching

     24360:   search cache=/etc/ld.so.cache

     24360:     trying file=/lib/x86_64-linux-gnu/libselinux.so.1

     24360:

     24360:   find library=libacl.so.1 [0]; searching

     24360:   search cache=/etc/ld.so.cache

     24360:     trying file=/lib/x86_64-linux-gnu/libacl.so.1

     24360:

     24360:   find library=libgpm.so.2 [0]; searching

     24360:   search cache=/etc/ld.so.cache

     24360:     trying file=/usr/lib/x86_64-linux-gnu/libgpm.so.2

     24360:

     24360:   find library=libc.so.6 [0]; searching

     24360:   search cache=/etc/ld.so.cache

     24360:     trying file=/lib/x86_64-linux-gnu/libc.so.6

     24360:

     24360:   find library=libdl.so.2 [0]; searching

     24360:   search cache=/etc/ld.so.cache

     24360:     trying file=/lib/x86_64-linux-gnu/libdl.so.2

     24360:

     24360:   find library=libattr.so.1 [0]; searching

     24360:   search cache=/etc/ld.so.cache

     24360:     trying file=/lib/x86_64-linux-gnu/libattr.so.1

copyright ykyi.net

configure –prefix 和 make install DESTDIR= 还有make install prefix 什么区别

./configure –prefix=*

确定了程序会被包装到哪里,以及,程序将在什么位置搜寻运行需要用到的相关的文件。如果你在一台机器上编译,然后仍然在这台机器上运行,那使用configure –prefix就是你想要的了。

 

make install DESTDIR=*

把程序安装到一个临时用的目录,这个目录不是程序以后将要运行的目录。例如,这个功能被deb包的打包人员使用。打包人员使用此功能时,并不真正把程序安装到–prefix指定的目录下。因为他可能已经安装了不同的版本,他不想搞乱他的环境,或者他没有boot权限,没有办法把程序安装到/bin,/sbin之类目录。 –prefix=/usr,让程序运行时认为被安装在/usr,然后make install DESTDIR=debian/tmp则实际把程序安装到debian/tmp。

 

make install prefix=/foo/bar/baz

和 make install DESTDIR的区别在于,前者不会创建prefix后面指定的所有目录层级,而DESTDIR会。

例如:

./configure –prefix=usr/local && make && sudo make install prefix=/usr/local/stow/foo 会把程序安装在/usr/local/stow/bin目录下。

而: make install DESTDIR=/usr/local/stow/foo,则把程序安装在/usr/local/stow/foo/usr/local/bin下面。

copyright ykyi.net

为什么dump生成core文件大小是0

今天程序崩溃了,但是生成的core文件大小是0.

用ulimit -c 查看生成core文件的大小限制是无限unlimited.

也不是磁盘大小和写入权限的问题。

但究竟是什么问题呢?

捣了半天终于搞明白,原来是文件系统造成的。

我是在vmware的虚拟机的debian linux上运行程序,文件系统用的是从host机windows 7挂载到/mnt/hgfs的windows的NTFS文件系统。

后来我把程序转移动linux自己的文件系统,崩溃的时候就生成正常的core dump文件了。

copyright ykyi.net

如何从windows远程调试linux程序。

用gdb在远程linux机器上调试程序实在太不方便了。于是想到用eclipse的GUI调试。下面介绍如何从windows远程调试linux程序。

 

 

 

 

1. 在远程linux上安装gdbserver

 

 

2. windows上安装Cygwin或者MinGW。我用Cygwin编译gdb时遇到问题,用MinGW则通过了。但我想Cygwin应该也是可以的.

 

 

3. sourceforge.net上下载expat工程。这是个分析xml文件的开源库。如果跳过这步,也可以,但是gdb不能分析gdbserver发过来的xml文件。 

 

 

4. expat文件夹, ./configure –enable-shared; make; make install

 

 

5. gdb官网下载gdb源代码,解开后运行: ./configure –with-expat –target=x86_64-linux-gnu  –host=i686-pc-mingw32   注意这里的with-expat使得gdb能用解析xml文件的功能,target使得gdb能调试的目标平台的程序,这个字符串可以从l远程inux中运行gdb时开打印出来的声明处得到。Host指定了gdb运行在什么样的平台,这个字符串可以通过运行 ./config.guess 得到。

 

 

6. 然后是make; make install 三板斧。

 

 

7. 现在试一试是否工作正常。在远程linux机器上随便创建一个程序。遵守程序员世界的传统,建个hello world,注意编译时开启 -g 选项。假设源程序是 hello.c, 可执行文件是 hello

 

 

8. 在远程linux端运行 gdbserver :8383 hello 。 8383前有个冒号,8383是端口号,随便取。

 

9. hello.c 和 hello 拷贝到windows机器。

 

 

10. 在控制台介面中,运行 x86_64-linux-gnu-gdb ./Hello。注意前面的gdb名字要相应替换成第5个步骤中编译出来的gdb文件名。

 

11. gdb的控制台交互介面中输入target remote 192.168.44.129:8383 注意把IP换成远程linux机器的IP地址。

12. 试试常用的gdb命令,continue, break, run 什么的。如果能工作就能进入下一步了。

 

13. 创建一个eclipsec/c++工程,源代码则是远程linux机器的源代码.假设工程名也是hello

13. 这一步的目的是在eclipse中创建一个Remote Application Debug configuration。选Run->Debug Configuration在左边选中c/c++ remote application,再点左上角的+号增加一个configuration。在main选项卡的c/c++ application处填windows机上可执行文件hello的路径。Projecteclipsec/c++工程名。 Connection处新建一个连接,类型选linux,其它选项填ssh。我想其它的协议应该也是可以的,但是我用了ssh。 Remote Absolute File path for c/c++ application要填在远程linux机器上启动hello的路径。是否勾上skip download to target path,表示是否在windows机器编译工程然后把编译好的文件上传到远程机器。因为我选择在远程linuxmake,所以我勾选了此项。因你的需求做调整。

 

 

14. Debugger选项卡中把GDB debugger的路填上windows上前面编译出来的gdb的路径。比如我的路径是:D:\MinGW\bin\x86_64-linux-gnu-gdb.exe

 

 

15. 现在就可以用这个Debug configuration远程调试了。

 

 

因为配置远程调试环境涉及到的配置实在太繁杂,如果写一篇考虑所有细节面面俱到的文章太困难了。这篇文章仅把骨干步骤写出,如果读者在实践中遇到各种千奇百怪的问题,需要运用你自己的判断力解决。hope this article helps.

 

copyright ykyi.net

 

 

packet captured和packet received by filter到底有什么区别

我用的是linux. 结论是 packet received by filter是tcpdump从内核中拿到的且匹配命令上行指定的过滤条件的包, packet captured是经由pcap_loop, 或 pcap_dispatch 或 pcap_next,把包交给回调处理过的包的数量。这两个数字的差值是tcpdump抓到的,还来不及处理的包。

下面是讨论的一些细节:

/////////////

tcpdump的最后输出. 592个包captured,  1184个包received by filter。。这个差值是不是表示有多少包tcpdump没来得及处理.

man tcpdump上写得好复杂,received by filter的数字取决于OS… 1. 包匹配不匹配命令行上指定的filter都算,如果匹配,有没有被tcpdump读出都算..   2. 只有匹配命令行上指定的filter的包才算,有没有被tcpdump读出都算.   3. 只有匹配filter才算,只有被tcpdump读出才算.

我的理解是:如果是第3种,那captured的数字和received by filter的数字就是一样的。 第2种的差值表示tcpdump来不及处理的包数量,理想状态上差值能为0.   第1种情况,基本上总是有差值。

我猜测我用的linux上应该是第2种情况. 

wangbin579() 10:18:54 
应该是匹配的才算received by filter,但奇怪的是,为啥你的系统,captured怎么少?
wangbin579() 10:19:30 
[root@hz0-12-157 ~]# tcpdump -i any tcp and port 36524 or 3306 -w all.pcap
tcpdump: listening on any, link-type LINUX_SLL (Linux cooked), capture size 65535 bytes
10757 packets captured
11171 packets received by filter
334 packets dropped by kernel
wangbin579() 10:20:07 
我们这边系统,基本可以认为packets received by filter=packets captured + packets dropped by kernel

siu¹ººººººº() 10:23:38 
/homemus/tmp # time time tcpdump -i tunl0:1  -w tmp
tcpdump: listening on tunl0:1, link-type RAW (Raw IP), capture size 96 bytes
19508 packets captured
39021 packets received by filter
0 packets dropped by kernel
0.01user 0.02system 0:17.04elapsed 0%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (0major+506minor)pagefaults 0swaps

real    0m17.139s
user    0m0.012s
sys     0m0.028s
wangbin579() 10:26:03 
如果是差是丢包,那么通过查看抓包文件,应该能看出很多不完整的session
siu¹ººººººº() 10:28:46 
我觉得差值是来不及写入磁盘的包.
siu¹ººººººº() 10:29:04 
再研究看看了。。谢谢啦/..
wangbin579() 10:30:03 
packets captured是pcap_loop所设置的回调函数所调用的,一旦调用回调函数,就用统计
wangbin579() 10:30:37 
有可能内核态部分和用户态部分,速度上不匹配,有延迟导致的?
siu¹ººººººº() 10:32:33 
我现在理解, received by filter是pcap库从内核中拿到的又匹配命令行上filter的包的数量, packets captured是经由pcap_loop, pcap_dispatch之类通过callback交付出去的包数量. 差值就是还没来得及处理的.
wangbin579() 10:32:48 
17s,每秒也就2000多个,不算多,用户态程序应该来得及处理

wangbin579() 10:33:58 
我这边系统很破,处理速度也比这个快,也没有来不及处理
wangbin579() 10:34:45 
看看我的:
wangbin579() 10:34:47 
[root@hz0-12-157 ~]# time tcpdump -i any tcp and port 36524 or 3306 -w 3306.pcap         
tcpdump: listening on any, link-type LINUX_SLL (Linux cooked), capture size 65535 bytes
294663 packets captured
295432 packets received by filter
693 packets dropped by kernel

real    0m17.676s
user    0m0.897s
sys     0m3.502s
wangbin579() 10:35:52 
量比你大7倍多,也没有出现来不及处理啊,当然我的是物理机,3G内存,
siu¹ººººººº() 10:36:59 
 那你觉得这个差值不是来不及处理的包么?。我觉得应该还是来不及处理的。我在想,可能是写到的磁盘文件系统是NFS之类的 ….我继续排查一下。
wangbin579() 10:37:43 
有可能,我的是写入本地磁盘。
wangbin579() 10:37:58 
你这种情况,我还是第一次碰到
siu¹ººººººº() 10:39:05 
我先去运维那边了解下情况…多谢啦 
wangbin579() 10:39:18 
算涨见识了,还以为一般dropped by kernel为0就代表不丢包呢,居然还有你这种情况。
你可以看看抓包文件,session是不是很多不完整,如果不完整,你的推测是对的
siu¹ººººººº() 10:39:58 
嗯。呵呵~~ 做IT,每天都会碰到挑战宇宙规律的现象。
siu¹ººººººº() 10:40:07 

мe(~ o мe(632813052) 10:41:09 
呵呵
wangbin579() 10:41:24 
其实,网络方面的问题,最复杂了。
我现在已经陷入到网络的汪洋大海之中了,各种各样的问题都会有,而且没有尽头。
早知道如此,3年前我就不搞这一块了
siu¹ººººººº() 10:42:30 
同感。写一点点代码,都非常难以调试。各种认为理所当然的假设,通通是bug的温床

@wangbin579  麻烦你在tcpdump前加个time,。。把输出贴出来。我好像看出问题来了。

[root@hz0-12-157 ~]# time tcpdump -i any tcp and port 36524 or 3306 -w 3306.pcap         
tcpdump: listening on any, link-type LINUX_SLL (Linux cooked), capture size 65535 bytes
294663 packets captured
295432 packets received by filter
693 packets dropped by kernel

real    0m17.676s
user    0m0.897s
sys     0m3.502s
wangbin579() 10:56:03 
不是加了time了吗?
wangbin579() 10:57:15 
[root@hz0-12-157 ~]# time time tcpdump -i any tcp and port 36524 or 3306 -w 3306.pcap
tcpdump: listening on any, link-type LINUX_SLL (Linux cooked), capture size 65535 bytes
^C202061 packets captured
202523 packets received by filter
369 packets dropped by kernel
0.66user 2.50system 0:11.99elapsed 26%CPU (0avgtext+0avgdata 24208maxresident)k
0inputs+105656outputs (0major+660minor)pagefaults 0swaps

real    0m11.999s
user    0m0.661s
sys     0m2.506s
wangbin579() 10:57:26 
加两个,结果如上
siu¹ººººººº() 10:59:29 
问题找到的。我这边运行的tcpdump,根本就没有抢到cpu时间来处理.
wangbin579() 11:00:05 

siu¹ººººººº() 11:00:06 

Real  0m3.914s

User  0m0.008s

Sys   0m0.000s

跑了4秒钟,用户空间才抢到0.008秒,内核态几乎是0 ….
siu¹ººººººº() 11:00:25 
那个差值确实是没有来得及处理的包的数量。
wangbin579() 11:00:41 
奥,那你系统这么繁忙啊

siu¹ººººººº() 11:02:22 
所以,解决了一个问题又会有新的颠覆宇宙规律的问题…系统负载很高,但cpu使用率很低。。

copyright ykyi.net

 

tcpcopy在视频广告组的二次开发

1.

流量筛选中的 “只导入某频道的流量”功能已经实现了。

技术层面上,实际上是通过指定正则式的方法匹配HTTP请求中的GET方法中的URL来达到过滤的目的。

所以,也可以用ty,ad_type, pf, coverid, oadid, v,plugin等出现在GET方法中的参数编写正则式来过滤流量。

 

2.

流量筛选中的“地域纬度筛选”暂时没有实现。

因为地域纬度的信息不是以参数形式出现在GET方法的URL中,需要通过IP地址或者cookie的中QQ号信息来判断。

还没最终决定是否实现这个功能。

 

3.

tcpcopy官方版本主要的应用场景是复制实时流量。所以部署的时候至少两台机器,一台线上机,另一台测试用机。为了方便压力测试,还引入了至少三台机器的高级模式。

部署起来比较麻烦。

如果“视频CPM广告的模拟投放,以及订单效果预估“只是从磁盘中读入以往的流量,针对这种场景,可以探索tcpcopy的单机离线模式,做到方便部署和使用。

 

4. 部分同学有一个误解.

"将线上的实际访问流量,复制一份保存到本地服务器,用于后续使用"

目前,tcpcopy的官方的版本没有把流量保存下来的功能,保存流量这个目前是用tcpdump的-w选项来做的。

 

另外,技术上,tcpdump只能在IP层和TCP层指定过滤条件,不能用业务的逻辑过滤流量。第1点提到的流量筛选工作在tcpcopy读入实时流量时,或者从tcpdump存下的文件中读入流量时,在应用层指定过滤条件。

copyright ykyi.net