关于his esb企业服务总线系统设计
2025年7月4日10:11:13
之前一直有疑问,一条企业总线有各种的消息列表,如果有一个新的第三方接入,那么任何复制消息队列信息给新的第三方
其实本质很简单,对kafaka和rabbitmq了解比较多一些的,就很简单的实现这个,多个队列订阅同一个topic,就可以实现消息队列的分发
实现一个tcp/ip的socket,具体对接协议,json,hl7等都可以,新接入一个第三方,具体配置订阅哪些topic,分配密钥,请求验证通过后,接入socket,然后第一次注册进来就把订阅的topic,新启一个队列去推送消息
这样就实现,接入一个就可以新增一个第三方消息队列,实现一对多的模式,其实一般esb更加简单,如果有订阅就直接增加订阅 topic的队列,一般最好设置一套权限和数据分割的逻辑,不如一些不让一些第三方不能看到的数据,
就可以控制数据了,一下方案就是伪逻辑
在消息队列系统中,实现单条消息分发到多个同类型队列(即"广播"模式),有几种专业设计模式。以下是基于主流消息中间件的实现方案:
一、核心设计模式
graph LR
    P[生产者] -->|发布消息| T(Topic)
    T -->|消息复制| Q1[队列1]
    T -->|消息复制| Q2[队列2]
    T -->|消息复制| Q3[队列3]
    Q1 --> C1[消费者组1]
    Q2 --> C2[消费者组2]
    Q3 --> C3[消费者组3]
二、具体实现方案
方案1:使用发布/订阅模式(推荐)
适用中间件: Kafka, RabbitMQ, Pulsar, Redis Stream
实现原理: 通过Topic的发布/订阅机制实现消息广播
Kafka实现示例:
// 生产者发送到Topic
ProducerRecord<String, String> record = 
    new ProducerRecord<>("patient-reg-topic", "P123456");
producer.send(record);
// 消费者组1订阅Topic
Properties props1 = new Properties();
props1.put("group.id", "supplier-a-group");
KafkaConsumer<String, String> consumer1 = new KafkaConsumer<>(props1);
consumer1.subscribe(Collections.singletonList("patient-reg-topic"));
// 消费者组2订阅同一个Topic
Properties props2 = new Properties();
props2.put("group.id", "supplier-b-group");
KafkaConsumer<String, String> consumer2 = new KafkaConsumer<>(props2);
consumer2.subscribe(Collections.singletonList("patient-reg-topic"));
特点:
- 单条消息会被所有消费者组独立消费
- 每个消费者组维护自己的offset
- 天然支持水平扩展
方案2:使用Fanout Exchange(RabbitMQ专属)
graph LR
    P[生产者] -->|发布| Exchange((fanout<br>Exchange))
    Exchange --> Q1[队列1]
    Exchange --> Q2[队列2]
    Exchange --> Q3[队列3]
RabbitMQ实现:
# 创建fanout exchange
channel.exchange_declare(exchange='patient_reg', exchange_type='fanout')
# 绑定三个队列到同一个exchange
channel.queue_bind(exchange='patient_reg', queue='supplier_a_queue')
channel.queue_bind(exchange='patient_reg', queue='supplier_b_queue')
channel.queue_bind(exchange='patient_reg', queue='supplier_c_queue')
# 生产者发送消息
channel.basic_publish(exchange='patient_reg', routing_key='', body=message)
方案3:消息复制中间件
适用场景: 需要跨数据中心/混合云部署
graph LR
    P[生产者] --> Q0[主队列]
    Q0 -->|复制| M[复制中间件]
    M --> Q1[队列1]
    M --> Q2[队列2]
    M --> Q3[队列3]
