brpc的介绍与安装
brpc 是用 c++语言编写的工业级 RPC 框架,常用于搜索、存储、机器学习、广告、推荐等高性能系统。你可以使用它:
1.搭建能在一个端口支持多协议的服务, 或访问各种服务
1.1 restful http/https, h2/gRPC。使用 brpc 的 http 实现比 libcurl 方便多了。从其他语言通过 HTTP/h2+json 访问基于 protobuf 的协议
1.2 redis 和 memcached, 线程安全,比官方 client 更方便
1.3 rtmp/flv/hls, 可用于搭建流媒体服务
1.4 支持 thrift , 线程安全,比官方 client 更方便
1.5 各种百度内使用的协议: baidu_std, streaming_rpc, hulu_pbrpc, sofa_pbrpc, nova_pbrpc, public_pbrpc, ubrpc 和使用 nshead 的各种协议
1.5基于工业级的 RAFT 算法实现搭建高可用分布式系统,已在 braft 开源
2.Server 能同步或异步处理请求
3.Client 支持同步、异步、半同步,或使用组合 channels 简化复杂的分库或并发访问。
4.通过 http 界面调试服务, 使用 cpu, heap, contention profilers
5.获得更好的延时和吞吐
6.把你组织中使用的协议快速地加入 brpc,或定制各类组件, 包括命名服务 (dns, zk, etcd), 负载均衡 (rr, random, consistent hashing)
安装
先安装依赖
sudo 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
类与接口介绍
日志输出:
#include <butil/logging.h>
logging::InitLogging(...)
protobuf相关类:
RpcController:上下文管理类--目前主要用于判断rpc请求是否OK
Closure:客户端-主要用于设置异步处理回调,服务端-通过Run()接口宣告请求处理完毕
服务端相关类:
Server类:服务器类
ServerOptions:服务器参数配置
ClosureGuard:Closure对象的智能管理类
客户端相关类:
Channel;客户端与服务器网络通信信道类
ChannelOptions:信道配置类
日志输出类与接口
包含头文件: #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);
}
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();
}
}
}
服务端类与接口
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)
};
}
客户端类与接口:
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);
};
}
使用案例
Rpc调用实现样例:
服务端:
1.创建rpc服务子类继承pb中的EchoService服务类,并实现内部的业务接口逻辑
2.创建rpc服务类,搭建服务器
3.向服务器类中添加rpc子服务对象-告诉服务器收到什么请求用哪个接口处理
4.启动服务器
客户端:
1.创建网络通信信道
2.实例化pb中的EchoService_Stub类对象
3.发起rpc请求,获取响应进行处理
同步调用
同步调用是指客户端会阻塞收到 server 端的响应或发生错误。
下面我们以 Echo(输出 hello world)方法为例, 来讲解基础的同步 RPC 请求是如何实现的。
main.proto
syntax = "proto3";
package example;
option cc_generic_services = true;
// 定义 Echo 方法请求参数结构
message EchoRequest {
string massage = 1;
}
// 定义 Echo 方法响应参数结构
message EchoResponse {
string massage = 1;
}
// 定义 RPC 远端方法
service EchoService {
rpc Echo(EchoRequest) returns(EchoResponse)
}
运行main.proto文件
proto --cpp_out=./ main.proto
server.cc
#include <brpc/server.h>
#include <butil/logging.h>
#include "main.pb.h"
// 继承于EchoService创建一个子类,并实现rpc调用的业务功能
class EchoServiceImpl : public example::EchoService
{
public:
EchoServiceImpl() {
}
~EchoServiceImpl

最低0.47元/天 解锁文章

1397

被折叠的 条评论
为什么被折叠?



