昨天看到一段brpc中的压测代码rpc_press, 看着不错。整理一下。
发压工具的难点不是发送请求,而是要注意下面的2点:git
足够的qps
,好比上万qps控制发送合理的qps
,好比控制为5qps,不能够大量发压rpc_press 采用多线程发送。
对于上万qps,多线程来分摊
,每一个线程发送qps控制在必定范围内。github
这是难点,线程如何控制发送qps。
看下面公式,1000000us(1s)须要发送200请求, 那50请求须要多少时间了?这就是brpc控制压力的核心原理。
多线程
核心原理
: rpc_press中根据目前发送请求的速度与应该的速度进行比较,来判断是继续发压,仍是usleep工具
这里贴一点rpc_press工做线程git代码(引用自brpc)fetch
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); } } } }