搭建brpc开发环境
来源:     阅读:1
易浩激活码
发布于 2025-11-11 20:09
查看主页

#RPC#据说brpc性能强悍,功能完整。这里体验下。

搭建brpc开发环境

bRPC官网

本文结合介绍如何在Ubuntu下基于源码构建bRPC,并基于C++开发开发服务端和客户端应用。

系统环境

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 24.04.3 LTS
Release:        24.04
Codename:       noble

构建并测试

下载bRPC依赖的工具与第三方库

# M 更新软件源缓存
sudo apt update
# M 安装brpc依赖
sudo apt-get install -y git g++ make libssl-dev libgflags-dev libprotobuf-dev libprotoc-dev protobuf-compiler libleveldb-dev
# M 安装glog,否则一些例子程序跑不起来
sudo apt install -y libgoogle-glog-dev
# O 静态连接leveldb
sudo apt-get install -y libsnappy-dev
# O 启用profile
sudo apt-get install -y libgoogle-perftools-dev
# O 运行测试
sudo apt-get install -y cmake libgtest-dev && cd /usr/src/gtest && sudo cmake . && sudo make && sudo mv lib/libgtest* /usr/lib/ && cd -

下载源码,执行构建

# 可直接官网下载最新版本的源码包apache-brpc-1.14.1-src
wget https://dlcdn.apache.org/brpc/1.14.1/apache-brpc-1.14.1-src.tar.gz
tar zxvf apache-brpc-1.14.1-src.tar.gz
cd apache-brpc-1.14.1-src

cmake -B build -G Ninja -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DWITH_GLOG=ON -DWITH_GLOG=ON

cmake --build build/

