1. 程式人生 > >系統技術非業餘研究 » dropwatch 網路協議棧丟包檢查利器

系統技術非業餘研究 » dropwatch 網路協議棧丟包檢查利器

在做網路伺服器的時候,會碰到各種各樣的網路問題比如說網路超時,通常一般的開發人員對於這種問題最常用的工具當然是tcpdump或者更先進的wireshark來進行抓包分析。通常這個工具能解決大部分的問題,但是比如說wireshark發現丟包,那深層次的原因就很難解釋了。這不怪開發人員,要怪就怪linux網路協議棧太深。我們來看下:
network-stack

這7層裡面每個層都可能由於各種各樣的原因,比如說緩衝區滿,包非法等,把包丟掉,這樣的問題就需要特殊的工具來發現了。 好了,主角dropwatch出場.
它的官方網站在這裡

What is Dropwatch

Dropwatch is a project I am tinkering with to improve the visibility developers and sysadmins have into the Linux networking stack. Specifically I am aiming to improve our ability to detect and understand packets that get dropped within the stack.

Dropwatch定位很清晰,就是用來檢視協議棧丟包的問題。

RHEL系的系統安裝相當簡單,yum安裝下就好:

$ uname -r
2.6.32-131.21.1.tb477.el6.x86_64
$ sudo yum install dropwatch

man dropwatch下就可以得到使用的幫助,dropwatch支援互動模式, 方便隨時啟動和停止觀測。

使用也是很簡單:

$ sudo dropwatch -l kas
Initalizing kallsymsa db
dropwatch> start
Enabling monitoring...
Kernel monitoring activated.
Issue Ctrl-C to stop monitoring
1 drops at netlink_unicast+251
15 drops at unix_stream_recvmsg+32a
3 drops at unix_stream_connect+1dc

-l kas的意思是獲取drop點的符號資訊,這樣的話針對原始碼就可以分析出來丟包的地方。

同學們可以參考這篇文章(Using netstat and dropwatch to observe packet loss on Linux servers):http://prefetch.net/blog/index.php/2011/07/11/using-netstat-and-dropwatch-to-observe-packet-loss-on-linux-servers/

那他的原理是什麼呢?在解釋原理之前,我們先看下這個工具的對等的stap指令碼:

$ cat /usr/share/doc/systemtap-1.6/examples/network/dropwatch.stp
#!/usr/bin/stap

############################################################
# Dropwatch.stp
# Author: Neil Horman <
[email protected]
> # An example script to mimic the behavior of the dropwatch utility # http://fedorahosted.org/dropwatch ############################################################ # Array to hold the list of drop points we find global locations # Note when we turn the monitor on and off probe begin { printf("Monitoring for dropped packets\n") } probe end { printf("Stopping dropped packet monitor\n") } # increment a drop counter for every location we drop at probe kernel.trace("kfree_skb") { locations[$location] <<< 1 } # Every 1 seconds report our drop locations probe timer.sec(1) { printf("\n") foreach (l in locations-) { printf("%d packets dropped at %s\n", @count(locations[l]), symname(l)) } delete locations }

這個指令碼核心的地方就在於這行:
probe kernel.trace(“kfree_skb”) { locations[$location] <<< 1 } 當kfree_skb被呼叫的時候,核心就記錄下這個drop協議棧的位置,同時透過netlink通知dropwatch使用者態的部分收集這個位置,同時把它整理顯示出來.以上就是dropwatch的工作流程。 現在的問題是核心什麼地方,什麼時候會呼叫kfree_skb這個函式呢? 我們繼續追查下: dropwatch需要對核心打patch,當然RHEL5U4以上的核心都已經打了patch。 patch在這裡下載:https://fedorahosted.org/releases/d/r/dropwatch/dropwatch_kernel_patches.tbz2 通過檢視裡面的5個patch,我們知道drop主要修改了以下幾個檔案:

include/linux/netlink.h
include/trace/skb.h
net/core/Makefile
net/core/net-traces.c
include/linux/skbuff.h
net/core/datagram.c
include/linux/net_dropmon.h
net/core/drop_monitor.c
include/linux/Kbuild
net/Kconfig
net/core/Makefile

我們透過RHEL5U4的程式碼可以清楚的看到:

//include/linux/skbuff.h
extern void kfree_skb(struct sk_buff *skb);
extern void consume_skb(struct sk_buff *skb);

