Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
B
brpc
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
brpc
Commits
138d8f06
Commit
138d8f06
authored
Sep 14, 2017
by
gejun
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
minor fixes on docs
parent
7a3d9a29
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
15 additions
and
16 deletions
+15
-16
avalanche.md
docs/cn/avalanche.md
+2
-2
avalanche_effect.md
docs/cn/avalanche_effect.md
+2
-2
benchmark.md
docs/cn/benchmark.md
+6
-7
bthread.md
docs/cn/bthread.md
+2
-2
bvar.md
docs/cn/bvar.md
+1
-1
error_code.md
docs/cn/error_code.md
+1
-1
http_client.md
docs/cn/http_client.md
+1
-1
No files found.
docs/cn/avalanche.md
View file @
138d8f06
...
...
@@ -12,8 +12,8 @@
了解这些因素后可以更好的理解brpc中相关的设计。
1.
拥塞时A服务最大qps的跳变是因为线程个数是
**硬限**
,单个请求的处理时间很大程度上决定了最大qps。而brpc server端默认在bthread中处理请求,个数是软限,单个请求超时只是阻塞所在的bthread,并不会影响为新请求建立新的bthread。brpc也提供了完整的异步接口,让用户可以进一步提高io-bound服务的并发度,降低服务被打满的可能性。
2.
brpc中
[
重试
](
client.md#重试
)
默认只在连接出错时发起,避免了流量放大,这是比较有效率的重试方式。如果需要基于超时重试,可以设置
[
backup request
](
client.md#
backuprequest
)
,这类重试最多只有一次,放大程度降到了最低。brpc中的RPC超时是deadline,超过后RPC一定会结束,这让用户对服务的行为有更好的预判。在之前的一些实现中,RPC超时是单次超时
*
重试次数,在实践中容易误判。
3.
brpc server端的
[
max_concurrency选项
](
server.md#
id-创建和设置Server-
限制最大并发
)
控制了server的最大并发:当同时处理的请求数超过max_concurrency时,server会回复client错误,而不是继续积压。这一方面在服务开始的源头控制住了积压的请求数,尽量避免延生到用户缓冲或队列中,另一方面也让client尽快地去重试其他server,对集群来说是个更好的策略。
2.
brpc中
[
重试
](
client.md#重试
)
默认只在连接出错时发起,避免了流量放大,这是比较有效率的重试方式。如果需要基于超时重试,可以设置
[
backup request
](
client.md#
重试
)
,这类重试最多只有一次,放大程度降到了最低。brpc中的RPC超时是deadline,超过后RPC一定会结束,这让用户对服务的行为有更好的预判。在之前的一些实现中,RPC超时是单次超时
*
重试次数,在实践中容易误判。
3.
brpc server端的
[
max_concurrency选项
](
server.md#限制最大并发
)
控制了server的最大并发:当同时处理的请求数超过max_concurrency时,server会回复client错误,而不是继续积压。这一方面在服务开始的源头控制住了积压的请求数,尽量避免延生到用户缓冲或队列中,另一方面也让client尽快地去重试其他server,对集群来说是个更好的策略。
对于brpc的用户来说,要防止雪崩,主要注意两点:
...
...
docs/cn/avalanche_effect.md
View file @
138d8f06
...
...
@@ -12,8 +12,8 @@
了解这些因素后可以更好的理解brpc中相关的设计。
1.
拥塞时A服务最大qps的跳变是因为线程个数是
**硬限**
,单个请求的处理时间很大程度上决定了最大qps。而brpc server端默认在bthread中处理请求,个数是软限,单个请求超时只是阻塞所在的bthread,并不会影响为新请求建立新的bthread。brpc也提供了完整的异步接口,让用户可以进一步提高io-bound服务的并发度,降低服务被打满的可能性。
2.
brpc中
[
重试
](
client.md#重试
)
默认只在连接出错时发起,避免了流量放大,这是比较有效率的重试方式。如果需要基于超时重试,可以设置
[
backup request
](
client.md#
backuprequest
)
,这类重试最多只有一次,放大程度降到了最低。brpc中的RPC超时是deadline,超过后RPC一定会结束,这让用户对服务的行为有更好的预判。在之前的一些实现中,RPC超时是单次超时
*
重试次数,在实践中容易误判。
3.
brpc server端的
[
max_concurrency选项
](
server.md#
id-创建和设置Server-
限制最大并发
)
控制了server的最大并发:当同时处理的请求数超过max_concurrency时,server会回复client错误,而不是继续积压。这一方面在服务开始的源头控制住了积压的请求数,尽量避免延生到用户缓冲或队列中,另一方面也让client尽快地去重试其他server,对集群来说是个更好的策略。
2.
brpc中
[
重试
](
client.md#重试
)
默认只在连接出错时发起,避免了流量放大,这是比较有效率的重试方式。如果需要基于超时重试,可以设置
[
backup request
](
client.md#
重试
)
,这类重试最多只有一次,放大程度降到了最低。brpc中的RPC超时是deadline,超过后RPC一定会结束,这让用户对服务的行为有更好的预判。在之前的一些实现中,RPC超时是单次超时
*
重试次数,在实践中容易误判。
3.
brpc server端的
[
max_concurrency选项
](
server.md#限制最大并发
)
控制了server的最大并发:当同时处理的请求数超过max_concurrency时,server会回复client错误,而不是继续积压。这一方面在服务开始的源头控制住了积压的请求数,尽量避免延生到用户缓冲或队列中,另一方面也让client尽快地去重试其他server,对集群来说是个更好的策略。
对于brpc的用户来说,要防止雪崩,主要注意两点:
...
...
docs/cn/benchmark.md
View file @
138d8f06
...
...
@@ -99,16 +99,15 @@ server一样的[内置服务](builtin_service.md)。
![
img
](
../images/qps_vs_reqsize.png
)
以_mc结尾的曲线代表client和server保持多个连接(线程数个),在本测试中会有更好的表现。
**分析**
*
以_mc结尾的曲线代表client和server保持多个连接(线程数个),在本测试中会有更好的表现。
*
brpc:当请求包小于16KB时,单连接下的吞吐超过了多连接的ubrpc_mc和thrift_mc,随着请求包变大,内核对单个连接的写入速度成为瓶颈。而多连接下的brpc则一骑绝尘,达到了测试中最高的2.3GB/s。注意:虽然使用连接池的brpc在发送大包时吞吐更高,但也会耗费更多的CPU(UB和thrift也是这样)。下图中的单连接brpc已经可以提供800多兆的吞吐,足以打满万兆网卡,而使用的CPU可能只有多链接下的1/2
*
(写出过程是
[
wait-free的
](
io.md#发消息
)
),真实系统中请优先使用单链接。
*
brpc:当请求包小于16KB时,单连接下的吞吐超过了多连接的ubrpc_mc和thrift_mc,随着请求包变大,内核对单个连接的写入速度成为瓶颈。而多连接下的brpc则达到了测试中最高的2.3GB/s。注意:虽然使用连接池的brpc在发送大包时吞吐更高,但也会耗费更多的CPU(UB和thrift也是这样)。下图中的单连接brpc已经可以提供800多兆的吞吐,足以打满万兆网卡,而使用的CPU可能只有多链接下的1/2(写出过程是
[
wait-free的
](
io.md#发消息
)
),真实系统中请优先使用单链接。
*
thrift: 初期明显低于brpc,随着包变大超过了单连接的brpc。
*
UB:
*
和thrift类似的曲线,但平均要低4-5万QPS,在32K包时超过了单连接的brpc。整个过程中QPS几乎没变过。
*
UB:和thrift类似的曲线,但平均要低4-5万QPS,在32K包时超过了单连接的brpc。整个过程中QPS几乎没变过。
*
grpc: 初期几乎与UB平行,但低1万左右,超过8K开始下降。
*
hulu-pbrpc和sofa-pbrpc:
*
512字节前高于UB和grpc,但之后就急转直下,相继垫底。这个趋势是写不够并发的迹象。
*
hulu-pbrpc和sofa-pbrpc: 512字节前高于UB和grpc,但之后就急转直下,相继垫底。这个趋势是写不够并发的迹象。
## 同机单client→单server在不同线程数下的QPS(越高越好)
...
...
docs/cn/bthread.md
View file @
138d8f06
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的前身是
[
DP
](
http://wiki.babel.baidu.com/twiki/bin/view/Com/Ecom/DistributedProcess
)
中的fiber,一个N:1的合作式线程库,等价于event-loop库,但写的是同步代码。
# Goals
...
...
@@ -44,7 +44,7 @@ pthread worker在任何时间只会运行一个bthread,当前bthread挂起时
##### Q:若有大量的bthread调用了阻塞的pthread或系统函数,会影响RPC运行么?
会。比如有8个pthread worker,当有8个bthread都调用了系统usleep()后,处理网络收发的RPC代码就暂时无法运行了。只要阻塞时间不太长, 这一般
**没什么影响**
, 毕竟worker都用完了, 除了排队也没有什么好方法.
在brpc中用户可以选择调大worker数来缓解问题, 在server端可设置
[
ServerOptions.num_threads
](
server.md#
id-创建和设置Server-
worker线程数
)
或
[
-bthread_concurrency
](
http://brpc.baidu.com:8765/flags/bthread_concurrency
)
, 在client端可设置
[
-bthread_concurrency
](
http://brpc.baidu.com:8765/flags/bthread_concurrency
)
.
在brpc中用户可以选择调大worker数来缓解问题, 在server端可设置
[
ServerOptions.num_threads
](
server.md#worker线程数
)
或
[
-bthread_concurrency
](
http://brpc.baidu.com:8765/flags/bthread_concurrency
)
, 在client端可设置
[
-bthread_concurrency
](
http://brpc.baidu.com:8765/flags/bthread_concurrency
)
.
那有没有完全规避的方法呢?
...
...
docs/cn/bvar.md
View file @
138d8f06
# 1.什么是bvar?
[
public/bvar
](
https://github.com/brpc/brpc/blob/master/src/
)
是多线程环境下的计数器类库,方便记录和查看用户程序中的各类数值,它利用了thread local存储避免了cache bouncing,相比UbMonitor几乎不会给程序增加性能开销,也快于竞争频繁的原子操作。brpc集成了bvar,
[
/vars
](
http://brpc.baidu.com:8765/vars
)
可查看所有曝光的bvar,
[
/vars/VARNAME
](
http://brpc.baidu.com:8765/vars/rpc_socket_count
)
可查阅某个bvar,在rpc中的具体使用方法请查看
[
这里
](
vars.md
)
。brpc大量使用了bvar提供统计数值,当你需要在多线程环境中计数并展现时,应该第一时间想到bvar。但bvar不能代替所有的计数器,它的本质是把写时的竞争转移到了读:读得合并所有写过的线程中的数据,而不可避免地变慢了。当你读写都很频繁并得基于数值做一些逻辑判断时,你不应该用bvar。
[
bvar
](
https://github.com/brpc/brpc/blob/master/src/bvar
)
是多线程环境下的计数器类库,方便记录和查看用户程序中的各类数值,它利用了thread local存储避免了cache bouncing,相比UbMonitor几乎不会给程序增加性能开销,也快于竞争频繁的原子操作。brpc集成了bvar,
[
/vars
](
http://brpc.baidu.com:8765/vars
)
可查看所有曝光的bvar,
[
/vars/VARNAME
](
http://brpc.baidu.com:8765/vars/rpc_socket_count
)
可查阅某个bvar,在rpc中的具体使用方法请查看
[
这里
](
vars.md
)
。brpc大量使用了bvar提供统计数值,当你需要在多线程环境中计数并展现时,应该第一时间想到bvar。但bvar不能代替所有的计数器,它的本质是把写时的竞争转移到了读:读得合并所有写过的线程中的数据,而不可避免地变慢了。当你读写都很频繁并得基于数值做一些逻辑判断时,你不应该用bvar。
# 2.什么是cache bouncing?
...
...
docs/cn/error_code.md
View file @
138d8f06
...
...
@@ -15,7 +15,7 @@ server端Controller的SetFailed()常由用户在服务回调中调用。当处
brpc使用的所有ErrorCode都定义在
[
errno.proto
](
https://github.com/brpc/brpc/blob/master/src/brpc/errno.proto
)
中,
*SYS_*
开头的来自linux系统,与/usr/include/errno.h中定义的精确一致,定义在proto中是为了跨语言。其余的是brpc自有的。
[
berror(error_code)
](
https://github.com/brpc/brpc/blob/master/src/butil/errno.h
)
可获得error_code的描述,berror()可获得
[
system errno
](
http://www.cplusplus.com/reference/cerrno/errno/
)
的描述。
**ErrorText() != berror(
****
ErrorCode())**
,ErrorText()会包含更具体的错误信息。brpc默认包含berror,你可以直接使用。
[
berror(error_code)
](
https://github.com/brpc/brpc/blob/master/src/butil/errno.h
)
可获得error_code的描述,berror()可获得
[
system errno
](
http://www.cplusplus.com/reference/cerrno/errno/
)
的描述。
**ErrorText() != berror(ErrorCode())**
,ErrorText()会包含更具体的错误信息。brpc默认包含berror,你可以直接使用。
brpc中常见错误的打印内容列表如下:
...
...
docs/cn/http_client.md
View file @
138d8f06
...
...
@@ -83,7 +83,7 @@ URL的一般形式如下图:
确实,在简单使用场景下,这两者有所重复,但在复杂场景中,两者差别很大,比如:
-
访问挂在bns下的多个http server。此时Channel.Init传入的是bns节点名称,对uri()的赋值则是包含Host的完整URL(比如"www.foo.com/index.html?name=value"),BNS下所有的http server都会看到"Host:
[
www.foo.com
](
http://www.foo.com/
)
";uri()也可以是只包含路径的URL,比如"/index.html?name=value",框架会以目标server的ip和port为Host,地址为10.46.188.39:8989的http server将会看到"Host: 10.46.188.39:8989"。
-
访问挂在bns下的多个http server。此时Channel.Init传入的是bns节点名称,对uri()的赋值则是包含Host的完整URL(比如"www.foo.com/index.html?name=value"),BNS下所有的http server都会看到"Host:
www.foo.com
";uri()也可以是只包含路径的URL,比如"/index.html?name=value",框架会以目标server的ip和port为Host,地址为10.46.188.39:8989的http server将会看到"Host: 10.46.188.39:8989"。
-
通过http proxy访问目标server。此时Channel.Init传入的是proxy server的地址,但uri()填入的是目标server的URL。
# 常见设置
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment