漫遊MQ-socket 長連線
使用MQ傳送或者接收訊息,首先需要與broker 保持通訊,是怎樣工作的?
consumer繫結的listener是什麼時機觸發的?
Insight 過程使用的activemq,模板如下:
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory();
Connection connection = connectionFactory.createConnection();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
connection.start();
Topic topic = session.createTopic("log-topic");
MessageConsumer consumer = session.createConsumer(topic);
consumer.setMessageListener(new LogListener());
然後,建立session,也就是執行緒ActiveMQ Task-n 會建立關鍵的TcpTransport, 通過FailoverTransport.task 的iterate方法,開始建立連線。
TcpTransport 與broker建立了長連線,同時實現了Runnable介面,訊息的傳遞以及listener的觸發就看run() 的實現了。
過程如下:socket讀取-listener消費鏈處理-對應的session分發message- message 入佇列。
由上述的過程可以看到,consumer繫結的listener並沒有直接通知消費,接著看程式碼。
session建立的taskRunner,呼叫wakeup()後,啟動消費message佇列的執行緒,如果有message 入佇列,則分發至對應的consumer,具體的處理流程見原始碼:
public void dispatch(MessageDispatch md) {
MessageListener listener = this.messageListener.get();
try {
synchronized (unconsumedMessages.getMutex()) {
if (!unconsumedMessages.isClosed()) {
if (listener != null && unconsumedMessages.isRunning()) {
ActiveMQMessage message = createActiveMQMessage(md);
beforeMessageIsConsumed(md);
try {
boolean expired = message.isExpired();
if (!expired) {
listener.onMessage(message);
}
afterMessageIsConsumed(md, expired);
} catch (RuntimeException e) {
// ack rollback...
}
} else {
unconsumedMessages.enqueue(md);
if (availableListener != null) {
availableListener.onMessageAvailable(this);
}
}
}
}
} catch (Exception e) {
session.connection.onClientInternalException(e);
}
}
結論:
mq 的通訊預設使用tcp socket 長連線實現,支援failover。
consumer繫結的listener由session 級別的執行緒去觸發,沒有listener 則將message轉入unconsume佇列,待呼叫receive()再消費該message。
備註:
mq封裝實現的自己的Executor用於長連線任務的管理,TaskRunnerFactory name = "ActiveMQ Task",真正的提交runnable task其實還是ThreadPoolExecutor去完成。
生成全域性唯一的Id,可以參考IdGenerator。
mq Command消費的listener傳遞鏈,可以參考TransportFilter 類。
相關文章
- 實現酒店無線覆蓋和無線漫遊
- 長連線和短連線
- 長連線與短連線
- 暑假旅遊新攻略,網路電話無漫遊打長途
- PDO 長連線
- HTTP長連線HTTP
- 漫遊HttpURLConnectionHTTP
- 長連線和短連線的使用
- http的長連線和短連線HTTP
- http Socket長連線HTTP
- php使用長連線PHP
- nginx 長連線配置Nginx
- 服務端漫遊服務端
- 輪詢、長輪詢、短連線、長連線區別對比
- WiFi漫遊卡頓嚴重,如何有效改善實現無縫漫遊WiFi
- JAVA之長連線、短連線和心跳包Java
- HTTP長連線和短連線原理淺析HTTP
- 【轉載】通訊長連線與短連線
- Websocket 突破最大長連線Web
- 使用mysql的長連線MySql
- HTTP 長連線問題HTTP
- 12、Swoole 中 TCP、UDP 和長連線、短連線TCPUDP
- HTTP長連線、短連線究竟是什麼?HTTP
- 聚焦業務場景,銳捷讓無線網路“零漫遊”
- Mysql關於長連線短連線優劣比較MySql
- 菜鳥學網路之 —— 長連線和短連線
- HTTP協議中的短輪詢、長輪詢、長連線和短連線HTTP協議
- http長短連線和長短輪詢HTTP
- 長連線的心跳及重連設計
- 計算機系統漫遊計算機
- D3.js 漫遊指南JS
- MySQL·引擎特性·InnoDBundolog漫遊MySql
- 一文讀透HTTP的長連線和短連線HTTP
- 談談HTTP協議中的短輪詢、長輪詢、長連線和短連線HTTP協議
- mysql連線池爆滿,釋放程式長連線殭屍程式MySql
- 長連線的心跳保持設計
- Springboot漫遊日誌(1)Spring Boot
- 內網漫遊之SOCKS代理大結局內網