Commit 31949b48 authored by gejun's avatar gejun

More translations in client.md

parent bddb5186
[bthread](https://github.com/brpc/brpc/tree/master/src/bthread)是brpc使用的M:N线程库,目的是在提高程序的并发度的同时,降低编码难度,并在核数日益增多的CPU上提供更好的scalability和cache locality。”M:N“是指M个bthread会映射至N个pthread,一般M远大于N。由于linux当下的pthread实现([NPTL](http://en.wikipedia.org/wiki/Native_POSIX_Thread_Library))是1:1的,M个bthread也相当于映射至N个[LWP](http://en.wikipedia.org/wiki/Light-weight_process)。bthread的前身是[DP](http://wiki.babel.baidu.com/twiki/bin/view/Com/Ecom/DistributedProcess)中的fiber,一个N:1的合作式线程库,等价于event-loop库,但写的是同步代码。
[bthread](https://github.com/brpc/brpc/tree/master/src/bthread)是brpc使用的M:N线程库,目的是在提高程序的并发度的同时,降低编码难度,并在核数日益增多的CPU上提供更好的scalability和cache locality。”M:N“是指M个bthread会映射至N个pthread,一般M远大于N。由于linux当下的pthread实现([NPTL](http://en.wikipedia.org/wiki/Native_POSIX_Thread_Library))是1:1的,M个bthread也相当于映射至N个[LWP](http://en.wikipedia.org/wiki/Light-weight_process)。bthread的前身是Distributed Process(DP)中的fiber,一个N:1的合作式线程库,等价于event-loop库,但写的是同步代码。
# Goals
......
# 背景
云平台部把使用ubrpc的模块改造为使用brpc。由于使用了mcpack2pb的转换功能,这个模块既能被老的ubrpc client访问,也可以通过protobuf类的协议访问(标准协议,sofa-pbrpc协议等等)。
云平台部把使用ubrpc的模块改造为使用brpc。由于使用了mcpack2pb的转换功能,这个模块既能被老的ubrpc client访问,也可以通过protobuf类的协议访问(baidu_std,sofa_pbrpc等)。
原有使用43台机器(对ubrpc也有富余),brpc使用3台机器即可(此时访问redis的io达到瓶颈)。当前流量4w qps,支持流量增长,考虑跨机房冗余,避免redis和vip瓶颈,brpc实际使用8台机器提供服务。
......
This diff is collapsed.
......@@ -2,9 +2,9 @@
brpc server在同端口支持所有的协议,大部分时候这对部署和运维更加方便。由于不同协议的格式大相径庭,严格地来说,同端口很难无二义地支持所有协议。出于解耦和可扩展性的考虑,也不太可能集中式地构建一个针对所有协议的分类器。我们的做法就是把协议归三类后逐个尝试:
- 第一类协议:标记或特殊字符在最前面,比如[标准协议](http://gollum.baidu.com/ProtobufRPC)[hulu协议](http://wiki.babel.baidu.com/twiki/bin/view/Com/Main/Hulu_rpc_protocols)的前4个字符分别分别是PRPC和HULU,解析代码只需要检查前4个字节就可以知道协议是否匹配,最先尝试这类协议。这些协议在同一个连接上也可以共存。
- 第一类协议:标记或特殊字符在最前面,比如[baidu_std](baidu_std.md),hulu_pbrpc的前4个字符分别分别是PRPC和HULU,解析代码只需要检查前4个字节就可以知道协议是否匹配,最先尝试这类协议。这些协议在同一个连接上也可以共存。
- 第二类协议:有较为复杂的语法,没有固定的协议标记或特殊字符,可能在解析一段输入后才能判断是否匹配,目前此类协议只有http。
- 第三类协议:协议标记或特殊字符在中间,比如[nshead](http://wiki.babel.baidu.com/twiki/bin/view/Com/Main/LibNshead)的magic_num在第25-28字节。由于之前的字段均为二进制,难以判断正确性,在没有读取完28字节前,我们无法判定消息是不是nshead格式的,所以处理起来很麻烦,若其解析排在http之前,那么<=28字节的http消息便可能无法被解析,因为程序以为是“还未完整的nshead消息”。
- 第三类协议:协议标记或特殊字符在中间,比如nshead的magic_num在第25-28字节。由于之前的字段均为二进制,难以判断正确性,在没有读取完28字节前,我们无法判定消息是不是nshead格式的,所以处理起来很麻烦,若其解析排在http之前,那么<=28字节的http消息便可能无法被解析,因为程序以为是“还未完整的nshead消息”。
考虑到大多数链接上只会有一种协议,我们会记录前一次的协议选择结果,下次首先尝试。对于长连接,这几乎把甄别协议的开销降到了0;虽然短连接每次都得运行这段逻辑,但由于短连接的瓶颈也往往不在于此,这套方法仍旧是足够快的。在未来如果有大量的协议加入,我们可能得考虑一些更复杂的启发式的区分方法。
......
......@@ -181,7 +181,7 @@ idl是mcpack/compack的前端,用户只要在idl文件中描述schema,就可
- Call ParseRequestFromIOBuf() to convert the body after nshead header to pb request, then call the pb method.
- When user calls server's done to end the RPC, SerializeResponseToIOBuf() is called to convert pb response to binary data that will be appended after nshead header and sent back to client.
这样做的好处是,这个服务还可以被其他使用protobuf的协议访问,比如标准协议,hulu协议,sofa协议等等。NsheadPbServiceAdaptor的主要接口如下。完整的example在[这里](https://github.com/brpc/brpc/tree/master/example/nshead_pb_extension_c++/)
这样做的好处是,这个服务还可以被其他使用protobuf的协议访问,比如baidu_std,hulu_pbrpc,sofa_pbrpc协议等等。NsheadPbServiceAdaptor的主要接口如下。完整的example在[这里](https://github.com/brpc/brpc/tree/master/example/nshead_pb_extension_c++/)
```c++
class NsheadPbServiceAdaptor : public NsheadService {
......
rpc_press无需写代码就压测各种rpc server,目前支持的协议有:
- 标准协议
- hulu-pbrpc协议
- sofa-pbrpc协议
- public_pbrpc协议(老版pbrpc协议)
- nova-pbrpc协议
- baidu_std
- hulu-pbrpc
- sofa-pbrpc
- public_pbrpc
- nova_pbrpc
# 获取工具
......@@ -18,7 +18,7 @@ rpc_press会动态加载proto文件,无需把proto文件编译为c++源文件
rpc_press的所有的选项都来自命令行参数,而不是配置文件.
如下的命令向下游0.0.0.0:8002用标准协议重复发送两个pb请求,分别转自'{"message":"hello"}和'{"message":"world"},持续压力直到按ctrl-c,qps为100。
如下的命令向下游0.0.0.0:8002用baidu_std重复发送两个pb请求,分别转自'{"message":"hello"}和'{"message":"world"},持续压力直到按ctrl-c,qps为100。
json也可以写在文件中,假如./input.json包含了上述两个请求,-input=./input.json也是可以的。
......@@ -35,7 +35,7 @@ json也可以写在文件中,假如./input.json包含了上述两个请求,-
- -lb_policy: 指定负载均衡算法,默认为空,可选项为: rr random la c_murmurhash c_md5,具体见[负载均衡](client.md#负载均衡)
- -timeout_ms: 设定超时,单位是毫秒(milliseconds),默认是1000(1秒)
- -max_retry: 最大的重试次数,默认是3, 一般无需修改. brpc的重试行为具体请见[这里](client.md#重试).
- -protocol: 连接server使用的协议,可选项见[协议](client.md#协议), 默认是baidu_std(标准协议)
- -protocol: 连接server使用的协议,可选项见[协议](client.md#协议), 默认是baidu_std
- -connection_type: 连接方式,可选项为: single pooled short,具体见[连接方式](client.md#连接方式)。默认会根据协议自动选择,无需指定.
- -output: 如果不为空,response会转为json并写入这个文件,默认为空。
- -duration:大于0时表示发送这么多秒的压力后退出,否则一直发直到按ctrl-c或进程被杀死。默认是0(一直发送)。
......@@ -44,15 +44,15 @@ json也可以写在文件中,假如./input.json包含了上述两个请求,-
常用的参数组合:
- 向下游0.0.0.0:8002、用标准协议重复发送./input.json中的所有请求,持续压力直到按ctrl-c,qps为100。
- 向下游0.0.0.0:8002、用baidu_std重复发送./input.json中的所有请求,持续压力直到按ctrl-c,qps为100。
./rpc_press -proto=echo.proto -method=example.EchoService.Echo -server=0.0.0.0:8002 -input=./input.json -qps=100
- 以round-robin分流算法向bns://node-name代表的所有下游机器、用标准协议重复发送两个pb请求,持续压力直到按ctrl-c,qps为100。
- 以round-robin分流算法向bns://node-name代表的所有下游机器、用baidu_std重复发送两个pb请求,持续压力直到按ctrl-c,qps为100。
./rpc_press -proto=echo.proto -method=example.EchoService.Echo -server=bns://node-name -lb_policy=rr -input='{"message":"hello"} {"message":"world"}' -qps=100
- 向下游0.0.0.0:8002、用hulu协议重复发送两个pb请求,持续压力直到按ctrl-c,qps为100。
./rpc_press -proto=echo.proto -method=example.EchoService.Echo -server=0.0.0.0:8002 -protocol=hulu_pbrpc -input='{"message":"hello"} {"message":"world"}' -qps=100
- 向下游0.0.0.0:8002、用标准协议重复发送两个pb请求,持续最大压力直到按ctrl-c。
- 向下游0.0.0.0:8002、用baidu_std重复发送两个pb请求,持续最大压力直到按ctrl-c。
./rpc_press -proto=echo.proto -method=example.EchoService.Echo -server=0.0.0.0:8002 -input='{"message":"hello"} {"message":"world"}' -qps=0
- 向下游0.0.0.0:8002、用标准协议重复发送两个pb请求,持续最大压力10秒钟。
- 向下游0.0.0.0:8002、用baidu_std重复发送两个pb请求,持续最大压力10秒钟。
./rpc_press -proto=echo.proto -method=example.EchoService.Echo -server=0.0.0.0:8002 -input='{"message":"hello"} {"message":"world"}' -qps=0 -duration=10
- echo.proto中import了另一个目录下的proto文件
./rpc_press -proto=echo.proto -inc=<another-dir-with-the-imported-proto> -method=example.EchoService.Echo -server=0.0.0.0:8002 -input='{"message":"hello"} {"message":"world"}' -qps=0 -duration=10
......
......@@ -29,7 +29,7 @@ brpc通过一个[bvar::Collector](https://github.com/brpc/brpc/blob/master/src/b
目录下的文件数不超过rpc_dump_max_files,超过后最老的文件被删除从而给新文件腾出位置。
文件是二进制格式,格式与标准协议的二进制格式类似,每个请求的binary layout如下:
文件是二进制格式,格式与baidu_std协议的二进制格式类似,每个请求的binary layout如下:
```
"PRPC" (4 bytes magic string)
......
......@@ -296,15 +296,15 @@ server.AddService(service, svc_opt);
server端会自动尝试其支持的协议,无需用户指定。`cntl->protocol()`可获得当前协议。server能从一个listen端口建立不同协议的连接,不需要为不同的协议使用不同的listen端口,一个连接上也可以传输多种协议的数据包(但一般不会这么做),支持的协议有:
- 标准协议,显示为"baidu_std",默认启用。
- 百度标准协议,显示为"baidu_std",默认启用。
- hulu协议,显示为"hulu",默认启动。
- hulu-pbrpc的协议,显示为"hulu_pbrpc",默认启动。
- http协议,显示为”http“,默认启用。
- sofa协议,显示为”sofa“,默认启用。
- sofa-pbrpc的协议,显示为”sofa_pbrpc“, 默认启用。
- nova协议,显示为”nova“ (r32206前显示为"nshead_server"),默认不启用,开启方式:
- nova协议,显示为”nova_pbrpc“, 默认不启用,开启方式:
```c++
#include <brpc/policy/nova_pbrpc_protocol.h>
......@@ -414,7 +414,7 @@ set_response_compress_type()设置response的压缩方式,默认不压缩。
## 附件
标准协议和hulu协议支持附件,这段数据由用户自定义,不经过protobuf的序列化。站在server的角度,设置在Controller::response_attachment()的附件会被client端收到,request_attachment()则包含了client端送来的附件。附件不受压缩选项影响。
baidu_std和hulu_pbrpc协议支持附件,这段数据由用户自定义,不经过protobuf的序列化。站在server的角度,设置在Controller::response_attachment()的附件会被client端收到,request_attachment()则包含了client端送来的附件。附件不受压缩选项影响。
在http协议中,附件对应[message body](http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html),比如要返回的数据就设置在response_attachment()中。
......@@ -445,7 +445,7 @@ public:
};
```
当server收到连接上的第一个包时,会尝试解析出其中的身份信息部分(如标准协议里的auth字段、HTTP协议里的Authorization头),然后附带client地址信息一起调用`VerifyCredential`。
当server收到连接上的第一个包时,会尝试解析出其中的身份信息部分(如baidu_std里的auth字段、HTTP协议里的Authorization头),然后附带client地址信息一起调用`VerifyCredential`。
若返回0,表示验证成功,用户可以把验证后的信息填入`AuthContext`,后续可通过`controller->auth_context()获取,用户不需要关心controller->auth_context()的分配和释放`
......
......@@ -21,7 +21,7 @@ Streaming RPC保证:
# 建立Stream
目前Stream都由Client端建立。Client先在本地创建一个Stream,再通过一次RPC(必须使用标准协议)与指定的Service建立一个Stream,如果Service在收到请求之后选择接受这个Stream, 那在response返回Client后Stream就会建立成功。过程中的任何错误都把RPC标记为失败,同时也意味着Stream创建失败。用linux下建立连接的过程打比方,Client先创建[socket](http://linux.die.net/man/7/socket)(创建Stream),再调用[connect](http://linux.die.net/man/2/connect)尝试与远端建立连接(通过RPC建立Stream),远端[accept](http://linux.die.net/man/2/accept)后连接就建立了(service接受后创建成功)。
目前Stream都由Client端建立。Client先在本地创建一个Stream,再通过一次RPC(必须使用baidu_std协议)与指定的Service建立一个Stream,如果Service在收到请求之后选择接受这个Stream, 那在response返回Client后Stream就会建立成功。过程中的任何错误都把RPC标记为失败,同时也意味着Stream创建失败。用linux下建立连接的过程打比方,Client先创建[socket](http://linux.die.net/man/7/socket)(创建Stream),再调用[connect](http://linux.die.net/man/2/connect)尝试与远端建立连接(通过RPC建立Stream),远端[accept](http://linux.die.net/man/2/accept)后连接就建立了(service接受后创建成功)。
> 如果Client尝试向不支持Streaming RPC的老Server建立Stream,将总是失败。
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment