背景
Channel 是 brpc 中的重要概念,抽象了 client 和 server 之间的通信细节,在每次发起一个 rpc call 时,需要一个 channel 实体进行通信。本文将尝试对 brpc Channel::Init 的过程进行梳理。
用法
从下面官方的例子可以看出,用户在使用 Channel 时需要进行初始化,可以在这个过程中对默认参数进行覆盖。
1 | brpc::ChannelOptions options; // 包含了默认值 |
目前 brpc 提供了 3 中签名的 Channel::Init 接口,签名如下。
1 | // src/brpc/channel.h |
实现细节
- 实现细节大同小异,区别是第一个不判断当前 channel 的管理方式,默认使用单链接,第一个不检查 PROTOCOL。
- 主要逻辑在
InitSingle中实现,其主要逻辑如下:- 调用
GlobalInitializeOrDie进行全局初始化,主要工作包括注册信号处理器、注册协议处理器 - 调用
InitChannelOptions为ChannelOptions设置默认值,如果用户设置了值,则会覆盖默认值- 检查
connection_type,优先级为SINGLE > POOLED > SHORT - 查找
protocol index,如果 protocol 不支持则失败 - Normalize connection group,即进行一次 stirng trim
- 检查
- 检查端口有效性
- 计算 Channel Signature,即对 ChannelOptions 计算 hash 值
- 如果 Channel 使用 SSL,调用
CreateSocketSSLContext,计算SSLContext - 调用
SocketMapKey创建连接的唯一标识 - 调用
SocketMapInsert根据ChannelOptions创建 Channel 并放到ChannelMap中- 最终依赖
SocketMap::Insert,其逻辑如下- 根据
channel key从 map 中查询连接,如果能找到则直接返回,说明其他线程可能已经创建好了 channel - 调用
SocketCreator::CreateSocket新建 socket - 根据 socket 创建
SocketUniquePtr保证 socket 总能访问到 - 将 socket 放到 map 中
- 如果需要在 bvar 中记录 socket_map,则更新 bvar,由
FLAGS_show_socketmap_in_vars控制
- 根据
- 最终依赖
- 调用