# 安装到特定目录
mkdir ~/soft/brpc
cp -r buid/output/* ~/soft/brpc/

进入例子程序

cd example/echo_c++/
cmake -B build && cmake --build build

# 运行服务
./build/echo_server &
# 运行客户端
./build/echo_client

基于protobuf开发C++服务与客户端

编写IDL

$ cat test.proto
syntax = "proto3";

package Test;

option cc_generic_services = true;

service TestService {
    rpc runTest (TestRequest) returns (TestResponse);
}

message TestRequest {
    string message = 1;
    int32 msg_type = 2;      // 新增:消息类型(如1-磁盘,2-网络,3-CPU,4-内存)
}

message TestResponse {
    string response = 1;
    int32 status_code = 2;    // 新增:处理状态(如0-成功,1-失败)
}

实现服务端

$ cat src/server.cpp 
#include <iostream>
#include <brpc/server.h>
#include <butil/logging.h>  // BRPC 日志头文件
#include "test.pb.h"

class TestServiceImpl : public Test::TestService {
public:
    TestServiceImpl() = default;
    ~TestServiceImpl() = default;

    void runTest(google::protobuf::RpcController* cntl_base,
                const Test::TestRequest* request,
                Test::TestResponse* response,
                google::protobuf::Closure* done) override {
        
        brpc::ClosureGuard done_guard(done);
        brpc::Controller* cntl = static_cast<brpc::Controller*>(cntl_base);

        // 获取请求参数
        std::string message = request->message();
        int32_t msg_type = request->msg_type();

        // 根据消息类型处理业务逻辑
        std::string processed_message;
        int32_t status_code = 0;

        switch (msg_type) {
            case 1: // 磁盘测试
                processed_message = "[磁盘测试] 处理: " + message;
                break;
            case 2: // 网络测试
                processed_message = "[网络测试] 处理: " + message;
                break;
            case 3: // CPU测试
                processed_message = "[CPU测试] 处理: " + message;
                break;
            case 4: // 内存测试
                processed_message = "[内存测试] 处理: " + message;
                break;
            default:
                processed_message = "[未知类型] 处理: " + message;
                status_code = 1; // 失败状态
                break;
        }

        // 设置响应
        response->set_response(processed_message);
        response->set_status_code(status_code);

        // 打印日志 - 使用 BRPC 的 LOG 宏
        LOG(INFO) << "收到请求: message=" << message 
                  << ", msg_type=" << msg_type
                  << ", 返回: " << processed_message
                  << ", 状态: " << (status_code == 0 ? "成功" : "失败");
    }
};

int main(int argc, char* argv[]) {
    // 方案1: 完全移除日志初始化代码(使用默认配置)
    // BRPC 默认会输出到 stderr,对于开发测试一般足够
    
    // 方案2: 使用更简单的日志配置(如果的确   需要)
    // 设置日志级别为 WARNING 以减少输出
    // 初始化 glog 日志系统(必须在设置日志级别之前)
    google::InitGoogleLogging(argv[0]);  // 新增这一行
					 
    //if (google::SetCommandLineOption("log_level", "2").empty()) {
    // minloglevel=1 表明只输出 WARNING 及以上级别日志(0=INFO,1=WARNING,2=ERROR,3=FATAL),更符合你的需求。
    if (google::SetCommandLineOption("minloglevel", "0").empty()) {  // 1 对应 WARNING
        std::cerr << "设置日志级别失败" << std::endl;
    }

    // 创建服务器
    brpc::Server server;
    TestServiceImpl test_service;

    // 添加服务
    if (server.AddService(&test_service, brpc::SERVER_DOESNT_OWN_SERVICE) != 0) {
        std::cerr << "添加服务失败!" << std::endl;
        return -1;
    }

    // 服务器配置
    brpc::ServerOptions options;
    options.idle_timeout_sec = -1; // 连接永不超时
    options.num_threads = 4; // IO线程数

    // 启动服务器(端口8000)
    if (server.Start(8000, &options) != 0) {
        std::cerr << "启动服务器失败!" << std::endl;
        return -1;
    }

    std::cout << "测试服务器运行在端口 8000..." << std::endl;

    // 等待直到收到停止信号
    server.RunUntilAskedToQuit();

    return 0;
}

实现客户端

$ cat src/client.cpp 
#include <iostream>
#include <brpc/channel.h>
#include "test.pb.h"

int main(int argc, char* argv[]) {
    // 检查参数
    if (argc < 3) {
        std::cerr << "用法: " << argv[0] << " <消息> <类型[1-4]>" << std::endl;
        std::cerr << "类型说明: 1-磁盘, 2-网络, 3-CPU, 4-内存" << std::endl;
        return -1;
    }

    std::string message = argv[1];
    int32_t msg_type = std::stoi(argv[2]);

    // 初始化通道
    brpc::Channel channel;
    brpc::ChannelOptions options;
    options.protocol = "baidu_std";
    options.timeout_ms = 1000; // 1秒超时
    options.max_retry = 3;

    // 连接服务器
    if (channel.Init("127.0.0.1:8000", &options) != 0) {
        std::cerr << "连接服务器失败!" << std::endl;
        return -1;
    }

    // 创建存根
    Test::TestService_Stub stub(&channel);

    // 准备请求和响应
    Test::TestRequest request;
    Test::TestResponse response;
    brpc::Controller cntl;

    // 设置请求参数
    request.set_message(message);
    request.set_msg_type(msg_type);

    // 发起RPC调用
    stub.runTest(&cntl, &request, &response, nullptr);

    // 处理响应
    if (!cntl.Failed()) {
        std::cout << "响应: " << response.response() << std::endl;
        std::cout << "状态码: " << response.status_code() 
                  << " (" << (response.status_code() == 0 ? "成功" : "失败") << ")" << std::endl;
        std::cout << "延迟: " << cntl.latency_us() << "us" << std::endl;
    } else {
        std::cerr << "RPC调用失败: " << cntl.ErrorText() << std::endl;
        return -1;
    }

    return 0;
}

构建

$ cat CMakeLists.txt 
cmake_minimum_required(VERSION 3.10)
project(test_brpc_project C CXX)

# 设置C++标准
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# 固定依赖库路径(请根据您的实际安装路径修改)
set(BRPC_INCLUDE_DIR "/home/release/soft/brpc/include")
set(BRPC_LIB_DIR "/home/release/soft/brpc/lib")
set(PROTOBUF_INCLUDE_DIR "/usr/include")
set(PROTOBUF_LIB_DIR "/usr/lib")
set(LEVELDB_INCLUDE_DIR "/usr/include")
set(LEVELDB_LIB_DIR "/usr/lib")

# 包含目录
include_directories(
    ${PROJECT_SOURCE_DIR}
    ${BRPC_INCLUDE_DIR}
    ${PROTOBUF_INCLUDE_DIR}
    ${LEVELDB_INCLUDE_DIR}
)

# 链接目录
link_directories(
    ${BRPC_LIB_DIR}
    ${PROTOBUF_LIB_DIR}
    ${LEVELDB_LIB_DIR}
)

# 生成protobuf文件
include(FindThreads)  # 加载 CMake 内置模块,用于查找系统线程库(pthread)
include(FindProtobuf)  # 加载 CMake 内置模块,用于查找 Protobuf 库
protobuf_generate_cpp(PROTO_SRC PROTO_HEADER idl/test.proto)  # 编译 proto 文件:生成 C++ 源码(PROTO_SRC)和头文件(PROTO_HEADER)
include_directories(${CMAKE_CURRENT_BINARY_DIR})  # 将 proto 生成文件的目录(编译目录)添加到头文件搜索路径

# 服务器可执行文件
add_executable(test_server 
    src/server.cpp
     ${PROTO_SRC} ${PROTO_HEADER}
)

# 客户端可执行文件
add_executable(test_client 
    src/client.cpp
     ${PROTO_SRC} ${PROTO_HEADER}
)

# 链接库(固定库名称)
target_link_libraries(test_server 
    brpc
    gflags
    glog
    unwind
    protobuf
    leveldb
    ssl
    crypto
    pthread
    dl
    z
)

target_link_libraries(test_client 
    brpc
    gflags
    glog
    unwind
    protobuf
    leveldb
    ssl
    crypto
    pthread
    dl
    z
)

测试

$ ./build/test_server 
测试服务器运行在端口 8000...
$ ./build/test_client aa 1
响应: [磁盘测试] 处理: aa
状态码: 0 (成功)
延迟: 2272us

# 停止服务
killall test_server

压力测试

rpc_press --proto=../idl/test.proto  --method=Test.TestService.runTest --input config.json

rpc_press --proto=./test.proto  --method=Test.TestService.runTest --input message.json --server 172.21.165.94:9000 --thread_num=30 --qps=5000

查看config.json

{
	"message":"12345678901234561234567890123456123456789012345612345678901234561234567890123456123456789012345612345678901234561234567890123456123456789012345612345678901234561234567890123456123456789012345612345678901234561234567890123456123456789012345612345678901234561234567890123456123456789012345612345678901234561234567890123456123456789012345612345678901234561234567890123456123456789012345612345678901234561234567890123456123456789012345612345678901234561234567890123456123456789012345612345678901234561234567890123456", 
	"msg_type":2
}

异常解决

protobuf库版本匹配与自身冲突

最好基于源码和自定义路径安装protobuf库,否则一旦有问题,清理起来极为麻烦。

参考资料

  1. bRPC官网 : https://brpc.apache.org/zh/docs/getting_started/
  2. 下载brpc : https://brpc.apache.org/zh/docs/downloadbrpc/
  3. https://github.com/apache/brpc/blob/master/docs/cn/server.md
免责声明:本文为用户发表,不代表网站立场,仅供参考,不构成引导等用途。 系统环境
相关推荐
以渐进迭代的方式优化小程序登录
记 Windows 10 编译 tensorflow
SQL Server DBA日常运维语句
写给准备参与秋找的童鞋的一点建议(1)
09. 迪米特法则
首页
搜索
订单
购物车
我的