ActiveMQ-05-JMS-可靠性機制

消息接收確認

JMS消息只有被確認之後,才被認為成功消費。成功消費一般情況下包含三個階段:客戶端接收消息,客戶端處理消息,客戶端消息被確認。

在事務型會話中(需設置Session.SESSION_TRANSACTED),一旦事務被提交,確認自動發生。在非事務會話中,消息什麼時候被確認取決於創建會話時的應答模式(acknowledged mode)。應答模式有三種:

Session.AUTO_ACKNOWLEDGE

當客戶端成功接受到消息,就會自動確認收到消息,比如receive方法或者MessageListener.onMessage方法,該方法返回後表明確認完畢。

<code>message = (MapMessage) consumer.receive();/<code>

Session.CLIENT_ACKNOWLEDGE

客戶端必須通過message明確調用acknowledge方法來確認收到消息,也就是說可以控制什麼時候發送確認消息。

<code>message = (MapMessage) consumer.receive();
message.acknowledge();/<code>

Session.DUPS_ACKNOWLEDGE

延遲確認,在這種確認模式下可能存在重複的提交,允許接收重複消息的應用程序可以使用該模式。比如說加入客戶端接受了5條消息,並且已經處理了,但是因為延遲提交了,所以在JMS服務端可能還沒有確認。這個時候假設JMS 服務器宕機,那麼重啟之後,可能會因為之前沒有提交的消息會進行重新發送,就導致服務端重複發送的問題。同時我們一般重新發送消息時會設置一個消息頭:JMSRedelivered設置為true。

生產者和JMS消息服務器

ActiveMQ-05-JMS-可靠性機制

生產者發送消息,然後進入阻塞,直到消息服務器收到一個確認為止。底層確認對客戶端編程模型來說是不可見的,如果中間任何環節可能出現異常,這時就會認為消息沒有被傳送。消息服務器收到消息,如果是持久化消息就會持久化到磁盤,否則存入內存,然後通知生產者已經接收到消息。上圖中可能出現的異常如下:

1.生產者發送消息失敗

可能由於網絡原因導致發送消息失敗,這時JMS服務器沒有感知,所以就需要生產者在代碼中做好異常檢測。

2.持久化失敗

生產者成功發送消息到JMS服務器,服務器在持久化時失敗,服務器會在第三步通知結果的時候,將錯誤信息返回給生產者,所以就需要生產者在代碼中做好異常檢測。

3.服務器通知生產者失敗

消費者成功接收消息並做完持久化後,在通知生產者時,出現網絡異常導致失敗,服務器沒有通知成功會刪除該消息,同時生產者會從阻塞中返回並拋出異常,所以就需要生產者在代碼中做好異常檢測。

可以看到上圖中可能出現異常的三種情況都需要在生產者中進行異常捕獲,然後處理異常。

事務消息

開啟事務後,一組消息要麼全部到達服務器,要麼都不到達服務器,生產者,消費者,消息服務器都直接支持事務。

生產者有事務發送消息

ActiveMQ-05-JMS-可靠性機制

從生產者角度來看,直到commit命令,如果過程中發生故障或者執行rollback,那麼這些消息會丟失。

消費者有事務接收消息

ActiveMQ-05-JMS-可靠性機制

從消費者角度來看,直到commit命令,如果過程中發生故障或者執行rollback,那麼生產者會重新發送消息,這些消息會被標記位重新傳送。

<code>/<code>
<code>public void onMessage(Message message){
	//try...
  TextMessage msg = (TextMessage) message;
  if(msg.getText().equals("end");{
  		session.commit();
  }
}/<code>

通過標記來作為判斷,接收完end結束標記後,在執行commit方法。

上述說的都是一些比較重要的,總結來說消息的可靠性其實可以從三方面來說:

  • 消息確認
  • 消息持久化
  • 本地事務

沒理解的可以留言,前邊幾篇都為理論,後續乾貨會比較多,關注不迷路,祝各位早日p8


分享到:


相關文章: