apache / brpc

brpc is an Industrial-grade RPC framework using C++ Language, which is often used in high performance system such as Search, Storage, Machine learning, Advertisement, Recommendation etc. "brpc" means "better RPC".
https://brpc.apache.org
Apache License 2.0
16.56k stars 3.98k forks source link

服务端的线程池和在服务中启动的线程会共享线程池么 #2803

Closed utopia9527 closed 3 weeks ago

utopia9527 commented 3 weeks ago

想确认一下服务端brpc 自身启动的线程池会不会和其它方式启动的线程共享线程池

为什么提出问题: 比如服务端启动了10个线程(bthread_work_count=10), 然后在服务中有异步线程启动任务,任务中发起rpc调用,这时候的线程阻塞,会不会影响bthread_work_count。 比如后发起来了4个rpc调用,但是bthread_worker_usage是观测不到的,实际上影响了bthread_work_count

chenBright commented 3 weeks ago

想确认一下服务端brpc 自身启动的线程池会不会和其它方式启动的线程共享线程池

不会

utopia9527 commented 3 weeks ago

想确认一下服务端brpc 自身启动的线程池会不会和其它方式启动的线程共享线程池

不会

通过打印bthread 缺确认了确实不会。

当前有个这样的问题: 其它线程进行系统调用(比如: std::system("ls")),会导致服务端对下游发起rpc 调用时产生阻塞 这个疑惑可以帮忙解答下么。 演示demo 如下。 访问url=/test Service接口,服务接口Service里面会进行下游rpc 调用。 rpc 调用的耗时毛刺点和后台线程运行时间保持一致

namespace example {
class EchoServiceImpl : public EchoService {
 public:
  EchoServiceImpl() {};
  virtual ~EchoServiceImpl() {};

  void Service(google::protobuf::RpcController *cntl_base,
               const EchoRequest *request, EchoResponse *response,
               google::protobuf::Closure *done) {
    brpc::ClosureGuard done_guard(done);
    brpc::Controller *cntl = static_cast<brpc::Controller *>(cntl_base);
    if (cntl) {
      auto start = std::chrono::high_resolution_clock::now();
      std::string url = "www.baidu.com/index.html";

      brpc::Channel channel;
      brpc::ChannelOptions options;

      options.protocol = FLAGS_protocol;
      options.timeout_ms = FLAGS_timeout_ms /*milliseconds*/;
      options.max_retry = FLAGS_max_retry;

      if (channel.Init(url.c_str(), FLAGS_load_balancer.c_str(), &options) !=
          0) {
        LOG(ERROR) << "Fail to initialize channel";
        return;
      }

      brpc::Controller cntl;
      cntl.http_request().uri() = url;
      channel.CallMethod(NULL, &cntl, NULL, NULL, NULL /*done*/);
      if (cntl.Failed()) {
        std::cerr << cntl.ErrorText() << std::endl;
        return;
      }
      // If -http_verbose is on, brpc already prints the response to stderr.
      // if (!brpc::FLAGS_http_verbose) {
      //   std::cout << cntl.response_attachment() << std::endl;
      // }
      auto end = std::chrono::high_resolution_clock::now();
      std::chrono::duration<double, std::milli> elapsed = end - start;
      LOG(INFO) << "耗时: " << elapsed.count() << " 毫秒" << std::endl;
    }
  };
};
}  // namespace example

void StartMockTask() {
  while (true) {
    std::cout << "sleep 5s" << std::endl;
    sleep(5);
    std::system("ls -al");
  }
};

int main(int argc, char *argv[]) {
  std::thread mock_thread = std::thread(StartMockTask);
  mock_thread.detach();

  gflags::ParseCommandLineFlags(&argc, &argv, true);
  brpc::Server server;
  example::EchoServiceImpl echo_service_impl;
  if (server.AddService(&echo_service_impl, brpc::SERVER_DOESNT_OWN_SERVICE,
                        "/test/ =>Service") != 0) {
    LOG(ERROR) << "Fail to add service.";
    return -1;
  }
  // Start the server.
  brpc::ServerOptions options;
  options.idle_timeout_sec = FLAGS_idle_timeout_s;

  if (server.Start(FLAGS_port, &options) != 0) {
    LOG(ERROR) << "Fail to start EchoServer";
    return -1;
  }
  server.RunUntilAskedToQuit();

  return 0;
}
chenBright commented 3 weeks ago

std::system好像会阻塞进程吧,可以试一下butil::read_command_output

utopia9527 commented 3 weeks ago

std::system好像会阻塞进程吧,可以试一下butil::read_command_output

"阻塞进程", 一言惊醒梦中人! 感谢~~