漫遊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 類。
相關文章
- 長連線和短連線
- HTTP長連線HTTP
- PDO 長連線
- http的長連線和短連線HTTP
- 長連線和短連線的使用
- 輪詢、長輪詢、短連線、長連線區別對比
- JAVA之長連線、短連線和心跳包Java
- 實現酒店無線覆蓋和無線漫遊
- HTTP長連線、短連線究竟是什麼?HTTP
- 12、Swoole 中 TCP、UDP 和長連線、短連線TCPUDP
- Websocket 突破最大長連線Web
- 菜鳥學網路之 —— 長連線和短連線
- Mysql關於長連線短連線優劣比較MySql
- 長連線的心跳及重連設計
- 一文讀透HTTP的長連線和短連線HTTP
- SQL Server如何判斷哪些會話/連線是長連線?SQLServer會話
- 遊戲漢化組:陪玩家走過漫長黑夜遊戲
- Socket程式設計-長連線與短連線,心跳(keep-alive)程式設計Keep-Alive
- 長連線的心跳保持設計
- 萬字長文帶你漫遊資料結構世界資料結構
- 聊聊 TCP 長連線和心跳那些事TCP
- 手把手教你寫 Socket 長連線
- Android 架構之長連線技術Android架構
- Nginx上游伺服器長連線配置Nginx伺服器
- Kubernetes 漫遊:etcd
- 夜間漫遊
- 內連線、左連線、右連線
- Android 長連線初體驗(基於netty)AndroidNetty
- 長連線資料實時推送方案(iOS)iOS
- Android websocket長連線+點對點訂閱AndroidWeb
- Gopusher 一個通用的長連線服務Go
- Netty(一) SpringBoot 整合長連線心跳機制NettySpring Boot
- 13年的MMO端遊如何連續三年逆勢增長?《天下》有長線運營之道
- 日本動漫《足球小將》手遊將在中國上線
- 長連線閘道器技術專題(六):石墨文件單機50萬WebSocket長連線架構實踐Web架構
- 服務端漫遊服務端
- Kubernetes 漫遊:理解 ConfigMap
- Juniper Research:5G漫遊連線量將從2023年的5300萬增加到2027年的5.26億
- 前端漫長的全棧之路前端全棧