離線數據推送問題(消息隊列)

  天天晚上9點多我要起身下班的時候,擡眼看到周圍還在公司的也就只有幾個剛畢業的小鮮肉了,就感受本身也好年輕啊。雖然不止感受,其實原本也不老。可是轉眼又一想,我晚飯都不吃,天天多比人家工做了好幾個小時,可是水平的提升一點也不成正比啊,是否是方法不當啊。惟一成正比的,我確實把身體鍛鍊好了,騎自行車40千米來上班,中間不停,騎得飛快,整個路程整體仍是往高處走的,到公司休息一下正常上班,一點兒感受都沒有。有一種無知叫作不知道什麼事情是不可能的,想到就去作了。html

  直到中午和咱們同事90後MM去吃飯,她最近想在網上作些小生意。我纔想到:女孩子最大的劣勢在於專一。朋友圈裏好多有正式工做的女孩在弄微商,我卻沒見過一個技術特別好的男同事在弄副業的。我能夠同時作不少的事情,確實全部的事情都沒有作深刻到極致。人所能達到的境界不是和付出的時間成正比,而是和對本身的要求成正比。人的優秀程度是和野心成正比的。個人滿足常樂的心,在生活中是件好事,可是工做中倒是本身最大的挑戰了。和之間同事聊天,他說天天進步一點點就好。我說若是我如今天天只是進步一點點,那麼之後的進步就更慢了。這幾年中沒有一個質的飛越,過幾年就更難衝破前進的壁壘,最後是本身覺得本身在進步,別人看你只是原地打轉。java

  今天發生的問題:消息隊列報錯,實時消息沒有發送成功,重啓後問題消失。spring

 

繼續看其餘的錯誤日誌:數據庫

消息隊列採用公司統一的apache qpidd集羣。報錯的lesocms.video.guoguang.queue這個消費隊列。問題很清楚,生產者在我這邊,消費者在搜索部門。生產的東西消費者沒被消費掉,隊列積壓了。消費的問題不論是他們消費程序掛了仍是消費慢,都已經交給搜索部門去處理了,我這邊要解決遇到這種問題怎麼處理。apache

  問題1:隊列滿了以後嘗試了幾回後close,只能靠人工重啓重置鏈接的問題session

  解決方法: 找到幾個關鍵的異常點多線程

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  謝謝哦~~

相關文章
相關標籤/搜索