這些patch的作用是使得支援dropwatch的核心把kfree_skb分成二類: 1. 人畜無害的呼叫consume_skb 2. 需要丟包的呼叫kfree_skb 同時提供基礎的netlink通訊往使用者空間傳遞位置資訊。

知道了這點,我們在RHEL 5U4的原始碼目錄下: linux-2.6.18.x86_64/net/ipv4 或者 linux-2.6.18.x86_64/net/core下 grep下

$ grep -rin kfree_skb  .
./tcp_input.c:3122:                     __kfree_skb(skb);
./tcp_input.c:3219:                     __kfree_skb(skb);
./tcp_input.c:3234:             __kfree_skb(skb);
./tcp_input.c:3318:                             __kfree_skb(skb);
...
./ip_fragment.c:166:static __inline__ void frag_kfree_skb(struct sk_buff *skb, int *work)
./ip_fragment.c:171:    kfree_skb(skb);
./ip_fragment.c:211:            frag_kfree_skb(fp, work);
./ip_fragment.c:452:            frag_kfree_skb(fp, NULL);
./ip_fragment.c:578:                    frag_kfree_skb(free_it, NULL);
./ip_fragment.c:607:    kfree_skb(skb);
./ip_fragment.c:732:    kfree_skb(skb);
./udp.c:1028:   kfree_skb(skb);
./udp.c:1049:           kfree_skb(skb);
./udp.c:1069:                   kfree_skb(skb);
./udp.c:1083:                   kfree_skb(skb);
./udp.c:1134:                                   kfree_skb(skb1);
./udp.c:1229:   kfree_skb(skb);
./udp.c:1242:   kfree_skb(skb);
./udp.c:1258:   kfree_skb(skb);
./udp.c:1418:                           kfree_skb(skb);
./ip_sockglue.c:286:            kfree_skb(skb);
./ip_sockglue.c:322:            kfree_skb(skb);
./ip_sockglue.c:398:    kfree_skb(skb);
./devinet.c:1140:               kfree_skb(skb);
./xfrm4_ninput.c:29:    kfree_skb(skb);
./xfrm4_ninput.c:122:   kfree_skb(skb);
./tunnel4.c:85: kfree_skb(skb);
./icmp.c:47: *                                  and moved all kfree_skb() up to
./icmp.c:1046:  kfree_skb(skb);
./ip_forward.c:121:     kfree_skb(skb);
./netfilter.c:73:               kfree_skb(*pskb);
./netfilter.c:114:              kfree_skb(*pskb);
./netfilter/ip_queue.c:277:             kfree_skb(skb);
./netfilter/ip_queue.c:335:     kfree_skb(nskb); 
./netfilter/ip_queue.c:373:                     kfree_skb(e->skb);
./netfilter/ip_queue.c:556:             kfree_skb(skb);
...
./netfilter/ipt_TCPMSS.c:153:           kfree_skb(*pskb);
./netfilter/ipt_ULOG.c:435:                     kfree_skb(ub->skb);
./tcp.c:1458:                           kfree_skb(skb);
./tcp.c:1577:           __kfree_skb(skb);
./ip_gre.c:482:         kfree_skb(skb2);
./ip_gre.c:497:                 kfree_skb(skb2);
./ip_gre.c:504:                 kfree_skb(skb2);
...
./ip_gre.c:892: dev_kfree_skb(skb);
./raw.c:244:            kfree_skb(skb);
./raw.c:254:            kfree_skb(skb);
./raw.c:329:    kfree_skb(skb);
./tcp_ipv4.c:1039:      kfree_skb(skb);
./tcp_ipv4.c:1151:      kfree_skb(skb);
./ipvs/ip_vs_xmit.c:213:        kfree_skb(skb);
./ipvs/ip_vs_xmit.c:290:        kfree_skb(skb);
./ipvs/ip_vs_xmit.c:374:                        kfree_skb(skb);
./ipvs/ip_vs_xmit.c:378:                kfree_skb(skb);
./ipvs/ip_vs_xmit.c:423:        kfree_skb(skb);
./ipvs/ip_vs_xmit.c:480:        kfree_skb(skb);
./ipvs/ip_vs_xmit.c:553:        dev_kfree_skb(skb);
./ipvs/ip_vs_core.c:197:        kfree_skb(*pskb);
./ipvs/ip_vs_core.c:829:        kfree_skb(*pskb);
./ipconfig.c:504:       kfree_skb(skb);
./ipconfig.c:1019:      kfree_skb(skb);
./xfrm4_input.c:50:     kfree_skb(skb);
./xfrm4_input.c:162:    kfree_skb(skb);
./fib_semantics.c:292:          kfree_skb(skb);
./ipip.c:414:           kfree_skb(skb2);
./ipip.c:429:                   kfree_skb(skb2);
./ipip.c:436:                   kfree_skb(skb2);
./ipip.c:444:                   kfree_skb(skb2);
./ipip.c:458:   kfree_skb(skb2);
./ipip.c:482:                   kfree_skb(skb);
./ipip.c:609:                   dev_kfree_skb(skb);
./ipip.c:615:           dev_kfree_skb(skb);
./ipip.c:654:   dev_kfree_skb(skb);
./ipmr.c:185:   kfree_skb(skb);
...
./ip_output.c:763:      kfree_skb(skb);
./ip_output.c:964:                              kfree_skb(skb);
./ip_output.c:1313:             kfree_skb(skb);

