1.brpc介绍
brpc
是用
c++
语言编写的工业级
RPC
框架,常用于搜索、存储、机器学习、广告、推
荐等高性能系统。
可以使用它搭建能在一个端口
支持多协议的服务
,
或访问各种服务。
2.brpc安装
安装依赖
apt-get install -y git g++ make
libssl-dev libprotobuf-dev libprotoc-dev protobuf-compiler
libleveldb-dev
安装 brpc
git clone https://github.com/apache/brpc.git
cd brpc/
mkdir build && cd build
cmake -DCMAKE_INSTALL_PREFIX=/usr .. && cmake --build . -j6
make && sudo make install
3.类与接口介绍
1.日志输出类与接口
包含头文件:
#include <butil/logging.h>
日志输出这里,本质上我们其实用不着
brpc
的日志输出,因此在这里主要介绍如何关
闭日志输出。
namespace logging {
enum LoggingDestination {
LOG_TO_NONE = 0
};
struct BUTIL_EXPORT LoggingSettings {
LoggingSettings();
LoggingDestination logging_dest;
};
bool InitLogging(const LoggingSettings& settings);
}
2.protobuf 类与接口
namespace google {
namespace protobuf {
class PROTOBUF_EXPORT Closure {
public:
Closure() {}
virtual ~Closure();
virtual void Run() = 0;
};
inline Closure* NewCallback(void (*function)());
class PROTOBUF_EXPORT RpcController {
bool Failed();
std::string ErrorText() ;
}
}
}
3.服务端类与接口
namespace brpc {
struct ServerOptions {
//无数据传输,则指定时间后关闭连接
int idle_timeout_sec; // Default: -1 (disabled)
int num_threads; // Default: #cpu-cores
//....
}
enum ServiceOwnership {
//添加服务失败时,服务器将负责删除服务对象
SERVER_OWNS_SERVICE,
//添加服务失败时,服务器也不会删除服务对象
SERVER_DOESNT_OWN_SERVICE
};
class Server {
int AddService(google::protobuf::Service* service,
ServiceOwnership ownership);
int Start(int port, const ServerOptions* opt);
int Stop(int closewait_ms/*not used anymore*/);
int Join();
//休眠直到 ctrl+c 按下,或者 stop 和 join 服务器
void RunUntilAskedToQuit();
}
class ClosureGuard {
explicit ClosureGuard(google::protobuf::Closure* done);
~ClosureGuard() { if (_done) _done->Run(); }
}
class HttpHeader {
void set_content_type(const std::string& type)
const std::string* GetHeader(const std::string& key)
void SetHeader(const std::string& key,
const std::string& value);
const URI& uri() const { return _uri; }
HttpMethod method() const { return _method; }
void set_method(const HttpMethod method)
int status_code()
void set_status_code(int status_code);
}
class Controller : public google::protobuf::RpcController {
void set_timeout_ms(int64_t timeout_ms);
void set_max_retry(int max_retry);
google::protobuf::Message* response();
HttpHeader& http_response();
HttpHeader& http_request();
bool Failed();
std::string ErrorText();
using AfterRpcRespFnType = std::function<
void(Controller* cntl,
const google::protobuf::Message* req,
const google::protobuf::Message* res)>;
void set_after_rpc_resp_fn(AfterRpcRespFnType&& fn)
}
4.客户端类与接口:
namespace brpc {
struct ChannelOptions {
//请求连接超时时间
int32_t connect_timeout_ms;// Default: 200 (milliseconds)
//rpc 请求超时时间
int32_t timeout_ms;// Default: 500 (milliseconds)
//最大重试次数
int max_retry;// Default: 3
//序列化协议类型 options.protocol = "baidu_std";
AdaptiveProtocolType protocol;
//....
}
class Channel : public ChannelBase {
//初始化接口,成功返回 0;
int Init(const char* server_addr_and_port,
const ChannelOptions* options);
4.brpc使用
同步调用
同步调用是指客户端会阻塞收到
server
端的响应或发生错误。
下面我们以
Echo
(输出
hello world
)方法为例
,
来讲解基础的同步
RPC
请求是如何实
现的。
定义一个proto文件
syntax="proto3";
package example;
/*cc_generic_services: 这是一个特定的编译器选项,用于控制C++代码生成的行为。
当设置为true时,它会告诉Protocol Buffers编译器生成通用的服务接口实现。
这对于需要编写与Protocol Buffers服务交互的客户端代码非常有用
因为它提供了一种标准的方式来调用服务,而不需要关心服务的具体实现。*/
option cc_generic_services = true;
message EchoRequest
{
string message = 1;
}
message EchoResponse
{
string message = 1;
}
service EchoService {
rpc Echo(EchoRequest) returns (EchoResponse);
};
利用protoc命令
protoc --cpp_out ./ main.proto
生成以后就可以查看main.pb.h
就会发现proto已经自动生成了对应的rpc函数以供调用。
样例编写
server.cpp
#include<brpc/server.h>
#include<butil/logging.h>
#include"main.pb.h"
using namespace std;
//1.继承EchoService创建子类,并实现rpc调用的业务功能
class EchoServiceImpl : public example::EchoService
{
public:
void Echo(google::protobuf::RpcController* controller,
const example::EchoRequest* request,
example::EchoResponse* response,
google::protobuf::Closure* done) override
{
cout<<"服务端收到信息:"<<request->message()<<endl;
response->set_message("Hello " + request->message());
done->Run();
}
};
int main()
{
logging::LoggingSettings setting;
setting.logging_dest = logging::LoggingDestination::LOG_TO_NONE;
logging::InitLogging(setting);
//构造服务器对象
brpc::Server server;
//向服务器注册服务
EchoServiceImpl echo_service;
//SERVER_DOESNT_OWN_SERVICE表示服务对象由用户管理,不归服务器所有,即使任务失败也不删除服务对象
server.AddService(&echo_service,brpc::SERVER_DOESNT_OWN_SERVICE);
brpc::ServerOptions options;
options.idle_timeout_sec = -1;//不设置空闲超时
options.num_threads = 1;//io线程数量
int ret=server.Start(8080, &options);
if(ret<0)
{
cerr<<"启动服务器失败"<<endl;
return -1;
}
server.RunUntilAskedToQuit();
return 0;
}
client.cpp
#include<brpc/channel.h>
#include<butil/logging.h>
#include"main.pb.h"
using namespace std;
void callback(google::protobuf::RpcController* controller,
const example::EchoResponse *response)
{
// 输出异步收到的响应消息
cout<<"异步收到响应:"<<response->message()<<endl;
delete(response);
delete(controller);
}
int main(int argc,char *argv[])
{
logging::LoggingSettings setting;
setting.logging_dest = logging::LoggingDestination::LOG_TO_NONE;
logging::InitLogging(setting);
brpc::ChannelOptions options;
options.connect_timeout_ms = -1;//连接等待超时时间,-1表示无限等待
options.timeout_ms = -1; //rpc请求等待超时时间,-1表示无限等待
options.max_retry = 3; //最大重试次数
options.protocol="baidu_std";
//构建rpc信道
brpc::Channel channel;
int ret=channel.Init("127.0.0.1:8080",&options);
if(ret<0)
{
cerr<<"init channel failed"<<endl;
return -1;
}
//构建EchoServiceImpl_Stub对象,用于发起rpc请求
example::EchoService_Stub stub(&channel);
//rpc调用
example::EchoRequest *request =new example::EchoRequest;
request->set_message("hello world");
example::EchoResponse *response =new example::EchoResponse;
brpc::Controller *controller =new brpc::Controller;
//auto closure = google::protobuf::NewCallback(callback);
//stub.Echo(controller,request,response,closure);//异步调用
stub.Echo(controller,request,response,nullptr);
if(controller->Failed())
{
cerr<<"rpc call failed"<<endl;
return -1;
}
cout<<"同步收到响应:"<<response->message()<<endl;
delete request;
delete response;
//channel.Close();
return 0;
}
makefile
all:server client
server:server.cpp main.pb.cc
g++ server.cpp main.pb.cc -o server -std=c++17 -lbrpc -lleveldb -lgflags -lssl -lcrypto -lprotobuf
client:client.cpp main.pb.cc
g++ client.cpp main.pb.cc -o client -std=c++17 -lbrpc -lleveldb -lgflags -lssl -lcrypto -lprotobuf
@PHONY:clean
clean:
rm -f client server
运行结果
至此,大家就安装和简单使用brpc了,感谢观看!