UB_PLUS 概述
UB 原生最大消息 64KB,UB_PLUS 通过"反向拉取"机制扩展到 10MB。这是一个多步握手协议。
状态机
sequenceDiagram
核心实现:umq_ub_read()
// umq_ub.c:1254-1310
int umq_ub_read(uint64_t umqh_tp, umq_buf_t *rx_buf, umq_ub_imm_t imm) {
// 1. 解析 immediate 中的元数据
uint16_t buf_num = imm.ub_plus.msg_num; // 批处理 buf 数量
uint16_t msg_id = imm.ub_plus.msg_id; // 消息 ID(用于去重)
// 2. 解析接收缓冲区头部的 umq_imm_head
umq_imm_head_t *umq_imm_head = (umq_imm_head_t *)rx_buf->buf_data;
ub_ref_sge_t *ref_sge = (ub_ref_sge_t *)(umq_imm_head + 1);
// 3. 预分配本地接收缓冲区
umq_buf_t *ctx_buf = umq_ub_read_ctx_create(queue, umq_imm_head, buf_num, msg_id);
// └─ 根据 mem_interval 计算总大小
// └─ umq_buf_alloc(total_size, 1, ...) 从 huge pool 分配
// 4. 逐块发起 READ
for (uint32_t i = 0; i < buf_num; i++) {
src_sge[i].addr = ref_sge[i].addr; // 远端地址
src_sge[i].tseg = imported_tseg_list[ref_sge[i].mempool_id];
dst_sge[i].addr = tmp_buf->buf_data; // 本地地址
dst_sge[i].tseg = tseg_list[tmp_buf->mempool_id];
urma_post_jetty_send_wr(queue->jetty, &urma_wr, &bad_wr); // READ
}
// 5. 完成后发送 REVERSE_PULL_MEM_DONE 确认
// └─ umq_ub_write_imm(imm = REVERSE_PULL_MEM_DONE)
}
缓冲区分配策略
UB_PLUS 使用独立的 huge qbuf pool,支持 8MB 级缓冲区:
flowchart TB
N0[buf_size < umq_buf_size_middle(]
N1[request_size, ...]
N2[buf_size]
N3[request_size, ..., type]
N4[umq_init_cfg_t *cfg]
N5[i = 0; i < HUGE_QBUF_POOL_SIZE_TYPE_MAX; i++]
N6[i]
N7[&pool_cfg]
Immediate 子类型
// umq_ub_imm_data.h: UB_PLUS 子类型
typedef enum umq_ub_plus_imm_sub_type {
IMM_TYPE_UB_PLUS_DEFAULT, // 默认子类型
IMM_TYPE_REVERSE_PULL_MEM, // 请求反向拉取
IMM_TYPE_REVERSE_PULL_MEM_FREE, // 释放反向拉取内存
IMM_TYPE_REVERSE_PULL_MEM_DONE, // 反向拉取完成确认
IMM_TYPE_UB_PLUS_MAX
} umq_ub_plus_imm_sub_type_t;