我們可以看到一堆可以丟包的點。
當我們觀察到dropwatch發現丟包的時候,可以根據符號資訊結合以上的原始碼輕鬆的分析出來問題所在。

小結: 工具是知識的積累。

祝玩得開心!

Post Footer automatically generated by wp-posturl plugin for wordpress.

相關推薦

系統技術業餘研究 » dropwatch 網路協議檢查利器

在做網路伺服器的時候,會碰到各種各樣的網路問題比如說網路超時,通常一般的開發人員對於這種問題最常用的工具當然是tcpdump或者更先進的wireshark來進行抓包分析。通常這個工具能解決大部分的問題,但是比如說wireshark發現丟包,那深層次的原因就很難解釋了。這不怪開發人員,要怪就怪lin

系統技術業餘研究 » Linux IO協議框圖

這張圖很清晰的把linux IO協議棧的層次給勾出來了,而且內容很與時俱進,特別是SCSI裝置的層次對大家理解sg3這樣的包非常有幫助,強烈推薦大家好好研習! 祝玩得開心! Post Footer automatically generated by wp-posturl plugin fo

系統技術業餘研究 » Erlang 網路密集型伺服器的瓶頸和解決思路

最近我們的Erlang IO密集型的伺服器程式要做細緻的效能提升,從每秒40萬包處理提升到60萬目標,需要對程序和IO排程器的原理很熟悉,並且對行為進行微調,花了不少時間參閱了相關的文件和程式碼。 其中最有價值的二篇文章是: 1. Characterizing the Scalability of

系統技術業餘研究 » Erlang網路多程序模型的實驗

在做網路程式的時候我們會經常用到多程序模式. 主程序執行bind呼叫得到控制代碼後, 同時fork N個子程序, 把控制代碼傳遞給子程序, 多程序同時accept來處理. 這個模型在erlang下很有現實意義的. 在之前的測試中,我們演示了erlang的單處理器模式的威力,最多的時候在單cpu上可

系統技術業餘研究 » nicstat 網路流量統計利器

前段時間看到brendangregg的 Linux Performance Analysis and Tools PPT裡面提到的nicstat,研究了下是個不錯的東西,分享給大家。 nicstat is to network interfaces as “iostat” is to disks,

系統技術業餘研究 » 調研核心呼叫方便的工具 kmalloc

我們在研究核心的時候,看了核心程式碼後,就想著某個函式被誰誰呼叫。 呼叫路徑有很多條,有熱門的,有偏門的,但從程式碼不大容易看出。 如果我們能和gdb那樣在函式上設個斷點,看下核心函式的呼叫棧就清楚了。 但是如何統計熱門路線呢?用systemtap就可以,參看這裡, 這裡。 但是用systemt

系統技術業餘研究 » systemtap函式呼叫資訊不齊的原因和解決方法

有時候在看系統程式碼的時候,我們很難從原始碼中看出我們感興趣的函式是如何被呼叫的,因為呼叫路徑有可能太多。使用者空間的程式gdb設斷點是個好的方法,核心的就麻煩了。這時候systemtap可以幫忙, 比如: $uname -r 2.6.18-164.el5 $stap -V Syste

系統技術業餘研究 » erlsnoop erlang訊息監聽器(除錯erlang網路程式利器,支援最新的R13B04)

由於R13B以後, Erlang的分佈協議修改了格式, 添加了Atom Cache, erlsnoop在新版本下無法使用, 我特地打了patch, 使得它支援最新的版本,原始碼在附件中下載. 在erlang的郵件列表上看到: Have you tried putting a snoop to se

