brpc/docs/cn/bthread_id.md
2022-12-14 20:13:26 +08:00

37 lines
2.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

bthread_id是一个特殊的同步结构它可以互斥RPC过程中的不同环节也可以O(1)时间内找到RPC上下文(即Controller)。注意这里我们谈论的是bthread_id_t不是bthread_tbthread的tid这个名字起的确实不太好容易混淆。
具体来说bthread_id解决的问题有
- 在发送RPC过程中response回来了处理response的代码和发送代码产生竞争。
- 设置timer后很快触发了超时处理代码和发送代码产生竞争。
- 重试产生的多个response同时回来产生的竞争。
- 通过correlation_id在O(1)时间内找到对应的RPC上下文而无需建立从correlation_id到RPC上下文的全局哈希表。
- 取消RPC。
上文提到的bug在其他rpc框架中广泛存在下面我们来看下brpc是如何通过bthread_id解决这些问题的。
bthread_id包括两部分一个是用户可见的64位id另一个是对应的不可见的bthread::Id结构体。用户接口都是操作id的。从id映射到结构体的方式和brpc中的[其他结构](memory_management.md)类似32位是内存池的位移32位是version。前者O(1)时间定位后者防止ABA问题。
bthread_id的接口不太简洁有不少API
- create
- lock
- unlock
- unlock_and_destroy
- join
- error
这么多接口是为了满足不同的使用流程。
- 发送request的流程bthread_id_create -> bthread_id_lock -> ... register timer and send RPC ... -> bthread_id_unlock
- 接收response的流程bthread_id_lock -> ..process response -> bthread_id_unlock_and_destroy
- 异常处理流程timeout/socket fail -> bthread_id_error -> 执行on_error回调(这里会加锁),分两种情况
- 请求重试/backup request 重新register timer and send RPC -> bthread_id_unlock
- 无法重试最终失败bthread_id_unlock_and_destroy
- 同步等待RPC结束bthread_id_join
为了减少等待bthread_id做了一些优化的机制
- error发生的时候如果bthread_id已经被锁住会把error信息放到一个pending queue中bthread_id_error函数立即返回。当bthread_id_unlock的时候如果pending queue里面有任务就取出来执行。
- RPC结束的时候如果存在用户回调先执行一个bthread_id_about_to_destroy让正在等待的bthread_id_lock操作立即失败再执行用户回调这个可能耗时较长不可控最后再执行bthread_id_unlock_and_destroy