操屁眼的视频在线免费看,日本在线综合一区二区,久久在线观看免费视频,欧美日韩精品久久综

新聞資訊

    折騰ActiveMQ時遇到的問題和解決方法:

    1.先講嚴重的:服務掛掉。

    這得從ActiveMQ的儲存機制說起。在通常的情況下,非持久化消息是存儲在內存中的,持久化消息是存儲在文件中的,它們的最大限制在配置文件的<systemUsage>節點中配置。但是,在非持久化消息堆積到一定程度,內存告急的時候,ActiveMQ會將內存中的非持久化消息寫入臨時文件中,以騰出內存。雖然都保存到了文件里,但它和持久化消息的區別是,重啟后持久化消息會從文件中恢復,非持久化的臨時文件會直接刪除。

    那如果文件增大到達了配置中的最大限制的時候會發生什么?我做了以下實驗:

    設置2G左右的持久化文件限制,大量生產持久化消息直到文件達到最大限制,此時生產者阻塞,但消費者可正常連接并消費消息,等消息消費掉一部分,文件刪除又騰出空間之后,生產者又可繼續發送消息,服務自動恢復正常。

    設置2G左右的臨時文件限制,大量生產非持久化消息并寫入臨時文件,在達到最大限制時,生產者阻塞,消費者可正常連接但不能消費消息,或者原本慢速消費的消費者,消費突然停止。整個系統可連接,但是無法提供服務,就這樣掛了。

    具體原因不詳,解決方案:盡量不要用非持久化消息,非要用的話,將臨時文件限制盡可能的調大。

    詳細配置信息見文檔: http://activemq.apache.org/producer-flow-control.html

    2.丟消息。

    這得從java的java.net.SocketException異常說起。簡單點說就是當網絡發送方發送一堆數據,然后調用close關閉連接之后。這些發送的數據都在接收者的緩存里,接收者如果調用read方法仍舊能從緩存中讀取這些數據,盡管對方已經關閉了連接。但是當接收者嘗試發送數據時,由于此時連接已關閉,所以會發生異常,這個很好理解。不過需要注意的是,當發生SocketException后,原本緩存區中數據也作廢了,此時接收者再次調用read方法去讀取緩存中的數據,就會報Software caused connection abort: recv failed錯誤。

    通過抓包得知,ActiveMQ會每隔10秒發送一個心跳包,這個心跳包是服務器發送給客戶端的,用來判斷客戶端死沒死。如果你看過上面第一條,就會知道非持久化消息堆積到一定程度會寫到文件里,這個寫的過程會阻塞所有動作,而且會持續20到30秒,并且隨著內存的增大而增大。當客戶端發完消息調用connection.close()時,會期待服務器對于關閉連接的回答,如果超過15秒沒回答就直接調用socket層的close關閉tcp連接了。這時客戶端發出的消息其實還在服務器的緩存里等待處理,不過由于服務器心跳包的設置,導致發生了java.net.SocketException異常,把緩存里的數據作廢了,沒處理的消息全部丟失。

    解決方案:用持久化消息,或者非持久化消息及時處理不要堆積,或者啟動事務,啟動事務后,commit()方法會負責任的等待服務器的返回,也就不會關閉連接導致消息丟失了。

    關于java.net.SocketException請看我的詳細研究: http://blog.163.com/_kid/blog/static/3040547620160231534692/

    3.持久化消息非常慢。

    默認的情況下,非持久化的消息是異步發送的,持久化的消息是同步發送的,遇到慢一點的硬盤,發送消息的速度是無法忍受的。但是在開啟事務的情況下,消息都是異步發送的,效率會有2個數量級的提升。所以在發送持久化消息時,請務必開啟事務模式。其實發送非持久化消息時也建議開啟事務,因為根本不會影響性能。

    4.消息的不均勻消費。

    有時在發送一些消息之后,開啟2個消費者去處理消息。會發現一個消費者處理了所有的消息,另一個消費者根本沒收到消息。原因在于ActiveMQ的prefetch機制。當消費者去獲取消息時,不會一條一條去獲取,而是一次性獲取一批,默認是1000條。這些預獲取的消息,在還沒確認消費之前,在管理控制臺還是可以看見這些消息的,但是不會再分配給其他消費者,此時這些消息的狀態應該算作“已分配未消費”,如果消息最后被消費,則會在服務器端被刪除,如果消費者崩潰,則這些消息會被重新分配給新的消費者。但是如果消費者既不消費確認,又不崩潰,那這些消息就永遠躺在消費者的緩存區里無法處理。更通常的情況是,消費這些消息非常耗時,你開了10個消費者去處理,結果發現只有一臺機器吭哧吭哧處理,另外9臺啥事不干。

    解決方案:將prefetch設為1,每次處理1條消息,處理完再去取,這樣也慢不了多少。

    詳細文檔: http://activemq.apache.org/what-is-the-prefetch-limit-for.html

    5.死信隊列。

    如果你想在消息處理失敗后,不被服務器刪除,還能被其他消費者處理或重試,可以關閉AUTO_ACKNOWLEDGE,將ack交由程序自己處理。那如果使用了AUTO_ACKNOWLEDGE,消息是什么時候被確認的,還有沒有阻止消息確認的方法?有!

    消費消息有2種方法,一種是調用consumer.receive()方法,該方法將阻塞直到獲得并返回一條消息。這種情況下,消息返回給方法調用者之后就自動被確認了。另一種方法是采用listener回調函數,在有消息到達時,會調用listener接口的onMessage方法。在這種情況下,在onMessage方法執行完畢后,消息才會被確認,此時只要在方法中拋出異常,該消息就不會被確認。那么問題來了,如果一條消息不能被處理,會被退回服務器重新分配,如果只有一個消費者,該消息又會重新被獲取,重新拋異常。就算有多個消費者,往往在一個服務器上不能處理的消息,在另外的服務器上依然不能被處理。難道就這么退回--獲取--報錯死循環了嗎?

    在重試6次后,ActiveMQ認為這條消息是“有毒”的,將會把消息丟到死信隊列里。如果你的消息不見了,去ActiveMQ.DLQ里找找,說不定就躺在那里。

    詳細文檔: http://activemq.apache.org/redelivery-policy.html

    http://activemq.apache.org/message-redelivery-and-dlq-handling.html


    監控到容器的cpu使用率過高問題

    當Grafana監控到Container Cpu Usage is high指標并告警,則說明activemq容器cpu使用率過高,為避免業務因 CPU 資源不足而受影響,建議提前對 CPU 利用率過高的實例進行業務優化,例如控制高并發,或者升級 CPU 資源,若參數調整后,而 CPU 利用率依然偏高,建議找維護人員升級 CPU 的配置,進而提高activemq的整體性能

    排查方法

    通過top命令找到可疑進程PID,或者top -H找出消耗資源最高的線程

    查看這個線程所有系統調用strace -p 24167

    通過這3步基本可以找出什么原因導致java進程占用那么高CPU資源

    監控到容器網絡入流量/網絡出流量告警問題

    當Grafana監控到Container Network Throughput In is high/Container Network Throughput Out is high指標告警,則表示出現網絡流量過高的情況,通常是因為服務器與服務器之間拷貝數據導致的,拷貝結束,流量即可恢復正常,如果不是數據拷貝,通常是服務器中毒或者受到攻擊,在對內或對外大量發包導致,此時,可按照以下方法進行排查

    • 如果您使用的是Linux系統的服務器,可以在系統中安裝nethogs查看具體的進程占用流量的情況(如nether eth0->查看網卡具體流量)并殺死該進程;對于一些常見的網絡問題,如容器之間網絡通信問題,您可以使用Tcpdump工具捕獲網絡流量,來解決這些網絡問題
    • 如果您使用的是windows系統,可通過資源監視器(啟動任務管理器>資源監視器>網絡)看到哪些進程占用網絡流量并結束相關進程

    監控到容器down告警問題

    當prometheus監控到容器down指標Container Killed告警,說明容器可能失效或終止運行,以異常狀態退出或健康檢查失敗,k8s的核心組件 kubelet會根據設置的pod重啟策略自動重啟該容器,例如容器運行時內存超出限制,容器以Failed狀態終止,kubelet則自動重啟該容器。而pod中的守護進程supervisor會保證activemq服務自動重啟。

    監控到容器內存使用率過高問題

    當prometheus監控到Container Memory Usage is high 告警,說明容器內存使用率過高, 檢查是否除activemq相關進程在運行外,還有其他不必要進程在運行,若有,可以關閉非必要進程。若是activemq已超過已使用流量的閾值,導致容器的memary的使用率超過預期,可以結合activemq的內存使用率進行分析,見下面提到的內存使用率過高問題

    監控到容器存儲使用率過高問題

    當prometheus監控到 Container Volume Usage is high告警,說明容器的存儲使用率過高, 首先檢查是哪一個目錄的磁盤量已快耗盡,如果是activemq的掛載目錄的磁盤已快滿,考慮定時刪除過期的消息文件,或是由于備份文件過大,可以增大磁盤容量,如果是其他目錄,檢查是否有垃圾緩存,或者其余日志文件,可以考慮只保留最新的內容。

    監控到ActiveMQ內存使用率過高問題

    當prometheus監控到activemq_memory_usage_ratio指標告警,則反映activemq使用內存接近耗盡

    可能原因及現象

    當消息數量超過了broker資源的限制,導致內存耗盡,生產者收到broker的阻塞信息提示,生產緩慢 或不再生產消息,broker幾乎停止對外服務

    解決辦法

    • 消費者端流控 在消費者端,流量控制是通過prefetchSize參數來控制未確認情況下,最多可以預獲取多少條記錄 ,如 tcp://localhost:61616?jms.prefetchPolicy.all=50 tcp://localhost:61616?jms.prefetchPolicy.queuePrefetch=1
    • 生產者端流控 /opt/apache-activemq-5.14.3/conf/activemq.xml中添加<sendFailIfNoSpaceAfterTimeout>屬性,單位是毫秒,它會阻塞指定的時間,如果超過了這個時間還是沒有可用的內存,則會發送異常給生產端,其配置如下 <systemUsage> <systemUsage sendFailIfNoSpaceAfterTimeout="3000"> <memoryUsage> <memoryUsage limit="20 mb"/> </memoryUsage> </systemUsage>
    • 增加虛機內存,增加容器應用的內存預留,升級應用

    監控到ActiveMQ硬盤空間使用量告警問題

    當prometheus監控到activemq_store_usage_ratio指標告警,則反映持久化消息幾乎占滿硬盤,分配的硬盤空間使用量接近耗盡, 此時生產者阻塞,但消費者可正常連接并消費消息,等消息消費掉一部分,文件刪除又騰出空間之后,生產者又可繼續發送消息,服務自動恢復正常

    報錯日志:Usage Manager Store is Full, 100% of 1073741824. Stopping producer (ID:db01-48754-1336034955132-0:5:1:1) to prevent flooding queue://queue.land.group...

    原因分析

    如果持久訂閱者很多,有幾個一直不在線,則導致db-.log文件中的持久化消息一直保留,只有所有持久訂閱者上線后才會刪除db-.log , 若是有很多持久訂閱者不在線,分配的磁盤就可能撐爆

    解決辦法

    • 檢查持久訂閱者是否異常下線
    • /opt/apache-activemq-5.14.3/conf/activemq.xml文件中增加硬盤分配 <storeUsage> <!-- 持久化消息占用硬盤大小 --> <storeUsage limit="100 gb"/> </storeUsage>

    監控到ActiveMQ臨時文件硬盤空間使用量告警問題

    當prometheus監控到activemq_temp_usage_ratio指標告警,則反映產生的非持久化消息過多使得分配的臨時文件硬盤空間使用量達到上限

    解決辦法

    /opt/apache-activemq-5.14.3/conf/activemq.xml文件中增加臨時硬盤分配

    <tempUsage>

    <!-- 非持久化消息占用硬盤大小 -->

    <tempUsage limit="50 gb"/>

    </tempUsage>


    監控到ActiveMQ的未消費消息數量告警問題

    當prometheus監控到activemq_queue_queue_size(隊列的未消費消息數量)或activemq_topic_queue_size(某主題訂閱者未消費消息數量)指標告警,則反映未被消費的消息數量過多,pending消息堆積則可能導致activemq的整體性能下降

    解決辦法

    設置消息的全局過期時間,在broker節點下增加如下的配置

    <plugins>

    <!-- 86,400,000ms=1 day -->

    <timeStampingBrokerPlugin ttlCeiling="10000" zeroExpirationOverride="10000"/>

    </plugins>

    ttlCeiling表示過期時間上限(程序寫的過期時間不能超過此時間,超過則以此時間為準) zeroExpirationOverride表示過期時間(給未分配過期時間的消息分配過期時間)

    消息過期后會進入死信隊列,AcitveMQ提供了一個便捷的插件DiscardingDLQBrokerPlugin來拋棄死信隊列或主題,配置如下

    <plugins>

    <!-- 丟棄所有死信-->

    <discardingDLQBrokerPlugindropAll="true" dropTemporaryTopics="true" dropTemporaryQueues="true" />

    </plugins>

    超過最大客戶端連接數問題

    當連接到activemq的生產者消費者客戶端超過一定數量,通過grafana查看/opt/apache-activemq-5.14.3/data目錄下的activemq.log,發現報錯

    2020-03-04 20:25:27,760 | ERROR | Could not accept connection : org.apache.activemq.transport.tcp.ExceededMaximumConnectionsException: Exceeded the maximum number of allowed client connections. See the 'maximumConnections' property on the TCP transport configuration URI in the ActiveMQ configuration file (e.g., activemq.xml) | org.apache.activemq.broker.TransportConnector | ActiveMQ Transport Server Thread Handler: mqtt://0.0.0.0:1883?maximumConnections=100&wireFormat.maxFrameSize=104857600

    解決辦法

    /opt/apache-activemq-5.14.3/conf/activemq.xml中修改對應協議的<maximumConnections>參數

    <transportConnector name="mqtt" uri="mqtt://0.0.0.0:1883?maximumConnections=100&wireFormat.maxFrameSize=104857600"/>

    Activemq內存分配問題

    /opt/apache-activemq-5.14.3/conf/activemq.xml文件中配置內存分配

    <systemUsage>

    <memoryUsage>

    <!-- 非持久化消息占用Jvm內存大小 -->

    <memoryUsage percentOfJvmHeap="70" />

    </memoryUsage>

    <storeUsage>

    <!-- 持久化消息占用硬盤大小 -->

    <storeUsage limit="100 gb"/>

    </storeUsage>

    <tempUsage>

    <!-- 非持久化消息占用硬盤大小 -->

    <tempUsage limit="50 gb"/>

    </tempUsage>

    </systemUsage>

    訂閱者下線斷連問題

    原因分析

    ActiveMQ InactivityMonitor是一個活動線程,用于檢查連接是否仍處于活動狀態,如果默認30秒鐘內未從連接中寫入或讀取任何數據,則InactivityMonitor將啟動 InactivityMonitor引發InactivityIOException并關閉與該連接關聯的傳輸。將導致以下調試日志記錄

    2012-06-26 17:13:55,712 | DEBUG | 30000 ms elapsed since last read check. | org.apache.activemq.transport.AbstractInactivityMonitor | InactivityMonitor ReadCheck 2012-06-26 17:13:55,712 | DEBUG | No message received since last read check for tcp:///127.0.0.1:52659! Throwing InactivityIOException. | org.apache.activemq.transport.AbstractInactivityMonitor | InactivityMonitor ReadCheck 2012-06-26 17:13:55,714 | DEBUG | Transport Connection to: tcp://127.0.0.1:52659 failed: org.apache.activemq.transport.InactivityIOException: Channel was inactive for too (>30000) long: tcp://127.0.0.1:52659 ...

    解決辦法

    在建立連接的Uri中加入<wireFormat.maxInactivityDuration=0>,關閉不活動狀態監測

    <transportConnectors>

    <transportConnector name="openwire" uri="tcp://0.0.0.0:61616?wireFormat.maxInactivityDuration=0

    </transportConnectors>

網站首頁   |    關于我們   |    公司新聞   |    產品方案   |    用戶案例   |    售后服務   |    合作伙伴   |    人才招聘   |   

友情鏈接: 餐飲加盟

地址:北京市海淀區    電話:010-     郵箱:@126.com

備案號:冀ICP備2024067069號-3 北京科技有限公司版權所有