首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

多 Tomcat 節點集群間方法調用通知方案:從 HTTP 回調到分布式協調

     編輯:程式設計疑難解答

業務場景

集群部署多個 Tomcat 節點,負載均衡隨機分發請求。用戶在節點 A 執行方法 a() 後,需通知節點 B、C 等也執行 a()(可攜帶參數),實現集群內狀態同步或觸發業務邏輯。

方案對比與選型指南

方案適用場景實現複雜度一致性保障性能/擴展性
HTTP 互相回調節點固定、數據量小、業務允許最終一致性低弱(無重試/無序)節點增多時 O(N²) 連接,難擴展
共享緩存
(Redis/Memcached)
高頻讀寫、需高性能、可接受最終一致性中最終一致性極佳,單點 Redis 可支撐大規模集群
消息隊列
(Kafka/RocketMQ/RabbitMQ)
高可靠、解耦、異步處理、需保證投遞中高最終一致性 (可配合事務消息)極佳,天然支持擴展與削峰填谷
分布式協調
(ZooKeeper/Etcd/Consul)
強一致性要求、配置同步、領導者選舉、分布式鎖高強一致性 (CP)寫性能受限,適合元數據/協調而非高頻業務數據
Session 復制 / Sticky Session僅需 Session 共享,非業務方法廣播低 (配置級)最終一致性僅限 Session 範圍,不適用於任意方法調用

推薦架構:消息隊列 (以 RocketMQ 為例)

1. 生產者 (節點 A 執行 a() 後)

@Autowired RocketMQTemplate mqTemplate;

public void executeAndNotify(MethodParams params) {
    // 1. 執行本地業務
    doLocalBusiness(params);
    
    // 2. 發送同步消息到 Topic
    SyncMessage msg = new SyncMessage("METHOD_A_SYNC", params);
    mqTemplate.syncSend("cluster-sync-topic", msg); // 或異步 send
}

2. 消費者 (所有節點包括 A 部署相同監聽器)

@Component
@RocketMQMessageListener(topic = "cluster-sync-topic", consumerGroup = "cluster-sync-group")
public class MethodSyncListener implements RocketMQListener<SyncMessage> {
    
    @Override
    public void onMessage(SyncMessage msg) {
        if ("METHOD_A_SYNC".equals(msg.getType())) {
            // 幂等性檢查(防重複消費)
            if (alreadyProcessed(msg.getId())) return;
            
            // 執行同步邏輯
            doLocalBusiness(msg.getParams());
            
            markProcessed(msg.getId());
        }
    }
}

3. 關鍵設計點

  • 幂等性: 消息可能重複投遞,**必須**基於消息 ID (UUID) + Redis Set/資料庫唯一索引去重。
  • 參數序列化: 使用 JSON (Jackson/Gson) 或 Protobuf,確保跨語言/版本兼容。
  • 異步非阻塞: 生產者用 asyncSend,消費者線程池隔離,不影響主業務響應。
  • 順序性: 若嚴格要求順序,指定 MessageQueue 選擇器 (如按用戶 ID hash),同一用戶操作進同一隊列。

輕量級替代:Redis Pub/Sub (適合簡單廣播)

// 發布
redisTemplate.convertAndSend("channel:method-a", params);

// 訂閱 (每個節點啟動時註冊)
@Bean
MessageListenerAdapter listenerAdapter(RedisMessageListener listener) {
    return new MessageListenerAdapter(listener, "onMessage");
}

@Component
public class RedisMessageListener {
    public void onMessage(Message message, byte[] pattern) {
        String body = new String(message.getBody());
        MethodParams params = JSON.parseObject(body, MethodParams.class);
        doLocalBusiness(params);
    }
}

缺點: 無持久化、無 ACK 機制、消費者離線會丟消息,**不適合核心業務同步**。

總結建議

  • 核心業務、高可靠要求: **RocketMQ / Kafka** 事務消息 + 幂等消費,標準分布式架構解法。
  • 配置/元數據同步、需強一致: **ZooKeeper / Etcd** Watch 機制。
  • 簡單通知、可容忍丟失: **Redis Pub/Sub** 或 **HTTP 回調** (需重試機制)。
  • 切忌: 硬編碼節點 IP 列表、直接 HTTP 互調無重試無幂等、同步阻塞調用導致雪崩。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved