線上故障排查全套路怔接,總有一款適合你

來自:fredal的博客
鏈接:https://fredal.xin/java-error-check

線上故障主要會包括cpu、磁盤振劳、內存以及網(wǎng)絡問題知牌,而大多數(shù)故障可能會包含不止一個層面的問題丹拯,所以進行排查時候盡量四個方面依次排查一遍。同時例如 jstack荸恕、jmap 等工具也是不囿于一個方面的問題的乖酬,基本上出問題就是df、free融求、top 三連咬像,然后依次jstack、jmap伺候生宛,具體問題具體分析即可县昂。

CPU

一般來講我們首先會排查 CPU 方面的問題。CPU 異常往往還是比較好定位的陷舅。原因包括業(yè)務邏輯問題(死循環(huán))倒彰、頻繁gc以及上下文切換過多。而最常見的往往是業(yè)務邏輯(或者框架邏輯)導致的莱睁,可以使用jstack來分析對應的堆棧情況狸驳。

使用 jstack 分析 CPU 問題

我們先用 ps 命令找到對應進程的pid(如果你有好幾個目標進程,可以先用top看一下哪個占用比較高)缩赛。

接著用top -H -p pid來找到 CPU 使用率比較高的一些線程

image

然后將占用最高的 pid 轉換為 16 進制printf '%x\n' pid得到 nid

image

接著直接在 jstack 中找到相應的堆棧信息jstack pid |grep 'nid' -C5 –color

image

可以看到我們已經(jīng)找到了 nid 為 0x42 的堆棧信息,接著只要仔細分析一番即可撰糠。

當然更常見的是我們對整個 jstack 文件進行分析酥馍,通常我們會比較關注 WAITING 和 TIMED_WAITING 的部分,BLOCKED 就不用說了阅酪。我們可以使用命令

cat jstack.log | grep "java.lang.Thread.State" | sort -nr | uniq -c

來對 jstack 的狀態(tài)有一個整體的把握旨袒,如果 WAITING 之類的特別多,那么多半是有問題啦术辐。

image

頻繁 gc

當然我們還是會使用 jstack 來分析問題砚尽,但有時候我們可以先確定下 gc 是不是太頻繁,使用jstat -gc pid 1000命令來對 gc 分代變化情況進行觀察辉词,1000 表示采樣間隔(ms)必孤,S0C/S1C、S0U/S1U瑞躺、EC/EU敷搪、OC/OU、MC/MU 分別代表兩個 Survivor 區(qū)幢哨、Eden 區(qū)赡勘、老年代、元數(shù)據(jù)區(qū)的容量和使用量捞镰。

YGC/YGT闸与、FGC/FGCT毙替、GCT 則代表 YoungGc、FullGc 的耗時和次數(shù)以及總耗時践樱。如果看到 gc 比較頻繁厂画,再針對 gc 方面做進一步分析,具體可以參考一下 gc 章節(jié)的描述映胁。

上下文切換

針對頻繁上下文問題木羹,我們可以使用vmstat命令來進行查看

image

cs(context switch)一列則代表了上下文切換的次數(shù)。

如果我們希望對特定的 pid 進行監(jiān)控那么可以使用 pidstat -w pid命令解孙,cswch 和 nvcswch 表示自愿及非自愿切換坑填。

image

磁盤

磁盤問題和 CPU 一樣是屬于比較基礎的。首先是磁盤空間方面弛姜,我們直接使用df -hl來查看文件系統(tǒng)狀態(tài)

image

更多時候脐瑰,磁盤問題還是性能上的問題。我們可以通過 iostat -d -k -x來進行分析

image

最后一列%util可以看到每塊磁盤寫入的程度廷臼,而rrqpm/s以及wrqm/s分別表示讀寫速度苍在,一般就能幫助定位到具體哪塊磁盤出現(xiàn)問題了。另外我們還需要知道是哪個進程在進行讀寫荠商,一般來說開發(fā)自己心里有數(shù)寂恬,或者用 iotop 命令來進行定位文件讀寫的來源。

image

