apache / apache/brpc

Channel/Controller的析构与NamingServiceThread的析构解耦

Open
#2,143 8 comments 0 reactions 0 assignees View on GitHub
discussion
Dominant language
C++
Stars
17.6k
Forks
4.1k
Avg merge
2d 12h
Merged PRs (30d)
69

Description

**Describe the bug (描述bug)**

Channel/Controller共享LoadBalancerWithNaming,LoadBalancerWithNaming之间共享NamingServiceThread(来自g_nsthread_map)。

如下例子,当Channel和Controller是service回调函数的栈变量,且ns需要通过rpc获取节点信息时,Channel析构,会将LoadBalancerWithNaming析构,而如果此时NamingServiceThread的引用计数为1的话,NamingServiceThread会析构。NamingServiceThread的析构时需要等(Join)ns bthread退出。如果刚好LoadBalancerWithNaming的ns bthread在等rpc完成的话,则LoadBalancerWithNaming、Channel需要等到ns bthread的rpc完成才能完成析构,总体的表现就是EchoService的一次rpc请求要等ns bthread的rpc完成才能回包,耗时会上涨,甚至client端可能会超时。特别consul ns里的rpc是long polling,rpc耗时比较久,最长是1分钟。

```c++
class EchoServiceImpl : public EchoService {
public:
EchoServiceImpl() {}
virtual ~EchoServiceImpl() {}
virtual void Echo(google::protobuf::RpcController* cntl_base,
const EchoRequest* request,
EchoResponse* response,
google::protobuf::Closure* done) {
brpc::ClosureGuard done_guard(done);

brpc::Channel ch;
brpc::ChannelOptions options;
brpc::Controller cntl;
ch.Init("consul://xxx", "rr", options);
BackEchoService_Stub stub(&channel);
stub.Echo(...);

response->set_message(request->message());
}
};
```

**To Reproduce (复现方法)**

**Expected behavior (期望行为)**

希望Channel/Controller的析构与NamingServiceThread的析构解耦,不需要等LoadBalancerWithNaming的ns bthread在等rpc完成

**初步方案**:

1. g_nsthread_map持有一个NamingServiceThread的引用,这样LoadBalancerWithNaming析构的时候,就不会将NamingServiceThread析构了,Channel/Controller的析构就不用等NamingServiceThread析构了。
2. 起一个协程,定期加锁扫描g_nsthread_map,将引用计数为1的NamingServiceThread拷贝到锁外进行析构。还可以加一个idle的限制,超过idle且引用计数为1的NamingServiceThread才会被析构。

**Versions (各种版本)**
OS:
Compiler:
brpc:
protobuf:

**Additional context/screenshots (更多上下文/截图)**

Contributor guide

Open the contributing guide

Research direction

Trace the destruction paths for Channel, Controller, LoadBalancerWithNaming, NamingServiceThread, and g_nsthread_map, starting with how the shared thread's reference count and Join behavior interact. Compare the two proposed lifetime-management approaches and validate that temporary Channel/Controller objects no longer wait for a long-polling naming-service RPC during destruction.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
backend, distributed-systems
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.