系統技術業餘研究 » blktrace未公開選項網路儲存擷取資料

我們透過blktrace來觀察io行為的時候,第一件事情需要選擇目標裝置,以便分析該裝置的io行為。具體使用可以參考我之前寫的幾篇:這裡 這裡 這裡 blktrace分為核心部分和應用部分,應用部分收到我們要捕捉的裝置名單,傳給核心。核心分佈在block層的各個tracepoint就會開始工作,把

系統技術業餘研究 » 巧用Netcat方便網路程式開發

首先介紹下NC,這個號稱網路瑞士軍刀的工具。 What is Netcat? Netcat is a featured networking utility which reads and writes data across network connections, using the TC

系統技術業餘研究 » qperf測量網路頻寬和延遲

我們在做網路伺服器的時候,通常會很關心網路的頻寬和延遲。因為我們的很多協議都是request-reponse協議,延遲決定了最大的QPS,而頻寬決定了最大的負荷。 通常我們知道自己的網絡卡是什麼型號,交換機什麼型號,主機之間的物理距離是多少,理論上是知道頻寬和延遲是多少的。但是現實的情況是,真正的

系統技術業餘研究 » 網路記憶體不足引發程序掛起問題

我們知道TCP socket有傳送緩衝區和接收緩衝區,這二個緩衝區都可以透過setsockopt設定SO_SNDBUF,SO_RCVBUF來修改,但是這些值設多大呢?這些值和協議棧的記憶體控制相關的值什麼關係呢? 我們來解釋下: $ sysctl net|grep mem net.core.wme

系統技術業餘研究

ItPub寫的文章“2017 年度 DB-Engines 資料庫冠軍得主:PostgreSQL 封王!”, 點選 這裡 進一步閱讀 升的最快的幾個資料庫,我簡單的無責任點評: PG資料庫是很老的資料庫,不過這幾年冉冉升起,因為是學院派的,有很好的學術和智力的支援,一直以來在資料庫的體系結構,程式碼

系統技術業餘研究 » MySQL資料庫架構的演化觀察

MySQL資料庫架構的演化觀察 December 14th, 2017 Categories: 資料庫 Tags: mysql

系統技術業餘研究 » inet_dist_connect_options

Erlang 17.5版本引入了inet_dist_{listen,connect}_options,對於結點間的互聯socket可以有更精細的控制,RPC的時候效能可以微調: raimo/inet_tcp_dist-priority-option/OTP-12476: Document ke

系統技術業餘研究 » 推薦工作機會

最後更新時間:2014/11/28 請賜簡歷至:[email protected], 感謝您對加入我們公司有興趣,我們希望能早日和您共事。 以下幾個職位1年內有效,歡迎內部轉崗:
 資深資料工程師 公司:阿里(核心系統資料庫組) 工作地點:杭州(西溪園區) 崗位描述: 分析雲服務產生的海

系統技術業餘研究 » 新的工作和研究方向

和大家更新下: 做了將近8年資料庫後,我的工作和研究方向將會延伸到虛擬化和計算相關的雲服務,希望能夠和大家一起進步,Happy New Year! 預祝大家玩得開心! Post Footer automatically generated by wp-posturl plugin for w

系統技術業餘研究 » 叢集引入inet_dist_{listen,connect}_options更精細引數微調

Erlang 17.5版本引入了inet_dist_{listen,connect}_options,對於結點間的互聯socket可以有更精細的控制,RPC的時候效能可以微調: raimo/inet_tcp_dist-priority-option/OTP-12476: Document ke

系統技術業餘研究 » 2017升的最快的幾個資料庫無責任點評

ItPub寫的文章“2017 年度 DB-Engines 資料庫冠軍得主:PostgreSQL 封王!”, 點選 這裡 進一步閱讀 升的最快的幾個資料庫,我簡單的無責任點評: PG資料庫是很老的資料庫,不過這幾年冉冉升起,因為是學院派的,有很好的學術和智力的支援,一直以來在資料庫的體系結構,程式碼

系統技術業餘研究 » Erlang 17.5引入+hpds命令列控制程序預設字典大小

Erlang 17.5釋出引入控制程序預設字典大小的命令列引數: Erlang/OTP 17.5 has been released Written by Henrik, 01 Apr 2015 Some highlights of the release are: ERTS: Added co