不過這邊拿到的是 tid莱没,我們要轉換成 pid初肉,可以通過 readlink 來找到 pidreadlink -f /proc/*/task/tid/../..。

image

找到 pid 之后就可以看這個進程具體的讀寫情況cat /proc/pid/io

image

我們還可以通過 lsof 命令來確定具體的文件讀寫情況 lsof -p pid

image

內存

內存問題排查起來相對比 CPU 麻煩一些饰躲,場景也比較多牙咏。主要包括 OOM、GC 問題和堆外內存嘹裂。一般來講妄壶,我們會先用 free 命令先來檢查一發(fā)內存的各種情況。

image

堆內內存

內存問題大多還都是堆內內存問題寄狼。表象上主要分為 OOM 和 Stack Overflow丁寄。

OOM

JMV 中的內存不足,OOM 大致可以分為以下幾種:

Exception in thread “main” java.lang.OutOfMemoryError: unable to create new native thread

這個意思是沒有足夠的內存空間給線程分配 Java 棧泊愧,基本上還是線程池代碼寫的有問題狡逢,比如說忘記 shutdown,所以說應該首先從代碼層面來尋找問題拼卵,使用 jstack 或者 jmap奢浑。如果一切都正常,JVM 方面可以通過指定Xss來減少單個 thread stack 的大小腋腮。另外也可以在系統(tǒng)層面雀彼,可以通過修改/etc/security/limits.confnofile 和 nproc 來增大 os 對線程的限制壤蚜。

image

Exception in thread “main” java.lang.OutOfMemoryError: Java heap space

這個意思是堆的內存占用已經(jīng)達到-Xmx 設置的最大值,應該是最常見的 OOM 錯誤了徊哑。解決思路仍然是先應該在代碼中找袜刷,懷疑存在內存泄漏,通過 jstack 和 jmap 去定位問題莺丑。如果說一切都正常著蟹,才需要通過調整Xmx的值來擴大內存。

Caused by: java.lang.OutOfMemoryError: Meta space

這個意思是元數(shù)據(jù)區(qū)的內存占用已經(jīng)達到XX:MaxMetaspaceSize設置的最大值梢莽,排查思路和上面的一致萧豆,參數(shù)方面可以通過XX:MaxPermSize來進行調整(這里就不說 1.8 以前的永久代了)。

Stack Overflow

棧內存溢出昏名,這個大家見到也比較多涮雷。

Exception in thread “main” java.lang.StackOverflowError

表示線程棧需要的內存大于 Xss 值,同樣也是先進行排查轻局,參數(shù)方面通過Xss來調整洪鸭,但調整的太大可能又會引起 OOM。

使用 JMAP 定位代碼內存泄漏

上述關于 OOM 和 Stack Overflow 的代碼排查方面仑扑,我們一般使用 JMAPjmap -dump:format=b,file=filename pid來導出 dump 文件

image

通過 mat(Eclipse Memory Analysis Tools)導入 dump 文件進行分析览爵,內存泄漏問題一般我們直接選 Leak Suspects 即可,mat 給出了內存泄漏的建議镇饮。另外也可以選擇 Top Consumers 來查看最大對象報告蜓竹。

和線程相關的問題可以選擇 thread overview 進行分析。除此之外就是選擇 Histogram 類概覽來自己慢慢分析盒让,大家可以搜搜 mat 的相關教程。

image

日常開發(fā)中司蔬,代碼產(chǎn)生內存泄漏是比較常見的事邑茄,并且比較隱蔽,需要開發(fā)者更加關注細節(jié)俊啼。比如說每次請求都 new 對象肺缕,導致大量重復創(chuàng)建對象;進行文件流操作但未正確關閉授帕;手動不當觸發(fā) gc同木;ByteBuffer 緩存分配不合理等都會造成代碼 OOM。

另一方面跛十,我們可以在啟動參數(shù)中指定-XX:+HeapDumpOnOutOfMemoryError來保存 OOM 時的 dump 文件彤路。

gc 問題和線程

gc 問題除了影響 CPU 也會影響內存,排查思路也是一致的芥映。一般先使用 jstat 來查看分代變化情況洲尊,比如 youngGC 或者 fullGC 次數(shù)是不是太多呀远豺;EU坞嘀、OU 等指標增長是不是異常呀等。

線程的話太多而且不被及時 gc 也會引發(fā) oom丽涩,大部分就是之前說的unable to create new native thread。除了 jstack 細細分析 dump 文件外矢渊,我們一般先會看下總體線程,通過 pstreee -p pid |wc -l锰瘸。

image

或者直接通過查看/proc/pid/task的數(shù)量即為線程數(shù)量昂灵。

image

堆外內存

如果碰到堆外內存溢出,那可真是太不幸了眨补。首先堆外內存溢出表現(xiàn)就是物理常駐內存增長快管削,報錯的話視使用方式都不確定,如果由于使用 Netty 導致的撑螺,那錯誤日志里可能會出現(xiàn)OutOfDirectMemoryError錯誤含思,如果直接是 DirectByteBuffer,那會報OutOfMemoryError: Direct buffer memory甘晤。

堆外內存溢出往往是和 NIO 的使用相關含潘,一般我們先通過 pmap 來查看下進程占用的內存情況

pmap -x pid | sort -rn -k3 | head -30

這段意思是查看對應 pid 倒序前 30 大的內存段。這邊可以再一段時間后再跑一次命令看看內存增長情況线婚,或者和正常機器比較可疑的內存段在哪里遏弱。

image

我們如果確定有可疑的內存端,需要通過 gdb 來分析

gdb --batch --pid {pid} -ex "dump memory filename.dump {內存起始地址} {內存起始地址+內存塊大小}"
image

獲取 dump 文件后可用 heaxdump 進行查看hexdump -C filename | less塞弊,不過大多數(shù)看到的都是二進制亂碼漱逸。

NMT 是 Java7U40 引入的 HotSpot 新特性,配合 jcmd 命令我們就可以看到具體內存組成了游沿。需要在啟動參數(shù)中加入 -XX:NativeMemoryTracking=summary 或者 -XX:NativeMemoryTracking=detail饰抒,會有略微性能損耗。

一般對于堆外內存緩慢增長直到爆炸的情況來說诀黍,可以先設一個基線

jcmd pid VM.native_memory baseline
image

然后等放一段時間后再去看看內存增長的情況袋坑,通過jcmd pid VM.native_memory detail.diff(summary.diff)做一下 summary 或者 detail 級別的 diff。

image
image

可以看到 jcmd 分析出來的內存十分詳細眯勾,包括堆內咒彤、線程以及 gc(所以上述其他內存異常其實都可以用 nmt 來分析)疆柔,這邊堆外內存我們重點關注 Internal 的內存增長,如果增長十分明顯的話那就是有問題了镶柱。

detail 級別的話還會有具體內存段的增長情況旷档,如下圖歇拆。

image

此外在系統(tǒng)層面故觅,我們還可以使用 strace 命令來監(jiān)控內存分配 strace -f -e “brk,mmap,munmap” -p pid

這邊內存分配信息主要包括了 pid 和內存地址输吏。

image

不過其實上面那些操作也很難定位到具體的問題點拄氯,關鍵還是要看錯誤日志棧译柏,找到可疑的對象鄙麦,搞清楚它的回收機制胯府,然后去分析對應的對象恨胚。比如 DirectByteBuffer 分配內存的話与纽,是需要 full GC 或者手動 system.gc 來進行回收的(所以最好不要使用-XX:+DisableExplicitGC)急迂。

那么其實我們可以跟蹤一下 DirectByteBuffer 對象的內存情況僚碎,通過jmap -histo:live pid手動觸發(fā) fullGC 來看看堆外內存有沒有被回收勺阐。如果被回收了,那么大概率是堆外內存本身分配的太小了蟆豫,通過-XX:MaxDirectMemorySize進行調整十减。如果沒有什么變化帮辟,那就要使用 jmap 去分析那些不能被 gc 的對象由驹,以及和 DirectByteBuffer 之間的引用關系了蔓榄。

GC 問題

堆內內存泄漏總是和 GC 異常相伴润樱。不過 GC 問題不只是和內存問題相關壹若,還有可能引起 CPU 負載店展、網(wǎng)絡問題等系列并發(fā)癥秃流,只是相對來說和內存聯(lián)系緊密些舶胀,所以我們在此單獨總結一下 GC 相關問題嚣伐。

我們在 CPU 章介紹了使用 jstat 來獲取當前 GC 分代變化信息轩端。而更多時候,我們是通過 GC 日志來排查問題的壳影,在啟動參數(shù)中加上-verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps來開啟 GC 日志宴咧。

常見的 Young GC悠汽、Full GC 日志含義在此就不做贅述了柿冲。

針對 gc 日志假抄,我們就能大致推斷出 youngGC 與 fullGC 是否過于頻繁或者耗時過長宿饱,從而對癥下藥谬以。我們下面將對 G1 垃圾收集器來做分析为黎,這邊也建議大家使用 G1-XX:+UseG1GC铭乾。

youngGC 過頻繁

youngGC 頻繁一般是短周期小對象較多炕檩,先考慮是不是 Eden 區(qū)/新生代設置的太小了笛质,看能否通過調整-Xmn妇押、-XX:SurvivorRatio 等參數(shù)設置來解決問題舆吮。如果參數(shù)正常色冀,但是 young gc 頻率還是太高锋恬,就需要使用 Jmap 和 MAT 對 dump 文件進行進一步排查了与学。

youngGC 耗時過長

耗時過長問題就要看 GC 日志里耗時耗在哪一塊了索守。以 G1 日志為例卵佛,可以關注 Root Scanning截汪、Object Copy衙解、Ref Proc 等階段蚓峦。Ref Proc 耗時長枫匾,就要注意引用相關的對象干茉。Root Scanning 耗時長角虫,就要注意線程數(shù)戳鹅、跨代引用枫虏。Object Copy 則需要關注對象生存周期隶债。

而且耗時分析它需要橫向比較死讹,就是和其他項目或者正常時間段的耗時比較赞警。比如說圖中的 Root Scanning 和正常時間段比增長較多愧旦,那就是起的線程太多了笤虫。

image

觸發(fā) fullGC

G1 中更多的還是 mixedGC境蜕,但 mixedGC 可以和 youngGC 思路一樣去排查粱年。觸發(fā) fullGC 了一般都會有問題台诗,G1 會退化使用 Serial 收集器來完成垃圾的清理工作拉队,暫停時長達到秒級別粱快,可以說是半跪了事哭。

fullGC 的原因可能包括以下這些鳍咱,以及參數(shù)調整方面的一些思路:

  • 并發(fā)階段失敯肌:在并發(fā)標記階段,MixGC 之前老年代就被填滿了涡戳,那么這時候 G1 就會放棄標記周期。這種情況挠将,可能就需要增加堆大小舔稀,或者調整并發(fā)標記線程數(shù)-XX:ConcGCThreads内贮。

  • 晉升失斠褂簟:在 GC 的時候沒有足夠的內存供存活/晉升對象使用竞端,所以觸發(fā)了 Full GC事富。這時候可以通過-XX:G1ReservePercent來增加預留內存百分比统台,減少-XX:InitiatingHeapOccupancyPercent來提前啟動標記贱勃,-XX:ConcGCThreads來增加標記線程數(shù)也是可以的募寨。

  • 大對象分配失敯斡ァ:大對象找不到合適的 region 空間進行分配列肢,就會進行 fullGC瓷马,這種情況下可以增大內存或者增大-XX:G1HeapRegionSize欧聘。

  • 程序主動執(zhí)行 System.gc():不要隨便寫就對了怀骤。

另外蒋伦,我們可以在啟動參數(shù)中配置-XX:HeapDumpPath=/xxx/dump.hprof來 dump fullGC 相關的文件痕届,并通過 jinfo 來進行 gc 前后的 dump

jinfo -flag +HeapDumpBeforeFullGC pid
jinfo -flag +HeapDumpAfterFullGC pid
jinfo -flag +HeapDumpBeforeFullGC pid
jinfo -flag +HeapDumpAfterFullGC pid

這樣得到 2 份 dump 文件研叫,對比后主要關注被 gc 掉的問題對象來定位問題嚷炉。

網(wǎng)絡

涉及到網(wǎng)絡層面的問題一般都比較復雜渤昌,場景多,定位難迈窟,成為了大多數(shù)開發(fā)的噩夢车酣,應該是最復雜的了湖员。這里會舉一些例子娘摔,并從 tcp 層凳寺、應用層以及工具的使用等方面進行闡述。

超時

超時錯誤大部分處在應用層面逆趋,所以這塊著重理解概念闻书。超時大體可以分為連接超時和讀寫超時魄眉,某些使用連接池的客戶端框架還會存在獲取連接超時和空閑連接清理超時杆融。

  • 讀寫超時霜运。readTimeout/writeTimeout,有些框架叫做 so_timeout 或者 socketTimeout池摧,均指的是數(shù)據(jù)讀寫超時作彤。注意這邊的超時大部分是指邏輯上的超時竭讳。soa 的超時指的也是讀超時。讀寫超時一般都只針對客戶端設置灿渴。

  • 連接超時骚露。connectionTimeout,客戶端通常指與服務端建立連接的最大時間倦零。服務端這邊 connectionTimeout 就有些五花八門了,Jetty 中表示空閑連接清理時間畜份,Tomcat 則表示連接維持的最大時間爆雹。

  • 其他愕鼓。包括連接獲取超時 connectionAcquireTimeout 和空閑連接清理超時 idleConnectionTimeout册倒。多用于使用連接池或隊列的客戶端或服務端框架磺送。

我們在設置各種超時時間中估灿,需要確認的是盡量保持客戶端的超時小于服務端的超時,以保證連接正常結束域慷。

在實際開發(fā)中,我們關心最多的應該是接口的讀寫超時了弛针。

如何設置合理的接口超時是一個問題钦奋。如果接口超時設置的過長朦拖,那么有可能會過多地占用服務端的 tcp 連接厌衔。而如果接口設置的過短睬隶,那么接口超時就會非常頻繁苏潜。

服務端接口明明 rt 降低,但客戶端仍然一直超時又是另一個問題贴唇。這個問題其實很簡單,客戶端到服務端的鏈路包括網(wǎng)絡傳輸瓶您、排隊以及服務處理等呀袱,每一個環(huán)節(jié)都可能是耗時的原因压鉴。

TCP 隊列溢出

tcp 隊列溢出是個相對底層的錯誤锻拘,它可能會造成超時、rst 等更表層的錯誤歌豺。因此錯誤也更隱蔽类咧,所以我們單獨說一說痕惋。

image

如上圖所示议谷,這里有兩個隊列:syns queue(半連接隊列)卧晓、accept queue(全連接隊列)逼裆。三次握手艺晴,在 server 收到 client 的 syn 后封寞,把消息放到 syns queue狈究,回復 syn+ack 給 client抖锥,server 收到 client 的 ack,如果這時 accept queue 沒滿拯勉,那就從 syns queue 拿出暫存的信息放入 accept queue 中憔购,否則按 tcp_abort_on_overflow 指示的執(zhí)行宫峦。

tcp_abort_on_overflow 0 表示如果三次握手第三步的時候 accept queue 滿了那么 server 扔掉 client 發(fā)過來的 ack。tcp_abort_on_overflow 1 則表示第三步的時候如果全連接隊列滿了玫鸟,server 發(fā)送一個 rst 包給 client导绷,表示廢掉這個握手過程和這個連接,意味著日志里可能會有很多connection reset / connection reset by peer屎飘。

那么在實際開發(fā)中妥曲,我們怎么能快速定位到 tcp 隊列溢出呢?

netstat 命令钦购,執(zhí)行 netstat -s | egrep “l(fā)isten|LISTEN”

image

如上圖所示肮雨,overflowed 表示全連接隊列溢出的次數(shù),sockets dropped 表示半連接隊列溢出的次數(shù)。

ss 命令沐批,執(zhí)行 ss -lnt

image

上面看到 Send-Q 表示第三列的 listen 端口上的全連接隊列最大為 5躺彬,第一列 Recv-Q 為全連接隊列當前使用了多少她君。

接著我們看看怎么設置全連接桨螺、半連接隊列大小吧:

全連接隊列的大小取決于 min(backlog, somaxconn)辣苏。backlog 是在 socket 創(chuàng)建的時候傳入的退客,somaxconn 是一個 os 級別的系統(tǒng)參數(shù)。而半連接隊列的大小取決于 max(64, /proc/sys/net/ipv4/tcp_max_syn_backlog)务傲。

在日常開發(fā)中,我們往往使用 servlet 容器作為服務端,所以我們有時候也需要關注容器的連接隊列大小。在 Tomcat 中 backlog 叫做acceptCount携悯,在 Jetty 里面則是acceptQueueSize。

RST 異常

RST 包表示連接重置,用于關閉一些無用的連接,通常表示異常關閉,區(qū)別于四次揮手。

在實際開發(fā)中静浴,我們往往會看到connection reset / connection reset by peer錯誤,這種情況就是 RST 包導致的。

端口不存在

如果像不存在的端口發(fā)出建立連接 SYN 請求,那么服務端發(fā)現(xiàn)自己并沒有這個端口則會直接返回一個 RST 報文,用于中斷連接。

主動代替 FIN 終止連接

一般來說椒楣,正常的連接關閉都是需要通過 FIN 報文實現(xiàn)吩屹,然而我們也可以用 RST 報文來代替 FIN,表示直接終止連接。實際開發(fā)中,可設置 SO_LINGER 數(shù)值來控制,這種往往是故意的遵蚜,來跳過 TIMED_WAIT雷滋,提供交互效率,不閑就慎用碰辅。

客戶端或服務端有一邊發(fā)生了異常,該方向對端發(fā)送 RST 以告知關閉連接

我們上面講的 tcp 隊列溢出發(fā)送 RST 包其實也是屬于這一種伐蒋。這種往往是由于某些原因全蝶,一方無法再能正常處理請求連接了(比如程序崩了催式,隊列滿了)捐下,從而告知另一方關閉連接晶框。

接收到的 TCP 報文不在已知的 TCP 連接內

比如窍育,一方機器由于網(wǎng)絡實在太差 TCP 報文失蹤了确镊,另一方關閉了該連接采呐,然后過了許久收到了之前失蹤的 TCP 報文,但由于對應的 TCP 連接已不存在,那么會直接發(fā)一個 RST 包以便開啟新的連接妻献。

image

接下來我們通過 wireshark 打開抓到的包嫌变,可能就能看到如下圖所示,紅色的就表示 RST 包了菇夸。

image

TIME_WAIT 和 CLOSE_WAIT

TIME_WAIT 和 CLOSE_WAIT 是啥意思相信大家都知道哗戈。

在線上時将鸵,我們可以直接用命令netstat -n | awk ‘/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}’來查看 time-wait 和 close_wait 的數(shù)量

用 ss 命令會更快ss -ant | awk ‘{++S[$1]} END {for(a in S) print a, S[a]}’

image

TIME_WAIT

time_wait 的存在一是為了丟失的數(shù)據(jù)包被后面連接復用螟左,二是為了在 2MSL 的時間范圍內正常關閉連接评雌。它的存在其實會大大減少 RST 包的出現(xiàn)。

過多的 time_wait 在短連接頻繁的場景比較容易出現(xiàn)和措。這種情況可以在服務端做一些內核參數(shù)調優(yōu):

#表示開啟重用诬留。允許將TIME-WAIT sockets重新用于新的TCP連接籍铁,默認為0,表示關閉net.ipv4.tcp_tw_reuse = 1#表示開啟TCP連接中TIME-WAIT sockets的快速回收,默認為0全释,表示關閉net.ipv4.tcp_tw_recycle = 1

當然我們不要忘記在 NAT 環(huán)境下因為時間戳錯亂導致數(shù)據(jù)包被拒絕的坑了装处,另外的辦法就是改小tcp_max_tw_buckets,超過這個數(shù)的 time_wait 都會被干掉浸船,不過這也會導致報time wait bucket table overflow的錯妄迁。

CLOSE_WAIT

close_wait 往往都是因為應用程序寫的有問題,沒有在 ACK 后再次發(fā)起 FIN 報文李命。close_wait 出現(xiàn)的概率甚至比 time_wait 要更高登淘,后果也更嚴重。往往是由于某個地方阻塞住了项戴,沒有正常關閉連接形帮,從而漸漸地消耗完所有的線程。

想要定位這類問題周叮,最好是通過 jstack 來分析線程堆棧來排查問題,具體可參考上述章節(jié)界斜。這里僅舉一個例子仿耽。

開發(fā)同學說應用上線后 CLOSE_WAIT 就一直增多,直到掛掉為止各薇,jstack 后找到比較可疑的堆棧是大部分線程都卡在了countdownlatch.await方法项贺,找開發(fā)同學了解后得知使用了多線程但是確沒有 catch 異常,修改后發(fā)現(xiàn)異常僅僅是最簡單的升級 sdk 后常出現(xiàn)的class not found峭判。

一方長期未收到另一方的確認報文开缎,在一定時間或重傳次數(shù)后發(fā)出 RST 報文

這種大多也和網(wǎng)絡環(huán)境相關了,網(wǎng)絡環(huán)境差可能會導致更多的 RST 報文林螃。

之前說過 RST 報文多會導致程序報錯奕删,在一個已關閉的連接上讀操作會報connection reset,而在一個已關閉的連接上寫操作則會報connection reset by peer疗认。通常我們可能還會看到broken pipe錯誤完残,這是管道層面的錯誤,表示對已關閉的管道進行讀寫横漏,往往是在收到 RST,報出connection reset錯后繼續(xù)讀寫數(shù)據(jù)報的錯,這個在 glibc 源碼注釋中也有介紹讲弄。

我們在排查故障時候怎么確定有 RST 包的存在呢熔号?當然是使用 tcpdump 命令進行抓包,并使用 wireshark 進行簡單分析了。tcpdump -i en0 tcp -w xxx.cap二蓝,en0 表示監(jiān)聽的網(wǎng)卡尊蚁。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市侣夷,隨后出現(xiàn)的幾起案子横朋,更是在濱河造成了極大的恐慌,老刑警劉巖百拓,帶你破解...
    沈念sama閱讀 212,383評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件琴锭,死亡現(xiàn)場離奇詭異,居然都是意外死亡衙传,警方通過查閱死者的電腦和手機决帖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蓖捶,“玉大人地回,你說我怎么就攤上這事】∮悖” “怎么了刻像?”我有些...
    開封第一講書人閱讀 157,852評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長并闲。 經(jīng)常有香客問我细睡,道長,這世上最難降的妖魔是什么帝火? 我笑而不...
    開封第一講書人閱讀 56,621評論 1 284
  • 正文 為了忘掉前任溜徙,我火速辦了婚禮,結果婚禮上犀填,老公的妹妹穿的比我還像新娘蠢壹。我一直安慰自己,他們只是感情好九巡,可當我...
    茶點故事閱讀 65,741評論 6 386
  • 文/花漫 我一把揭開白布图贸。 她就那樣靜靜地躺著,像睡著了一般比庄。 火紅的嫁衣襯著肌膚如雪求妹。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,929評論 1 290
  • 那天佳窑,我揣著相機與錄音制恍,去河邊找鬼。 笑死神凑,一個胖子當著我的面吹牛净神,可吹牛的內容都是我干的何吝。 我是一名探鬼主播,決...
    沈念sama閱讀 39,076評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼鹃唯,長吁一口氣:“原來是場噩夢啊……” “哼爱榕!你這毒婦竟也來了?” 一聲冷哼從身側響起坡慌,我...
    開封第一講書人閱讀 37,803評論 0 268
  • 序言:老撾萬榮一對情侶失蹤黔酥,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后洪橘,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體跪者,經(jīng)...
    沈念sama閱讀 44,265評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,582評論 2 327
  • 正文 我和宋清朗相戀三年熄求,在試婚紗的時候發(fā)現(xiàn)自己被綠了渣玲。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,716評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡弟晚,死狀恐怖忘衍,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情卿城,我是刑警寧澤枚钓,帶...
    沈念sama閱讀 34,395評論 4 333
  • 正文 年R本政府宣布,位于F島的核電站藻雪,受9級特大地震影響秘噪,放射性物質發(fā)生泄漏。R本人自食惡果不足惜勉耀,卻給世界環(huán)境...
    茶點故事閱讀 40,039評論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蹋偏。 院中可真熱鬧便斥,春花似錦、人聲如沸威始。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽黎棠。三九已至晋渺,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間脓斩,已是汗流浹背木西。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留随静,地道東北人八千。 一個月前我還...
    沈念sama閱讀 46,488評論 2 361
  • 正文 我出身青樓吗讶,卻偏偏與公主長得像,于是被迫代替她去往敵國和親恋捆。 傳聞我的和親對象是個殘疾皇子照皆,可洞房花燭夜當晚...
    茶點故事閱讀 43,612評論 2 350