brpc简介
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了brpc简介相关的知识,希望对你有一定的参考价值。
参考技术A brpc是百度开源的c++ rpc项目,同grpc和thrift相似是一种rpc实现。目前看更像grpc,都使用了protobuf实现序列化,但是似乎只有c++支持,这不不适合多语言交互了。粗略看,针对c++做了很好的性能方面的优化,性能表现应该会好一些。
编译相关在: https://github.com/apache/incubator-brpc/blob/master/docs/cn/getting_started.md
基本介绍在: https://github.com/apache/incubator-brpc/blob/master/docs/cn/brpc_intro.pptx
内部机制介绍在: https://github.com/apache/incubator-brpc/blob/master/docs/en/brpc_internal.pptx
这个rpc的实现文档确实介绍的不错,我还没有仔细看,后续可能会一点点分开写一下。
更新:
如果你使用brpc注意栈空间的大小,bthread申请的栈是固定大小的,注意不要越界了。 或者你根据使用情况自己配置这一项。
百度brpc 发压工具rpc_press解析
1. 背景
昨天看到一段brpc中的压测代码rpc_press, 看着不错。整理一下。
发压工具的难点不是发送请求,而是要注意下面的2点:
- 保证能发出
足够的qps
,比如上万qps 控制发送合理的qps
,比如控制为5qps,不可以大量发压
2. brpc 中的是关键实现
2.1 如何确保发送足够qps
rpc_press 采用多线程发送。
对于上万qps,多线程来分摊
,每个线程发送qps控制在一定范围内。
2.2 如何控制合理qps
这是难点,线程如何控制发送qps。
看下面公式,1000000us(1s)需要发送200请求, 那50请求需要多少时间了?这就是brpc控制压力的核心原理。
核心原理
: rpc_press中根据目前发送请求的速度与应该的速度进行比较,来判断是继续发压,还是usleep
2.3 rpc_press 代码
这里贴一点rpc_press工作线程git代码(引用自brpc)
void RpcPress::sync_client() {
double req_rate = _options.test_req_rate / _options.test_thread_num;
//max make up time is 5 s
if (_msgs.empty()) {
LOG(ERROR) << "nothing to send!";
return;
}
const int thread_index = g_thread_count.fetch_add(1, butil::memory_order_relaxed);
int msg_index = thread_index;
std::deque<int64_t> timeq;
size_t MAX_QUEUE_SIZE = (size_t)req_rate;
if (MAX_QUEUE_SIZE < 100) {
MAX_QUEUE_SIZE = 100;
} else if (MAX_QUEUE_SIZE > 2000) {
MAX_QUEUE_SIZE = 2000;
}
timeq.push_back(butil::gettimeofday_us());
while (!_stop) {
brpc::Controller* cntl = new brpc::Controller;
msg_index = (msg_index + _options.test_thread_num) % _msgs.size();
Message* request = _msgs[msg_index];
Message* response = _pbrpc_client->get_output_message();
const int64_t start_time = butil::gettimeofday_us();
google::protobuf::Closure* done = brpc::NewCallback<
RpcPress,
RpcPress*,
brpc::Controller*,
Message*,
Message*, int64_t>
(this, &RpcPress::handle_response, cntl, request, response, start_time);
const brpc::CallId cid1 = cntl->call_id();
_pbrpc_client->call_method(cntl, request, response, done);
_sent_count << 1;
if (_options.test_req_rate <= 0) {
brpc::Join(cid1);
} else {
int64_t end_time = butil::gettimeofday_us();
int64_t expected_elp = 0;
int64_t actual_elp = 0;
timeq.push_back(end_time);
if (timeq.size() > MAX_QUEUE_SIZE) {
actual_elp = end_time - timeq.front();
timeq.pop_front();
expected_elp = (int64_t)(1000000 * timeq.size() / req_rate);
} else {
actual_elp = end_time - timeq.front();
expected_elp = (int64_t)(1000000 * (timeq.size() - 1) / req_rate);
}
if (actual_elp < expected_elp) {
usleep(expected_elp - actual_elp);
}
}
}
}
3. 参考
以上是关于brpc简介的主要内容,如果未能解决你的问题,请参考以下文章