系統技術非業餘研究 » dropwatch 網路協議棧丟包檢查利器
在做網路伺服器的時候,會碰到各種各樣的網路問題比如說網路超時,通常一般的開發人員對於這種問題最常用的工具當然是tcpdump或者更先進的wireshark來進行抓包分析。通常這個工具能解決大部分的問題,但是比如說wireshark發現丟包,那深層次的原因就很難解釋了。這不怪開發人員,要怪就怪linux網路協議棧太深。我們來看下:
這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