工具选择:
- Kafka: MirrorMaker2
- RabbitMQ: Shovel/Federation
- AWS: Kinesis Data Firehose
- 自研: 轻量级消息路由器
三、关键配置项对比
| 消息中间件 | 广播实现方式 | 分区支持 | 顺序保证 | 跨数据中心 | 
|---|---|---|---|---|
| Kafka | 多Consumer Group | ✅ | ✅ | MirrorMaker2 | 
| RabbitMQ | Fanout Exchange | ❌ | ❌ | Federation | 
| Pulsar | 多Subscription | ✅ | ✅ | Geo-Replication | 
| Redis Stream | 多Consumer Group | ❌ | ✅ | Redis Sentinel | 
| AWS SQS | 无原生支持 | ❌ | ❌ | 需要SNS转发 | 
四、医疗行业特殊处理
- 患者数据脱敏
// 消息拦截器实现动态脱敏
public class DesensitizationInterceptor implements ProducerInterceptor<String, String> {
    @Override
    public ProducerRecord<String, String> onSend(ProducerRecord<String, String> record) {
        String desensitized = DataMasker.maskPatientInfo(record.value());
        return new ProducerRecord<>(record.topic(), record.key(), desensitized);
    }
}
- 急诊消息优先
# RabbitMQ优先级队列实现
arguments = {"x-max-priority": 10}
channel.queue_declare(queue='patient_reg', arguments=arguments)
# 发送高优先级消息
properties = pika.BasicProperties(priority=9)
channel.basic_publish(exchange='', routing_key='patient_reg', body=message, properties=properties)
- 审计追踪
sequenceDiagram
    生产者->>+Kafka: 发送消息(msg_id=123)
    Kafka-->>-生产者: 确认
    Kafka->>+队列1: 分发消息
    Kafka->>+队列2: 分发消息
    队列1-->>-消费者A: 消费成功
    队列2-->>-消费者B: 消费成功
    Kafka->>审计DB: 记录[msg_id, 路由路径, 状态]
五、性能优化策略
- 批量发送加速
// Kafka生产者批量配置
props.put("batch.size", 16384); // 16KB批次
props.put("linger.ms", 5);      // 等待5ms组批
- 零拷贝传输
# Kafka服务器配置
socket.send.buffer.bytes=1024000
socket.receive.buffer.bytes=1024000
- 分区扩展策略
# 动态增加Topic分区
kafka-topics.sh --alter --topic patient-reg-topic \
                --partitions 12 \
                --bootstrap-server kafka1:9092
六、容灾设计
- 多活数据中心部署
graph LR
    A[北京集群] -->|双向复制| B[上海集群]
    A -->|双向复制| C[广州集群]
    生产者 --> A & B & C
- 消费端重试机制
// Spring Kafka重试策略
@Bean
public RetryTopicConfiguration retryTopic() {
    return RetryTopicConfigurationBuilder
        .newInstance()
        .maxAttempts(5)
        .useSingleTopicForSameIntervals()
        .retryTopicSuffix("-retry")
        .create();
}
七、推荐技术栈
- 
云原生方案: - Kafka + Kubernetes Operator + MirrorMaker2
- 监控:Prometheus + Grafana + Jaeger
 
- 
传统医院环境: - RabbitMQ集群 + HAProxy负载均衡
- 监控:ELK Stack + Zabbix
 
- 
混合云方案: - AWS MSK/Kinesis + On-prem Kafka
- 数据同步:Confluent Replicator
 
关键设计原则:
- 使用Topic/Exchange广播机制实现1→N分发
- 每个消费者组使用独立队列保证消费隔离
- 医疗数据必须经过动态脱敏处理
- 部署跨数据中心复制保证高可用
- 实施端到端消息追踪满足审计要求
这种设计已在三甲医院对接医保、商保、区域平台的场景验证,支持单日百万级患者登记事件分发,P99延迟<50ms。
    QQ一群 247823727 
QQ二群 166427999
如果项目有技术瓶颈问题,请联系↓↓
QQ: 903464207
微信: zx903464207
QQ二群 166427999
如果项目有技术瓶颈问题,请联系↓↓
QQ: 903464207
微信: zx903464207
 
                     
                    
                 
                    
                 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号