每天晚上9點多我要起身下班的時候,抬眼看到周圍還在公司的也就只有幾個剛畢業的小鮮肉了,就感覺自己也好年輕啊。雖然不止感覺,其實本來也不老。但是轉眼又一想,我晚飯都不吃,每天多比人家工作了好幾個小時,但是水平的提高一點也不成正比啊,是不是方法不當啊。唯一成正比的,我確實把身體鍛煉好了,騎自行車40公里來上班,中間不停,騎得飛快,整個路程總體還是往高處走的,到公司休息一下正常上班,一點兒感覺都沒有。有一種無知叫做不知道什么事情是不可能的,想到就去做了。
直到中午和我們同事90后MM去吃飯,她最近想在網上做些小生意。我才想到:女孩子最大的劣勢在於專注。朋友圈里好多有正式工作的女孩在弄微商,我卻沒見過一個技術特別好的男同事在弄副業的。我可以同時做很多的事情,確實所有的事情都沒有做深入到極致。人所能達到的境界不是和付出的時間成正比,而是和對自己的要求成正比。人的優秀程度是和野心成正比的。我的知足常樂的心,在生活中是件好事,但是工作中卻是自己最大的挑戰了。和之間同事聊天,他說每天進步一點點就好。我說如果我現在每天只是進步一點點,那么以后的進步就更慢了。這幾年中沒有一個質的飛越,過幾年就更難沖破前進的壁壘,最后是自己以為自己在進步,別人看你只是原地打轉。
今天發生的問題:消息隊列報錯,實時消息沒有發送成功,重啟后問題消失。
繼續看其他的錯誤日志:
消息隊列采用公司統一的apache qpidd集群。報錯的lesocms.video.guoguang.queue這個消費隊列。問題很清楚,生產者在我這邊,消費者在搜索部門。生產的東西消費者沒被消費掉,隊列積壓了。消費的問題不管是他們消費程序掛了還是消費慢,都已經交給搜索部門去處理了,我這邊要解決遇到這種問題怎么處理。
問題1:隊列滿了之后嘗試了幾次后close,只能靠人工重啟重置連接的問題
解決方法: 找到幾個關鍵的異常點
Caused by: org.apache.qpid.transport.SessionException: timed out waiting for sync: complete = -1, point = 0
Exception when sending message:timed out waiting for sync: complete = -1, point = 0
Caused by: org.apache.qpid.transport.SessionClosedException: session closed
Caused by: javax.jms.JMSException: Exception when sending message:session closed
異常剛開始的日志:
定位到剛開始異常的行:
找到異常前后的日志:
發現越往后的日志里,新增大量的 create class:com.letv.mms.transmission.task.sub.SwiftSendMsgTask
我專門查了一下 create class:com.letv.mms.transmission.task.sub.SwiftSendMsgTask的新建數量:
出問題的這天不斷的新建,正常穩定的時候是沒有新加的。SwiftSendMsgTask是我當初自己設計的一個對象連接池,目的在於如果消息的發送和正常向消息隊列里組裝消息是同步的,會造成第一實行性不能保證,因為有的專輯下面有幾萬個視頻,必須組裝成一個消息發送,這個消息組裝就要好幾分鍾。第二,組裝過程中數據庫連接池等待時間過長會自動關閉。所以我就直接異步發消息,從對象連接池中取出一個處理發消息的處理對象扔進去,直接處理下一個。如果處理消息的空閑對象不夠用我就直接新建一個放到連接池里。一直想好好總結一下離線數據的程序,因為這個程序整個架構基本上很原始,資源的調度分配都是程序自己控制的,基本沒用什么現成的技術。細節處處處體現精巧,每個設計都解決了特定的問題,但是總體去說這個程序,我卻很難把這個程序的獨到之處用語言表達出來。言歸正傳:
記得有次開會,組里誰說線上出了什么什么問題,不過倒是沒有異常。我不負責那個項目具體不知道,我只是笑着說:“那可能不是真的沒有異常,而是異常日志沒打好哦。”經常發現自己這句話說的很有道理。上面異常日志截圖里面都把.cpp文件的異常都打印出來了,完全可以按圖索驥。但是自己就是個寫代碼的自己知道,異常的說明文字未必准確,最好還是要查源碼。查BasicMessageProducer的源碼發現,首先這個session是AMQSession。那么它close了,為什么使用到的時候沒新建?org.springframework.jms.connection.CachingConnectionFactory的源碼里看到reconnectOnException默認是true,也就是說拋出了這個Jms異常理論上是會新建的,除非新建不成功,不成功是因為SwiftSendMsgTask的新建數量太多,超過了設定的<property name="sessionCacheSize" value="700"></property>。那么我要解決的就是SwiftSendMsgTask在異常后不要新建那么多的問題了。
將原有的一個對象池分成兩個,一個是無限制的對象池,使用時即創建。因為這個離線服務半夜有個跑全量的,我會起1000多個線程來跑,但是每次處理數據的線程池是50,因為這個環節要涉及大量CPU計算數據庫連接,雖然是高配物理機,而且數據庫是專門將線上數據實時復制的一個從庫,專門使用(線程數不大於100的時候效率高)。但是是24核CPU,計算量大,線程數大於50會有CPU跑滿的風險。但是每個線程會生成獨立的數據文件,然后進行gz壓縮。gz壓縮很耗時,但是消耗的IO資源,釋放了CPU,平時的時候跑全量時會存在600多個同時在壓縮,所以對這個的對象池無限制。他們問我:為啥你的程序執行的那么快,我的數量小,反而慢了那么多?因為你拷貝完我那一版之后我改了代碼[哭笑], 我把很多線程中不需要返回結果的,和大循環中的項都扔到另外的線程池里去啦。
發消息的單獨放到一個有限制的線程池里去管理。本來cacheSize是700,但是發現正常情況下就算數據量突增,100個都不解決問題的話(其實正常情況下會5個負責發消息的,因為消息體最大是4M,發消息是很快的,異步的,扔到exchange中即可,實時也沒有什么並發量),媒資程序那邊就掛了,異常不會到達這邊,折中一下資源,將cacheSize設置為100。程序中創建對象的時候,如果對象池的activeNum個數超過或者等於91個(因為最多會有8個sleeping的),則不會再新建。配了日志報警,到達40個系統會給我發報警郵件。
問題2:為什么數據量會突增
答案:咨詢了一下德偉:最近接了一批短視頻。實時的量發生了劇增。所以消費的能力突然不夠也是正常的。目前消費者有兩個:一個專輯的,一個視頻的。但是生產者只有一個,如果專輯或者視頻一個發生了突增,會影響到另一個。另外,專輯有的消息體特別大,極端情況下,一個隊列也就是能放100多個消息。所以決定將專輯和視頻分開,已經和搜索部門的同事達成協議。並提醒他們將隊列承載量采用最高配(500M)。因為發現他們那邊現在不是這么做的[汗]。
問題3:沒有收到消息隊列溢出的報警
答案:咨詢了管MQ集群的同事,報警沒加上[汗]。
相信問題解決到這個程度,下次再遇到這種問題,搜索的哥哥們下次就不會第一時間來找我了。下次溝通估計就是我出差回來給他們帶吃噠[勝利][勝利]
如需轉載,請注上我的原文鏈接: http://www.cnblogs.com/xiexj/p/6677694.html 謝謝哦~~