brpc jiangrujiebaidu com RPC Request Response Client Server
brpc外功修炼宝典 jiangrujie@baidu. com 蒋如杰
什么是RPC Request Response Client • • Server RPC(Remote Procedure Call),它把网络交互类比为“client访 问server上的函数” 由于RPC会等待response的特性,在client端能轻松获知server是 否成功处理,保证上层逻辑正确可靠
非自描述结构 struct Hello. Request { char name[16]; int age; int weight; char message[256]; int salary; }; message:你谁啊,再烦我报 警了 玉帝 女神
半自描述格式——protobuf message Hello. Request { required string name = 1; optional int 32 age = 2; optional int 32 salary = 3; optional string message = 4; } message Hello. Response { required message = 1; } req. set_name(“玉帝”); req. set_age(26); … res. set_message(“么么哒 ”); 玉帝 女神
Protobuf简介 message [message name] { [field rule] [field type] [field name] = [tag]; } field rule : = required | optional | repeated filed type : = int 32 | int 64 | uint 32 | uint 64 | double | bool | string | bytes • • • tag不能重复,一旦定了也不能随意修改 field type可以是已定义过的message 可以通过import xx. proto来引用其他文件
Protobuf简介 // hello. proto // hello. pb. h message Hello. Request { optional string name = 1; repeated int 32 id = 2; } class Hello. Request { public: const string& name() const; bool has_name() const; void set_message(const string&); size_t id_size() const; int id(int index) const; void add_id(int id); }
Protobuf简介 // hello. proto option cc_generic_services = true; service Hello. Service { rpc Hello(Hello. Request) returns (Hello. Response); } // hello. pb. h class Hello. Service { public: virtual void Hello(Controller*, Hello. Request*, Hello. Response*, Closure*) = 0; } class Hello. Service_Stub: public Hello. Service { public: Hello. Service_Stub(Channel*); void Hello(Controller*, Hello. Request*, Hello. Response*, Closure*);
RPC要素——协议 // hello. proto message Hello. Request { … } message Hello. Response { … } service Hello. Service { rpc Hello(Hello. Request) returns (Hello. Response); } 如果直接发送整个Hello. Request到对端,那么: • • • 如何辨识请求大小? 如果增加一个Goodbye方法,如何区分? 请求/返回需要压缩,如果告知对方?
brpc —— 框架 Server Client Selective Channel Parallel Channel Mechanism Partition Channel Policy Channel Naming Load Balancer BNS List RPC Method Implementation RR Hash Built-in Services Format Protocol Compression Authentication Socket http nshead snappy gzip Giano SSL
baidu-rpc 72绝技 组合访问 • Parallel. Channel:广播访问 • Selective. Channel:Channel级联 • Partition. Channel:分库访问 • Dynamic. Partition. Channel:动态分库 高级功能: • backup request • RPC cancellation • 数据压缩、加密 • 内置服务 • RPC dump & replay
Client端实战 // #include <brpc/channel. h> brpc: : Channel channel; brpc: : Channel. Options options; options. timeout_ms = 100; channel. Init(“ 10. 92. 34. 89: 8888”, &options); Hello. Service_Stub stub(&channel); Hello. Request request; Hello. Response response; brpc: : Controller controller; stub. Hello(&controller, &request, &response, NULL); if (controller. Failed()) { LOG(INFO) << controller. Error. Text(); } else { LOG(INFO) << response. message(); }
Client端实战 channel. Init(“file: //server. list”, bns: //BNS-TAG list: //ip: port, ip: port “rr”, &options); random c_murmurhash void hello_callback(Controller, Hello. Response*); stub. Hello(&controller, &request, &response, google: : protobuf: : New. Callback( hello_callback, &controller, &response)); brpc: : Call. Id cid = controller->call_id(); stub. Hello(…); brpc: : Join(cid);
Server端实战 // #include “hello. pb. h”; Hello. Service. Impl: public Hello. Service { public: void Hello(Controller*, Hello. Request* request, Hello. Response* response, Closure* done) { brpc: : Closure. Guard done_guard(done); response->set_message(request->message()); done->Run(); } }
Server端实战 // #include <brpc/server. h> brpc: : Server server; brpc: : Server. Options options; options. num_threads = 30; Hello. Service. Impl hservice; server. Add. Service(&hservice, baidu: : rpc: : SERVER_DOESNT_OWN_SERVICE); server. Start(8888, &options); server. Join(); server. Run. Until. Asked. To. Quit();
HTTP实战——Client端 brpc: : Channel channel; brpc: : Channel. Options options; options. protocol = “http”; channel. Init(“www. baidu. com”, &options); brpc: : Controller controller; controller. http_request(). uri() = “www. baidu. com/index. html”; channel. Call. Method(NULL, &controller, NULL, NULL); if (controller. Failed()) { LOG(INFO) << controller. Error. Text(); } else { LOG(INFO) << response. message(); }
HTTP实战——Client端 { “name”: “玉帝”, “age”: 26 } message Http. Request { optional string name = 1; optional int 32 age = 2; } brpc: : Controller controller; controller. http_request(). Set. Header(“x-bce-request-id”, “ 123456789 -abcdef”); controller. http_request(). set_method( brpc: : HTTP_METHOD_POST); Http. Request request; Http. Response response; channel. Call. Method(NULL, &controller, &request, &response, NULL); controller. http_response(). status_code(); controller. http_response(). Get. Header(“log-id”);
HTTP实战——Server端 message Http. Request { … } message Http. Response { … } service Http. Service { rpc Call(Http. Request) returns (Http. Response); } // 访问URI为 /Http. Service/Call server. Add. Service(&hservice, brpc: : SERVER_DOESNT_OWN_SERVICE); class Http. Service. Impl: public Http. Service { public: void Call(…) { controller->http_request(). uri(). Get. Query(“device_id”); controller->http_response(). set_content_type(“text/plain”); … } };
HTTP实战——Server端 service Http. Service { rpc default_method(Http. Request) returns (Http. Response); } // 访问URI为 /Http. Service/* server. Add. Service(&hservice, brpc: : SERVER_DOESNT_OWN_SERVICE); class Http. Service. Impl: public Http. Service { public: void Call(…) { controller->http_request(). unresolved_path(); … } };
HTTP实战——Server端 service Http. Service { rpc create(Create. Request) returns (Create. Response); rpc delete(Delete. Request) returns (Delete. Response); rpc show(Show. Request) returns (Show. Service); } server. Add. Service(&hservice, brpc: : SERVER_DOESNT_OWN_SERVICE, “/v 1/network/create => create” “/v 1/network/*/delete => delete” “/v 1/network/show/* => show”); … void show(…) { int id = atoi(controller->http_request(). unresolved_path(). c_str()); … }
brpc常用链接 • • • 总体介绍:https: //github. com/brpc Client:https: //github. com/brpc/blob/master/docs/cn/client. md Server:https: //github. com/brpc/blob/master/docs/cn/server. md 内置服务: https: //github. com/brpc/blob/master/docs/cn/builtin_service. md protobuf:https: //developers. google. com/protocol-buffers/ 对于具体接口用法,多看头文件,svn目录下也有example https: //github. com/brpc/tree/master/example
- Slides: 34