diff --git a/README.md b/README.md
index 7a365ce0e3..60dedcfb57 100644
--- a/README.md
+++ b/README.md
@@ -15,7 +15,7 @@ Let's see how the issues are solved.
* RPC needs serialization which is done by [protobuf](https://github.com/google/protobuf) pretty well. Users fill requests in format of protobuf::Message, do RPC, and fetch results from responses in protobuf::Message. protobuf has good forward and backward compatibility for users to change fields and build services incrementally. For http services, [json](http://www.json.org/) is used for serialization extensively.
* Establishment and re-using of connections are transparent to users, but users can make choices, say [different connection types](docs/cn/client.md#连接方式): short, pooled, single.
-* Machines are discovered by Naming Service, which can be implemented by [DNS](https://en.wikipedia.org/wiki/Domain_Name_System), [ZooKeeper](https://zookeeper.apache.org/) or [etcd](https://github.com/coreos/etcd). Inside Baidu, we use BNS (Baidu Naming Service). baidu-rpc provides ["list://" and "file://" as well](docs/cn/client.md#名字服务). Users specify load balancing algorithms to choose one machine for each request from all machines, including: round-robin, randomized, [consistent-hashing](docs/cn/consistent_hashing.md)(murmurhash3 or md5) and [locality-aware](docs/cn/lalb.md).
+* Machines are discovered by Naming Service, which can be implemented by [DNS](https://en.wikipedia.org/wiki/Domain_Name_System), [ZooKeeper](https://zookeeper.apache.org/) or [etcd](https://github.com/coreos/etcd). Inside Baidu, we use BNS (Baidu Naming Service). brpc provides ["list://" and "file://" as well](docs/cn/client.md#名字服务). Users specify load balancing algorithms to choose one machine for each request from all machines, including: round-robin, randomized, [consistent-hashing](docs/cn/consistent_hashing.md)(murmurhash3 or md5) and [locality-aware](docs/cn/lalb.md).
* RPC retries when the connection is broken. When server does not respond within given time, client fails with timeout error.
# Where can I use RPC?
@@ -30,15 +30,15 @@ Common doubts on RPC:
- I'm sending streaming data, which can't be processed by RPC. Actually many protocols in RPC can handle streaming data, including [ProgressiveReader in http](docs/cn/http_client.md#持续下载), streams in h2, [streaming rpc](docs/cn/streaming_rpc.md), and RTMP which is a specialized streaming protocol.
- I don't need replies. With some inductions, we know that in your scene, requests can be dropped at any stage, because the client is always unaware of the situation. Are you really sure this is acceptable? Even if you don't need the reply, we recommend sending back small-size replies, which are unlikely performance bottlenecks and probably valuable clues when debugging complex bugs.
-# What is ![baidu-rpc](docs/images/logo.png)?
+# What is ![brpc](docs/images/logo.png)?
A RPC framework used throughout [Baidu](http://ir.baidu.com/phoenix.zhtml?c=188488&p=irol-irhome), with more than 600,000 instances. Only C++ implementation is opensourced right now.
You can use it for:
* Build a server that can talk in multiple protocols (**on same port**), or access all sorts of services
- * restful http/https, h2/h2c (compatible with [grpc](https://github.com/grpc/grpc), will be opensourced soon). using http in baidu-rpc is much more friendly than [libcurl](https://curl.haxx.se/libcurl/).
+ * restful http/https, h2/h2c (compatible with [grpc](https://github.com/grpc/grpc), will be opensourced soon). using http in brpc is much more friendly than [libcurl](https://curl.haxx.se/libcurl/).
* [redis](docs/cn/redis_client.md) and [memcached](docs/cn/memcache_client.md), thread-safe, more friendly and performant than the official clients
- * [rtmp](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/brpc/rtmp.h)/[flv](https://en.wikipedia.org/wiki/Flash_Video)/[hls](https://en.wikipedia.org/wiki/HTTP_Live_Streaming), for building live-streaming services.
+ * [rtmp](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/brpc/rtmp.h)/[flv](https://en.wikipedia.org/wiki/Flash_Video)/[hls](https://en.wikipedia.org/wiki/HTTP_Live_Streaming), for building live-streaming services.
* hadoop_rpc(not opensourced yet)
* [rdma](https://en.wikipedia.org/wiki/Remote_direct_memory_access) support via [openucx](https://github.com/openucx/ucx) (will be opensourced soon)
* all sorts of protocols used in Baidu: baidu_std, [streaming_rpc](docs/cn/streaming_rpc.md), hulu_pbrpc, [sofa_pbrpc](https://github.com/baidu/sofa-pbrpc), nova_pbrpc, public_pbrpc, ubrpc, and nshead-based ones.
@@ -49,39 +49,39 @@ You can use it for:
* Use [combo channels](docs/cn/combo_channel.md) to simplify complicated client patterns declaratively, including sharded and parallel accesses.
* Debug services [via http](docs/cn/builtin_service.md), and run online profilers.
* Get [better latency and throughput](#better-latency-and-throughput).
-* [Extend baidu-rpc](docs/cn/new_protocol.md) with the protocols used in your organization quickly, or customize components, including [naming services](docs/cn/load_balancing.md#名字服务) (dns, zk, etcd), [load balancers](docs/cn/load_balancing.md#负载均衡) (rr, random, consistent hashing)
+* [Extend brpc](docs/cn/new_protocol.md) with the protocols used in your organization quickly, or customize components, including [naming services](docs/cn/load_balancing.md#名字服务) (dns, zk, etcd), [load balancers](docs/cn/load_balancing.md#负载均衡) (rr, random, consistent hashing)
-# Advantages of baidu-rpc
+# Advantages of brpc
### More friendly API
-Only 3 (major) user headers: [Server](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/brpc/server.h), [Channel](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/brpc/channel.h), [Controller](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/brpc/controller.h), corresponding to server-side, client-side and parameter-set respectively. You don't have to worry about "How to initialize XXXManager", "How to layer all these components together", "What's the relationship between XXXController and XXXContext". All you to do is simple:
+Only 3 (major) user headers: [Server](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/brpc/server.h), [Channel](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/brpc/channel.h), [Controller](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/brpc/controller.h), corresponding to server-side, client-side and parameter-set respectively. You don't have to worry about "How to initialize XXXManager", "How to layer all these components together", "What's the relationship between XXXController and XXXContext". All you to do is simple:
-* Build service? include [brpc/server.h](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/brpc/server.h) and follow the comments or [examples](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/example/echo_c++/server.cpp).
+* Build service? include [brpc/server.h](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/brpc/server.h) and follow the comments or [examples](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/example/echo_c++/server.cpp).
-* Access service? include [brpc/channel.h](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/brpc/channel.h) and follow the comments or [examples](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/example/echo_c++/client.cpp).
+* Access service? include [brpc/channel.h](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/brpc/channel.h) and follow the comments or [examples](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/example/echo_c++/client.cpp).
-* Tweak parameters? Checkout [brpc/controller.h](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/brpc/controller.h). Note that the class is shared by server and channel. Methods are separated into 3 parts: client-side, server-side and both-side.
+* Tweak parameters? Checkout [brpc/controller.h](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/brpc/controller.h). Note that the class is shared by server and channel. Methods are separated into 3 parts: client-side, server-side and both-side.
-We tried to make simple things simple. Take naming service as an example, in older RPC implementations, you may need to copy a pile of obscure code to make it work, however in baidu-rpc accessing BNS is expressed as `Init("bns://node-name"...`, DNS is "http://domain-name" and local machine list is "file:///home/work/server.list". Without any explanation, you know what it means.
+We tried to make simple things simple. Take naming service as an example, in older RPC implementations, you may need to copy a pile of obscure code to make it work, however in brpc accessing BNS is expressed as `Init("bns://node-name"...`, DNS is "http://domain-name" and local machine list is "file:///home/work/server.list". Without any explanation, you know what it means.
### Make services more reliable
-baidu-rpc is extensively used in baidu-rpc, with more than 600,000 instances and 500 kinds of services, from map-reduce, table storages, high-performance computing, machine learning, indexing servers, ranking servers…. It's been proven.
+brpc is extensively used in brpc, with more than 600,000 instances and 500 kinds of services, from map-reduce, table storages, high-performance computing, machine learning, indexing servers, ranking servers…. It's been proven.
-baidu-rpc pays special attentions to development and maintenance efficency, you can [view internal status of servers](docs/cn/builtin_service.md) in web brower or with curl, you can analyze [cpu usages](docs/cn/cpu_profiler.md), [heap allocations](docs/cn/heap_profiler.md) and [lock contentions](docs/cn/contention_profiler.md) of services online, you can measure stats by [bvar](docs/cn/bvar.md), which is viewable in [/vars](docs/cn/vars.md).
+brpc pays special attentions to development and maintenance efficency, you can [view internal status of servers](docs/cn/builtin_service.md) in web brower or with curl, you can analyze [cpu usages](docs/cn/cpu_profiler.md), [heap allocations](docs/cn/heap_profiler.md) and [lock contentions](docs/cn/contention_profiler.md) of services online, you can measure stats by [bvar](docs/cn/bvar.md), which is viewable in [/vars](docs/cn/vars.md).
### Better latency and throughput
-Although almost all RPC implementations claim that they're "high-performant", the number are probably just numbers. Being really high-performant in different scenarios is difficult. To make users easier, baidu-rpc goes much deeper at performance than other implementations.
+Although almost all RPC implementations claim that they're "high-performant", the number are probably just numbers. Being really high-performant in different scenarios is difficult. To make users easier, brpc goes much deeper at performance than other implementations.
-* Reading and parsing requests from different clients is fully parallelized, and users don't need to distinguish between "IO-threads" and "Processing-threads". Other implementations probably have "IO-threads" and "Processing-threads" and hash file descriptors(fd) into IO-threads. When a IO-thread handles one of its fds, other fds in the thread can't be handled. If a message is large, other fds are significantly delayed. Although different IO-threads run in parallel, you won't have many IO-threads since they don't have too much to do generally except reading/parsing from fds. If you have 10 IO-threads, one fd may affect 10% of all fds, which is unacceptable to industrial online services (requiring 99.99% availability). The problem will be worse, when fds are distributed unevenly accross IO-threads (unfortunately common), or the service is multi-tenancy (common in cloud services). In baidu-rpc, reading from different fds is parallelized and even processing different messages from one fd is parallelized as well. Parsing a large message does not block other messages from the same fd, not to mention other fds. More details can be found [here](docs/cn/io.md#收消息).
+* Reading and parsing requests from different clients is fully parallelized, and users don't need to distinguish between "IO-threads" and "Processing-threads". Other implementations probably have "IO-threads" and "Processing-threads" and hash file descriptors(fd) into IO-threads. When a IO-thread handles one of its fds, other fds in the thread can't be handled. If a message is large, other fds are significantly delayed. Although different IO-threads run in parallel, you won't have many IO-threads since they don't have too much to do generally except reading/parsing from fds. If you have 10 IO-threads, one fd may affect 10% of all fds, which is unacceptable to industrial online services (requiring 99.99% availability). The problem will be worse, when fds are distributed unevenly accross IO-threads (unfortunately common), or the service is multi-tenancy (common in cloud services). In brpc, reading from different fds is parallelized and even processing different messages from one fd is parallelized as well. Parsing a large message does not block other messages from the same fd, not to mention other fds. More details can be found [here](docs/cn/io.md#收消息).
* Writing into one fd and multiple fds are highly concurrent. When multiple threads write into the same fd (common for multiplexed connections), the first thread directly writes in-place and other threads submit their write requests in [wait-free](http://en.wikipedia.org/wiki/Non-blocking_algorithm#Wait-freedom) manner. One fd can be written into 5,000,000 16-byte messages per second by a couple of highly-contended threads. More details can be found [here](docs/cn/io.md#发消息).
* Minimal locks. High-QPS services can utilize all CPU power on the machine. For example, [creating bthreads](docs/cn/memory_management.md) for processing requests, [setting up timeout](docs/cn/timer_keeping.md), [finding RPC contexts](docs/cn/bthread_id.md) according to response, [recording performance counters](docs/cn/bvar.md) are all highly concurrent. Users see very few contentions (via [contention profiler](docs/cn/contention_profiler.md)) caused by RPC framework even if the service runs at 500,000+ QPS.
-* Server adjusts thread number according to load. Traditional implementations set number of threads according to latency to avoid limiting the throughput. baidu-rpc creates a new [bthread](docs/cn/bthread.md) for each request and ends the bthread when the request is done, which automatically adjusts thread number according to load.
+* Server adjusts thread number according to load. Traditional implementations set number of threads according to latency to avoid limiting the throughput. brpc creates a new [bthread](docs/cn/bthread.md) for each request and ends the bthread when the request is done, which automatically adjusts thread number according to load.
-Check out [benchmark](docs/cn/benchmark.md) for a comparison between baidu-rpc and other implementations.
+Check out [benchmark](docs/cn/benchmark.md) for a comparison between brpc and other implementations.
# Try it!
-Check out [Getting Started](docs/cn/getting_started.md) to start.
\ No newline at end of file
+Check out [Getting Started](docs/cn/getting_started.md) to start.
diff --git a/docs/cn/atomic_instructions.md b/docs/cn/atomic_instructions.md
index a1ad16e3f5..353f3eb06b 100644
--- a/docs/cn/atomic_instructions.md
+++ b/docs/cn/atomic_instructions.md
@@ -25,7 +25,7 @@
- 一个依赖全局多生产者多消费者队列(MPMC)的程序难有很好的多核扩展性,因为这个队列的极限吞吐取决于同步cache的延时,而不是核心的个数。最好是用多个SPMC或多个MPSC队列,甚至多个SPSC队列代替,在源头就规避掉竞争。
- 另一个例子是全局计数器,如果所有线程都频繁修改一个全局变量,性能就会很差,原因同样在于不同的核心在不停地同步同一个cacheline。如果这个计数器只是用作打打日志之类的,那我们完全可以让每个线程修改thread-local变量,在需要时再合并所有线程中的值,性能可能有几十倍的差别。
-做不到完全不共享,那就尽量少共享。在一些读很多的场景下,也许可以降低写的频率以减少同步cacheline的次数,以加快读的平均性能。一个相关的编程陷阱是避免false sharing:这指的是那些不怎么被修改的变量,由于同一个cacheline中的另一个变量被频繁修改,而不得不经常等待cacheline同步而显著变慢了。多线程中的变量尽量按访问规律排列,频繁被其他线程的修改要放在独立的cacheline中。要让一个变量或结构体按cacheline对齐,可以include 然后使用BAIDU_CACHELINE_ALIGNMENT宏,用法请自行grep一下baidu-rpc的代码了解。
+做不到完全不共享,那就尽量少共享。在一些读很多的场景下,也许可以降低写的频率以减少同步cacheline的次数,以加快读的平均性能。一个相关的编程陷阱是避免false sharing:这指的是那些不怎么被修改的变量,由于同一个cacheline中的另一个变量被频繁修改,而不得不经常等待cacheline同步而显著变慢了。多线程中的变量尽量按访问规律排列,频繁被其他线程的修改要放在独立的cacheline中。要让一个变量或结构体按cacheline对齐,可以include 然后使用BAIDU_CACHELINE_ALIGNMENT宏,用法请自行grep一下brpc的代码了解。
# Memory fence
@@ -91,7 +91,7 @@ if (ready.load(std::memory_order_acquire)) {
# wait-free & lock-free
-原子指令能为我们的服务赋予两个重要属性:[wait-free](http://en.wikipedia.org/wiki/Non-blocking_algorithm#Wait-freedom)和[lock-free](http://en.wikipedia.org/wiki/Non-blocking_algorithm#Lock-freedom)。前者指不管OS如何调度线程,每个线程都始终在做有用的事;后者比前者弱一些,指不管OS如何调度线程,至少有一个线程在做有用的事。如果我们的服务中使用了锁,那么OS可能把一个刚获得锁的线程切换出去,这时候所有依赖这个锁的线程都在等待,而没有做有用的事,所以用了锁就不是lock-free,更不会是wait-free。为了确保一件事情总在确定时间内完成,实时系统的关键代码至少是lock-free的。在我们广泛又多样的在线服务中,对时效性也有着严苛的要求,如果RPC中最关键的部分满足wait-free或lock-free,就可以提供更稳定的服务质量。比如,由于[fd](https://en.wikipedia.org/wiki/File_descriptor)只适合被单个线程操作,baidu-rpc中使用原子指令最大化了fd的读写的并发度,具体见[IO](io.md)。
+原子指令能为我们的服务赋予两个重要属性:[wait-free](http://en.wikipedia.org/wiki/Non-blocking_algorithm#Wait-freedom)和[lock-free](http://en.wikipedia.org/wiki/Non-blocking_algorithm#Lock-freedom)。前者指不管OS如何调度线程,每个线程都始终在做有用的事;后者比前者弱一些,指不管OS如何调度线程,至少有一个线程在做有用的事。如果我们的服务中使用了锁,那么OS可能把一个刚获得锁的线程切换出去,这时候所有依赖这个锁的线程都在等待,而没有做有用的事,所以用了锁就不是lock-free,更不会是wait-free。为了确保一件事情总在确定时间内完成,实时系统的关键代码至少是lock-free的。在我们广泛又多样的在线服务中,对时效性也有着严苛的要求,如果RPC中最关键的部分满足wait-free或lock-free,就可以提供更稳定的服务质量。比如,由于[fd](https://en.wikipedia.org/wiki/File_descriptor)只适合被单个线程操作,brpc中使用原子指令最大化了fd的读写的并发度,具体见[IO](io.md)。
值得提醒的是,常见想法是lock-free或wait-free的算法会更快,但事实可能相反,因为:
diff --git a/docs/cn/avalanche_effect.md b/docs/cn/avalanche_effect.md
index b826fb1a72..014804974f 100644
--- a/docs/cn/avalanche_effect.md
+++ b/docs/cn/avalanche_effect.md
@@ -9,13 +9,13 @@
1. A可能对B发起了过于频繁的基于超时的重试。这不仅会让A的最大qps降到**线程数 / 超时**,还会让B处的qps翻**重试次数**倍。这就可能陷入恶性循环了:只要**线程数 / 超时 \* 重试次数**大于B的最大qps**,**B就无法恢复 -> A处的client会继续超时 -> A继续重试 -> B继续无法恢复。
2. A或B没有限制某个缓冲或队列的长度,或限制过于宽松。拥塞请求会大量地积压在那里,要恢复就得全部处理完,时间可能长得无法接受。由于有限长的缓冲或队列需要在填满时解决等待、唤醒等问题,有时为了简单,代码可能会假定缓冲或队列不会满,这就埋下了种子。即使队列是有限长的,恢复时间也可能很长,因为清空队列的过程是个追赶问题,排空的时间取决于**积压的请求数 / (最大qps - 当前qps)**,如果当前qps和最大qps差的不多,积压的请求又比较多,那排空时间就遥遥无期了。
-了解这些因素后可以更好的理解baidu-rpc中相关的设计。
+了解这些因素后可以更好的理解brpc中相关的设计。
-1. 拥塞时A服务最大qps的跳变是因为线程个数是**硬限**,单个请求的处理时间很大程度上决定了最大qps。而baidu-rpc server端默认在bthread中处理请求,个数是软限,单个请求超时只是阻塞所在的bthread,并不会影响为新请求建立新的bthread。baidu-rpc也提供了完整的异步接口,让用户可以进一步提高io-bound服务的并发度,降低服务被打满的可能性。
-2. baidu-rpc中[重试](client.md#重试)默认只在连接出错时发起,避免了流量放大,这是比较有效率的重试方式。如果需要基于超时重试,可以设置[backup request](client.md#backuprequest),这类重试最多只有一次,放大程度降到了最低。baidu-rpc中的RPC超时是deadline,超过后RPC一定会结束,这让用户对服务的行为有更好的预判。在之前的一些实现中,RPC超时是单次超时*重试次数,在实践中容易误判。
-3. baidu-rpc server端的[max_concurrency选项](server.md#id-创建和设置Server-限制最大并发)控制了server的最大并发:当同时处理的请求数超过max_concurrency时,server会回复client错误,而不是继续积压。这一方面在服务开始的源头控制住了积压的请求数,尽量避免延生到用户缓冲或队列中,另一方面也让client尽快地去重试其他server,对集群来说是个更好的策略。
+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,对集群来说是个更好的策略。
-对于baidu-rpc的用户来说,要防止雪崩,主要注意两点:
+对于brpc的用户来说,要防止雪崩,主要注意两点:
-1. 评估server的最大并发,设置合理的max_concurrency值。这个默认是不设的,也就是不限制。无论程序是同步还是异步,用户都可以通过 **最大qps \* 非拥塞时的延时**(秒)来评估最大并发,原理见[little's law](https://en.wikipedia.org/wiki/Little),这两个量都可以在baidu-rpc中的内置服务中看到。max_concurrency与最大并发相等或大一些就行了。
-2. 注意考察重试发生时的行为,特别是在定制RetryPolicy时。如果你只是用默认的baidu-rpc重试,一般是安全的。但用户程序也常会自己做重试,比如通过一个Channel访问失败后,去访问另外一个Channel,这种情况下要想清楚重试发生时最差情况下请求量会放大几倍,服务是否可承受。
+1. 评估server的最大并发,设置合理的max_concurrency值。这个默认是不设的,也就是不限制。无论程序是同步还是异步,用户都可以通过 **最大qps \* 非拥塞时的延时**(秒)来评估最大并发,原理见[little's law](https://en.wikipedia.org/wiki/Little),这两个量都可以在brpc中的内置服务中看到。max_concurrency与最大并发相等或大一些就行了。
+2. 注意考察重试发生时的行为,特别是在定制RetryPolicy时。如果你只是用默认的brpc重试,一般是安全的。但用户程序也常会自己做重试,比如通过一个Channel访问失败后,去访问另外一个Channel,这种情况下要想清楚重试发生时最差情况下请求量会放大几倍,服务是否可承受。
diff --git a/docs/cn/backup_request.md b/docs/cn/backup_request.md
index f3e9ef4ec3..d5fa6eaee8 100644
--- a/docs/cn/backup_request.md
+++ b/docs/cn/backup_request.md
@@ -1,10 +1,10 @@
-有时为了保证可用性,需要同时访问两路服务,哪个先返回就取哪个。在baidu-rpc中,这有多种做法:
+有时为了保证可用性,需要同时访问两路服务,哪个先返回就取哪个。在brpc中,这有多种做法:
# 当后端server可以挂在一个名字服务内时
Channel开启backup request。这个Channel会先向其中一个server发送请求,如果在ChannelOptions.backup_request_ms后还没回来,再向另一个server发送。之后哪个先回来就取哪个。在设置了合理的backup_request_ms后,大部分时候只会发一个请求,对后端服务只有一倍压力。
-示例代码见[example/backup_request_c++](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/example/backup_request_c++)。这个例子中,client设定了在2ms后发送backup request,server在碰到偶数位的请求后会故意睡眠20ms以触发backup request。
+示例代码见[example/backup_request_c++](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/example/backup_request_c++)。这个例子中,client设定了在2ms后发送backup request,server在碰到偶数位的请求后会故意睡眠20ms以触发backup request。
运行后,client端和server端的日志分别如下,“index”是请求的编号。可以看到server端在收到第一个请求后会故意sleep 20ms,client端之后发送另一个同样index的请求,最终的延时并没有受到故意sleep的影响。
@@ -18,7 +18,7 @@ Channel开启backup request。这个Channel会先向其中一个server发送请
## 选择合理的backup_request_ms
-可以观察baidu-rpc默认提供的latency_cdf图,或自行添加。cdf图的y轴是延时(默认微秒),x轴是小于y轴延时的请求的比例。在下图中,选择backup_request_ms=2ms可以大约覆盖95.5%的请求,选择backup_request_ms=10ms则可以覆盖99.99%的请求。
+可以观察brpc默认提供的latency_cdf图,或自行添加。cdf图的y轴是延时(默认微秒),x轴是小于y轴延时的请求的比例。在下图中,选择backup_request_ms=2ms可以大约覆盖95.5%的请求,选择backup_request_ms=10ms则可以覆盖99.99%的请求。
![img](../images/backup_request_4.png)
@@ -41,6 +41,6 @@ my_func_latency << tm.u_elapsed(); // u代表微秒,还有s_elapsed(), m_elap
# 当后端server不能挂在一个名字服务内时
-【推荐】建立一个开启backup request的SelectiveChannel,其中包含两个sub channel。访问这个SelectiveChannel和上面的情况类似,会先访问一个sub channel,如果在ChannelOptions.backup_request_ms后没返回,再访问另一个sub channel。如果一个sub channel对应一个集群,这个方法就是在两个集群间做互备。SelectiveChannel的例子见[example/selective_echo_c++](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/tree/example/selective_echo_c++),具体做法请参考上面的过程。
+【推荐】建立一个开启backup request的SelectiveChannel,其中包含两个sub channel。访问这个SelectiveChannel和上面的情况类似,会先访问一个sub channel,如果在ChannelOptions.backup_request_ms后没返回,再访问另一个sub channel。如果一个sub channel对应一个集群,这个方法就是在两个集群间做互备。SelectiveChannel的例子见[example/selective_echo_c++](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/tree/example/selective_echo_c++),具体做法请参考上面的过程。
-【不推荐】发起两个异步RPC后Join它们,它们的done内是相互取消的逻辑。示例代码见[example/cancel_c++](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/tree/example/cancel_c++)。这种方法的问题是总会发两个请求,对后端服务有两倍压力,这个方法怎么算都是不经济的,你应该尽量避免用这个方法。
+【不推荐】发起两个异步RPC后Join它们,它们的done内是相互取消的逻辑。示例代码见[example/cancel_c++](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/tree/example/cancel_c++)。这种方法的问题是总会发两个请求,对后端服务有两倍压力,这个方法怎么算都是不经济的,你应该尽量避免用这个方法。
diff --git a/docs/cn/benchmark.md b/docs/cn/benchmark.md
index 880c826d48..80482a0849 100644
--- a/docs/cn/benchmark.md
+++ b/docs/cn/benchmark.md
@@ -2,7 +2,7 @@
在多核的前提下,性能和线程是紧密联系在一起的。线程间的跳转对高频IO操作的性能有决定性作用:一次跳转意味着至少3-20微秒的延时,由于每个核心的L1 cache独立(我们的cpu L2 cache也是独立的),随之而来是大量的cache miss,一些变量的读取、写入延时会从纳秒级上升几百倍至微秒级:等待cpu把对应的cacheline同步过来。有时这带来了一个出乎意料的结果,当每次的处理都很简短时,一个多线程程序未必比一个单线程程序更快。因为前者可能在每次付出了大的切换代价后只做了一点点“正事”,而后者在不停地做“正事”。不过单线程也是有代价的,它工作良好的前提是“正事”都很快,否则一旦某次变慢就使后续的所有“正事”都被延迟了。在一些处理时间普遍较短的程序中,使用(多个不相交的)单线程能最大程度地”做正事“,由于每个请求的处理时间确定,延时表现也很稳定,各种http server正是这样。但我们的检索服务要做的事情可就复杂多了,有大量的后端服务需要访问,广泛存在的长尾请求使每次处理的时间无法确定,排序策略也越来越复杂。如果还是使用(多个不相交的)单线程的话,一次难以预计的性能抖动,或是一个大请求可能导致后续一堆请求被延迟。
-为了避免请求之间相互影响,请求级的线程跳转是baidu-rpc必须付出的代价,我们能做的是使[线程跳转最优化](io.md#the-full-picture)。不过,对服务的性能测试还不能很好地体现这点。测试中的处理往往极为简单,使得线程切换的影响空前巨大,通过控制多线程和单线程处理的比例,我们可以把一个测试服务的qps从100万到500万操纵自如(同机),这损伤了性能测试结果的可信度。要知道,真实的服务并不是在累加一个数字,或者echo一个字符串,一个qps几百万的echo程序没有指导意义。鉴于此,在发起性能测试一年后(15年底),在baidu-rpc又经历了1200多次改动后,我们需要review所有的测试,加强其中的线程因素,以获得对真实场景有明确意义的结果。具体来说:
+为了避免请求之间相互影响,请求级的线程跳转是brpc必须付出的代价,我们能做的是使[线程跳转最优化](io.md#the-full-picture)。不过,对服务的性能测试还不能很好地体现这点。测试中的处理往往极为简单,使得线程切换的影响空前巨大,通过控制多线程和单线程处理的比例,我们可以把一个测试服务的qps从100万到500万操纵自如(同机),这损伤了性能测试结果的可信度。要知道,真实的服务并不是在累加一个数字,或者echo一个字符串,一个qps几百万的echo程序没有指导意义。鉴于此,在发起性能测试一年后(15年底),在brpc又经历了1200多次改动后,我们需要review所有的测试,加强其中的线程因素,以获得对真实场景有明确意义的结果。具体来说:
- 请求不应等长,要有长尾。这能考察RPC能否让请求并发,否则一个慢请求会影响大量后续请求。
- 要有多级server的场景。server内用client访问下游server,这能考察server和client的综合表现。
@@ -14,7 +14,7 @@
## UB
-com组(INF前身)在08年开发的RPC框架,在百度产品线广泛使用,已被baidu-rpc代替。UB的每个请求独占一个连接(连接池),在大规模服务中每台机器都需要保持大量的连接,限制了其使用场景,像百度的分布式系统都不用UB。UB只支持nshead+mcpack协议,也没怎么考虑扩展性,所以增加新协议和新功能往往要调整大段代码,在实践中大部分人“知难而退”了。UB缺乏调试和运维接口,服务的运行状态对用户基本是黑盒,只能靠低效地打日志来追踪问题,服务出现问题时常要拉上维护者一起排查,效率很低。UB有多个变种:
+com组(INF前身)在08年开发的RPC框架,在百度产品线广泛使用,已被brpc代替。UB的每个请求独占一个连接(连接池),在大规模服务中每台机器都需要保持大量的连接,限制了其使用场景,像百度的分布式系统都不用UB。UB只支持nshead+mcpack协议,也没怎么考虑扩展性,所以增加新协议和新功能往往要调整大段代码,在实践中大部分人“知难而退”了。UB缺乏调试和运维接口,服务的运行状态对用户基本是黑盒,只能靠低效地打日志来追踪问题,服务出现问题时常要拉上维护者一起排查,效率很低。UB有多个变种:
* ubrpc:INF在10年基于UB开发的RPC框架,用.idl文件(类似.proto)描述数据的schema,而不是手动打包。这个RPC有被使用,但不广泛。
@@ -26,11 +26,11 @@ connection")。虽然这个名称不太准确(见上文对ubrpc的介绍)
## hulu-pbrpc
-INF在13年基于saber(kylin变种)和protobuf实现的RPC框架,hulu在实现上有较多问题:未封装的引用计数,混乱的生命周期,充斥的race conditions和ABA problems,运行质量不可靠,比如短链接从来没有能正常运行过。之后迅速被baidu-rpc代替,测试时其代码为:。hulu-pbrpc只支持单连接,结果用“**hulu-pbrpc**"指代。
+INF在13年基于saber(kylin变种)和protobuf实现的RPC框架,hulu在实现上有较多问题:未封装的引用计数,混乱的生命周期,充斥的race conditions和ABA problems,运行质量不可靠,比如短链接从来没有能正常运行过。之后迅速被brpc代替,测试时其代码为:。hulu-pbrpc只支持单连接,结果用“**hulu-pbrpc**"指代。
-## baidu-rpc
+## brpc
-INF在2014年底开发至今的rpc产品,支持百度内所有协议(不限于protobuf),并第一次统一了百度内主要分布式系统的RPC框架。测试时其代码为[r31906](https://svn.baidu.com/public/tags/baidu-rpc/baidu-rpc_1-0-199-31906_PD_BL)(开发请使用@ci-base保持更新)。baidu-rpc既支持单连接也支持连接池,前者的结果用"**baidu-rpc**"指代,后者用“**baidu-rpc_mc**"指代。
+INF在2014年底开发至今的rpc产品,支持百度内所有协议(不限于protobuf),并第一次统一了百度内主要分布式系统的RPC框架。测试时其代码为[r31906](https://svn.baidu.com/public/tags/brpc/brpc_1-0-199-31906_PD_BL)(开发请使用@ci-base保持更新)。brpc既支持单连接也支持连接池,前者的结果用"**brpc**"指代,后者用“**brpc_mc**"指代。
## sofa-pbrpc
@@ -70,7 +70,7 @@ thrift是由facebook最早在07年开发的序列化方法和rpc框架,包含
测试代码:
-下面所有的曲线图是使用baidu-rpc开发的dashboard程序绘制的,去掉路径后可以看到和所有baidu-rpc
+下面所有的曲线图是使用brpc开发的dashboard程序绘制的,去掉路径后可以看到和所有brpc
server一样的[内置服务](builtin_service.md)。
## 配置
@@ -83,7 +83,7 @@ server一样的[内置服务](builtin_service.md)。
- hulu-pbrpc: 额外配置了12个IO线程。这些线程会处理fd读取,请求解析等任务。hulu有个“共享队列“的配置项,默认不打开,作用是把fd静态散列到多个线程中,由于线程间不再争抢,hulu的qps会显著提高,但会明显地被长尾影响(原因见[测试方法](#测试方法))。考虑到大部分使用者并不会去改配置,我们也选择不打开。
- thrift: 额外配置了12个IO线程。这些线程会处理fd读取,请求解析等任务。thrift的client不支持多线程,每个线程得使用独立的client,连接也都是分开的。
- sofa-pbrpc:按照sofa同学的要求,把io_service_pool_size配置为24,work_thread_num配置为1。大概含义是使用独立的24组线程池,每组1个worker thread。和hulu不打开“共享队列”时类似,这个配置会显著提高sofa-pbrpc的QPS,但同时使它失去了处理长尾的能力。如果你在真实产品中使用,我们不建议这个配置。(而应该用io_service_pool_size=1, work_thread_num=24)
-- baidu-rpc:尽管baidu-rpc的client运行在bthread中时会获得10%~20%的QPS提升和更低的延时,但测试中的client都运行统一的pthread中。
+- brpc:尽管brpc的client运行在bthread中时会获得10%~20%的QPS提升和更低的延时,但测试中的client都运行统一的pthread中。
所有的RPC client都以多个线程同步方式发送,这种方法最接近于真实系统中的情况,在考察QPS时也兼顾了延时因素。
@@ -99,11 +99,11 @@ server一样的[内置服务](builtin_service.md)。
**分析**
* 以_mc结尾的曲线代表client和server保持多个连接(线程数个),在本测试中会有更好的表现。
- * baidu-rpc:当请求包小于16KB时,单连接下的吞吐超过了多连接的ubrpc_mc和thrift_mc,随着请求包变大,内核对单个连接的写入速度成为瓶颈。而多连接下的baidu-rpc则一骑绝尘,达到了测试中最高的2.3GB/s。注意:虽然使用连接池的baidu-rpc在发送大包时吞吐更高,但也会耗费更多的CPU(UB和thrift也是这样)。下图中的单连接baidu-rpc已经可以提供800多兆的吞吐,足以打满万兆网卡,而使用的CPU可能只有多链接下的1/2
+ * brpc:当请求包小于16KB时,单连接下的吞吐超过了多连接的ubrpc_mc和thrift_mc,随着请求包变大,内核对单个连接的写入速度成为瓶颈。而多连接下的brpc则一骑绝尘,达到了测试中最高的2.3GB/s。注意:虽然使用连接池的brpc在发送大包时吞吐更高,但也会耗费更多的CPU(UB和thrift也是这样)。下图中的单连接brpc已经可以提供800多兆的吞吐,足以打满万兆网卡,而使用的CPU可能只有多链接下的1/2
* (写出过程是[wait-free的](io.md#发消息)),真实系统中请优先使用单链接。
-* thrift: 初期明显低于baidu-rpc,随着包变大超过了单连接的baidu-rpc。
+* thrift: 初期明显低于brpc,随着包变大超过了单连接的brpc。
* UB:
-* 和thrift类似的曲线,但平均要低4-5万QPS,在32K包时超过了单连接的baidu-rpc。整个过程中QPS几乎没变过。
+* 和thrift类似的曲线,但平均要低4-5万QPS,在32K包时超过了单连接的brpc。整个过程中QPS几乎没变过。
* grpc: 初期几乎与UB平行,但低1万左右,超过8K开始下降。
* hulu-pbrpc和sofa-pbrpc:
* 512字节前高于UB和grpc,但之后就急转直下,相继垫底。这个趋势是写不够并发的迹象。
@@ -118,9 +118,9 @@ server一样的[内置服务](builtin_service.md)。
**分析**
-baidu-rpc: 随着发送线程增加,QPS在快速增加,有很好的多线程扩展性。
+brpc: 随着发送线程增加,QPS在快速增加,有很好的多线程扩展性。
-UB和thrift:8个线程下高于baidu-rpc,但超过8个线程后被baidu-rpc迅速超过,thrift继续“平移”,UB出现了明显下降。
+UB和thrift:8个线程下高于brpc,但超过8个线程后被brpc迅速超过,thrift继续“平移”,UB出现了明显下降。
grpc,hulu-pbrpc,sofa-pbrpc: 几乎重合,256个线程时相比1个线程时只有1倍的提升,多线程扩展性不佳。
@@ -134,8 +134,8 @@ grpc,hulu-pbrpc,sofa-pbrpc: 几乎重合,256个线程时相比1个线程
![img](../images/latency_cdf.png)
**分析**
-- baidu-rpc:平均延时短,几乎没有被长尾影响。
-- UB和thrift:平均延时比baidu-rpc高1毫秒,受长尾影响不大。
+- brpc:平均延时短,几乎没有被长尾影响。
+- UB和thrift:平均延时比brpc高1毫秒,受长尾影响不大。
- hulu-pbrpc:走向和UB和thrift类似,但平均延时进一步增加了1毫秒。
- grpc : 初期不错,到长尾区域后表现糟糕,直接有一部分请求超时了。(反复测试都是这样,像是有bug)
- sofa-pbrpc:30%的普通请求(上图未显示)被长尾严重干扰。
@@ -149,8 +149,8 @@ grpc,hulu-pbrpc,sofa-pbrpc: 几乎重合,256个线程时相比1个线程
![img](../images/qps_vs_multi_client.png)
**分析**
-* baidu-rpc: 随着cilent增加,server的QPS在快速增加,有不错的client扩展性。
-* sofa-pbrpc: 随着client增加,server的QPS也在快速增加,但幅度不如baidu-rpc,client扩展性也不错。从16个client到32个client时的提升较小。
+* brpc: 随着cilent增加,server的QPS在快速增加,有不错的client扩展性。
+* sofa-pbrpc: 随着client增加,server的QPS也在快速增加,但幅度不如brpc,client扩展性也不错。从16个client到32个client时的提升较小。
* hulu-pbrpc: 随着client增加,server的QPS在增加,但幅度进一步小于sofa-pbrpc。
* UB:增加client几乎不能增加server的QPS。
* thrift:平均QPS低于UB,增加client几乎不能增加server的QPS。
@@ -167,8 +167,8 @@ grpc,hulu-pbrpc,sofa-pbrpc: 几乎重合,256个线程时相比1个线程
![img](../images/multi_client_latency_cdf.png)
**分析**
-- baidu-rpc:平均延时短,几乎没有被长尾影响。
-- UB和thrift:平均延时短,受长尾影响小,平均延时高于baidu-rpc
+- brpc:平均延时短,几乎没有被长尾影响。
+- UB和thrift:平均延时短,受长尾影响小,平均延时高于brpc
- sofa-pbrpc:14%的普通请求被长尾严重干扰。
- hulu-pbrpc:15%的普通请求被长尾严重干扰。
- grpc : 已经完全失控,非常糟糕。
@@ -184,8 +184,8 @@ grpc,hulu-pbrpc,sofa-pbrpc: 几乎重合,256个线程时相比1个线程
![img](../images/multi_server_latency_cdf.png)
**分析**
-- baidu-rpc和UB:平均延时短,几乎没有被长尾影响。
-- thrift: 平均延时显著高于baidu-rpc和UB。
+- brpc和UB:平均延时短,几乎没有被长尾影响。
+- thrift: 平均延时显著高于brpc和UB。
- sofa-pbrpc:2.5%的普通请求被长尾严重干扰。
- hulu-pbrpc:22%的普通请求被长尾严重干扰。
@@ -200,19 +200,19 @@ grpc,hulu-pbrpc,sofa-pbrpc: 几乎重合,256个线程时相比1个线程
![img](../images/twolevel_server_latency_cdf.png)
**分析**
-- baidu-rpc:平均延时短,几乎没有被长尾影响。
-- UB:平均延时短,长尾区域略差于baidu-rpc。
-- thrift: 平均延时显著高于baidu-rpc和UB。
+- brpc:平均延时短,几乎没有被长尾影响。
+- UB:平均延时短,长尾区域略差于brpc。
+- thrift: 平均延时显著高于brpc和UB。
- sofa-pbrpc:17%的普通请求被长尾严重干扰,其中2%的请求延时极长。
- hulu-pbrpc:基本消失在视野中,已无法正常工作。
# 结论
-baidu-rpc:在吞吐,平均延时,长尾处理上都表现优秀。
+brpc:在吞吐,平均延时,长尾处理上都表现优秀。
UB:平均延时和长尾处理的表现都不错,吞吐的扩展性较差,提高线程数和client数几乎不能提升吞吐。
-thrift:单机的平均延时和吞吐尚可,多机的平均延时明显高于baidu-rpc和UB。吞吐的扩展性较差,提高线程数和client数几乎不能提升吞吐。
+thrift:单机的平均延时和吞吐尚可,多机的平均延时明显高于brpc和UB。吞吐的扩展性较差,提高线程数和client数几乎不能提升吞吐。
sofa-pbrpc:处理小包的吞吐尚可,大包的吞吐显著低于其他RPC,延时受长尾影响很大。
diff --git a/docs/cn/benchmark_http.md b/docs/cn/benchmark_http.md
index 93e7e91910..36086fcbea 100644
--- a/docs/cn/benchmark_http.md
+++ b/docs/cn/benchmark_http.md
@@ -1,5 +1,5 @@
-可代替[ab](https://httpd.apache.org/docs/2.2/programs/ab.html)测试http server极限性能。ab功能较多但年代久远,有时本身可能会成为瓶颈。benchmark_http基本上就是一个baidu-rpc http client,性能很高,功能较少,一般压测够用了。
+可代替[ab](https://httpd.apache.org/docs/2.2/programs/ab.html)测试http server极限性能。ab功能较多但年代久远,有时本身可能会成为瓶颈。benchmark_http基本上就是一个brpc http client,性能很高,功能较少,一般压测够用了。
使用方法:
-首先你得[下载和编译](getting_started.md)了baidu-rpc源码,然后去example/http_c++目录编译,成功后应该能看到benchmark_http。
+首先你得[下载和编译](getting_started.md)了brpc源码,然后去example/http_c++目录编译,成功后应该能看到benchmark_http。
diff --git a/docs/cn/bthread.md b/docs/cn/bthread.md
index 0c889da087..908552535a 100644
--- a/docs/cn/bthread.md
+++ b/docs/cn/bthread.md
@@ -1,4 +1,4 @@
-bthread([代码](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/tree/src/bthread))是baidu-rpc使用的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([代码](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/tree/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
@@ -22,7 +22,7 @@ bthread是一个M:N线程库,一个bthread被卡住不会影响其他bthread
##### Q: 我应该在程序中多使用bthread吗?
-不应该。除非你需要在一次RPC过程中[让一些代码并发运行](bthread_or_not.md),你不应该直接调用bthread函数,把这些留给baidu-rpc做更好。
+不应该。除非你需要在一次RPC过程中[让一些代码并发运行](bthread_or_not.md),你不应该直接调用bthread函数,把这些留给brpc做更好。
##### Q:bthread和pthread worker如何对应?
@@ -43,7 +43,7 @@ pthread worker在任何时间只会运行一个bthread,当前bthread挂起时
##### Q:若有大量的bthread调用了阻塞的pthread或系统函数,会影响RPC运行么?
会。比如有8个pthread worker,当有8个bthread都调用了系统usleep()后,处理网络收发的RPC代码就暂时无法运行了。只要阻塞时间不太长, 这一般没什么影响, 毕竟worker都用完了, 除了排队也没有什么好方法.
-在baidu-rpc中用户可以选择调大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#id-创建和设置Server-worker线程数)或[-bthread_concurrency](http://brpc.baidu.com:8765/flags/bthread_concurrency), 在client端可设置[-bthread_concurrency](http://brpc.baidu.com:8765/flags/bthread_concurrency).
那有没有完全规避的方法呢?
diff --git a/docs/cn/bthread_id.md b/docs/cn/bthread_id.md
index 2c3fd99cce..385b65b707 100644
--- a/docs/cn/bthread_id.md
+++ b/docs/cn/bthread_id.md
@@ -8,9 +8,9 @@ bthread_id是一个特殊的同步结构,它可以互斥RPC过程中的不同
- 通过correlation_id在O(1)时间内找到对应的RPC上下文,而无需建立从correlation_id到RPC上下文的全局哈希表。
- 取消RPC。
-上文提到的bug在其他rpc框架中广泛存在,下面我们来看下baidu-rpc是如何通过bthread_id解决这些问题的。
+上文提到的bug在其他rpc框架中广泛存在,下面我们来看下brpc是如何通过bthread_id解决这些问题的。
-bthread_id包括两部分,一个是用户可见的64位id,另一个是对应的不可见的bthread::Id结构体。用户接口都是操作id的。从id映射到结构体的方式和baidu-rpc中的[其他结构](memory_management.md)类似:32位是内存池的位移,32位是version。前者O(1)时间定位,后者防止ABA问题。
+bthread_id包括两部分,一个是用户可见的64位id,另一个是对应的不可见的bthread::Id结构体。用户接口都是操作id的。从id映射到结构体的方式和brpc中的[其他结构](memory_management.md)类似:32位是内存池的位移,32位是version。前者O(1)时间定位,后者防止ABA问题。
bthread_id的接口不太简洁,有不少API:
diff --git a/docs/cn/bthread_or_not.md b/docs/cn/bthread_or_not.md
index e95ab2f9c8..27432caf8f 100644
--- a/docs/cn/bthread_or_not.md
+++ b/docs/cn/bthread_or_not.md
@@ -1,4 +1,4 @@
-baidu-rpc提供了[异步接口](client.md#异步访问),所以一个常见的问题是:我应该用异步接口还是bthread?
+brpc提供了[异步接口](client.md#异步访问),所以一个常见的问题是:我应该用异步接口还是bthread?
短回答:延时不高时你应该先用简单易懂的同步接口,不行的话用异步接口,只有在需要多核并行计算时才用bthread。
@@ -6,7 +6,7 @@ baidu-rpc提供了[异步接口](client.md#异步访问),所以一个常见的
异步即用回调代替阻塞,有阻塞的地方就有回调。虽然在javascript这种语言中回调工作的很好,接受度也非常高,但只要用过,就会发现这和我们需要的回调是两码事,这个区别不是[lambda](https://en.wikipedia.org/wiki/Anonymous_function),也不是[future](https://en.wikipedia.org/wiki/Futures_and_promises),而是javascript是单线程的。javascript的回调放到多线程下可能没有一个能跑过,竞争太多,单线程的同步方法和多线程的同步方法是完全不同的。那是不是服务能搞成类似的形式呢?多个线程,每个都是独立的eventloop。可以,ub**a**server就是(注意带a),但实际效果糟糕,因为阻塞改回调可不简单,当阻塞发生在循环,条件分支,深层子函数中时,改造特别困难,况且很多老代码、第三方代码根本不可能去改造。结果是代码中会出现不可避免的阻塞,导致那个线程中其他回调都被延迟,流量超时,server性能不符合预期。如果你说,”我想把现在的同步代码改造为大量的回调,除了我其他人都看不太懂,并且性能可能更差了”,我猜大部分人不会同意。别被那些鼓吹异步的人迷惑了,他们写的是从头到尾从下到上全异步且不考虑多线程的代码,和你要写的完全是两码事。
-baidu-rpc中的异步和单线程的异步是完全不同的,异步回调会运行在与调用处不同的线程中,你会获得多核扩展性,但代价是你得意识到多线程问题。你可以在回调中阻塞,只要线程够用,对server整体的性能并不会有什么影响。不过异步代码还是很难写的,所以我们提供了[组合访问](combo_channel.md)来简化问题,通过组合不同的channel,你可以声明式地执行复杂的访问,而不用太关心其中的细节。
+brpc中的异步和单线程的异步是完全不同的,异步回调会运行在与调用处不同的线程中,你会获得多核扩展性,但代价是你得意识到多线程问题。你可以在回调中阻塞,只要线程够用,对server整体的性能并不会有什么影响。不过异步代码还是很难写的,所以我们提供了[组合访问](combo_channel.md)来简化问题,通过组合不同的channel,你可以声明式地执行复杂的访问,而不用太关心其中的细节。
当然,延时不长,qps不高时,我们更建议使用同步接口,这也是创建bthread的动机:维持同步代码也能提升交互性能。
@@ -22,7 +22,7 @@ baidu-rpc中的异步和单线程的异步是完全不同的,异步回调会
# 异步或bthread
-有了bthread这个工具,用户甚至可以自己实现异步。以“半同步”为例,在baidu-rpc中用户有多种选择:
+有了bthread这个工具,用户甚至可以自己实现异步。以“半同步”为例,在brpc中用户有多种选择:
- 发起多个异步RPC后挨个Join,这个函数会阻塞直到RPC结束。(这儿是为了和bthread对比,实现中我们建议你使用[ParallelChannel](combo_channel.md#parallelchannel),而不是自己Join)
- 启动多个bthread各自执行同步RPC后挨个join bthreads。
diff --git a/docs/cn/builtin_service.md b/docs/cn/builtin_service.md
index 0770e30889..2d853f881a 100644
--- a/docs/cn/builtin_service.md
+++ b/docs/cn/builtin_service.md
@@ -1,6 +1,6 @@
# 什么是内置服务?
-内置服务以多种形式展现服务器内部状态,提高你开发和调试服务的效率。baidu-rpc通过HTTP协议提供内置服务,可通过浏览器或curl访问,服务器会根据User-Agent返回纯文本或html,你也可以添加?console=1要求返回纯文本。我们在自己的开发机上启动了[一个长期运行的例子](http://brpc.baidu.com:8765/),你可以点击后随便看看。服务端口只有在8000-8999内才能被笔记本访问到,对于范围之外的端口可以使用[rpc_view](rpc_view.md)或在命令行中使用curl 。
+内置服务以多种形式展现服务器内部状态,提高你开发和调试服务的效率。brpc通过HTTP协议提供内置服务,可通过浏览器或curl访问,服务器会根据User-Agent返回纯文本或html,你也可以添加?console=1要求返回纯文本。我们在自己的开发机上启动了[一个长期运行的例子](http://brpc.baidu.com:8765/),你可以点击后随便看看。服务端口只有在8000-8999内才能被笔记本访问到,对于范围之外的端口可以使用[rpc_view](rpc_view.md)或在命令行中使用curl 。
从浏览器访问:
diff --git a/docs/cn/bvar.md b/docs/cn/bvar.md
index 900429ab96..48dac13991 100644
--- a/docs/cn/bvar.md
+++ b/docs/cn/bvar.md
@@ -1,6 +1,6 @@
# 1.什么是bvar?
-[public/bvar](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/)是多线程环境下的计数器类库,方便记录和查看用户程序中的各类数值,它利用了thread local存储避免了cache bouncing,相比UbMonitor几乎不会给程序增加性能开销,也快于竞争频繁的原子操作。baidu-rpc集成了bvar,[/vars](http://brpc.baidu.com:8765/vars)可查看所有曝光的bvar,[/vars/VARNAME](http://brpc.baidu.com:8765/vars/rpc_socket_count)可查阅某个bvar,在rpc中的具体使用方法请查看[这里](vars.md)。baidu-rpc大量使用了bvar提供统计数值,当你需要在多线程环境中计数并展现时,应该第一时间想到bvar。但bvar不能代替所有的计数器,它的本质是把写时的竞争转移到了读:读得合并所有写过的线程中的数据,而不可避免地变慢了。当你读写都很频繁并得基于数值做一些逻辑判断时,你不应该用bvar。
+[public/bvar](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/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。
# 2.什么是cache bouncing?
diff --git a/docs/cn/bvar_c++.md b/docs/cn/bvar_c++.md
index eb36ca63ca..511d4d009b 100644
--- a/docs/cn/bvar_c++.md
+++ b/docs/cn/bvar_c++.md
@@ -145,11 +145,11 @@ class Variable {
static int dump_exposed(Dumper* dumper, const DumpOptions* options);
};
```
-最常见的导出需求是通过HTTP接口查询和写入本地文件。前者在baidu-rpc中通过[/vars](vars.md)服务提供,后者则已实现在bvar中,由用户选择开启。该功能由5个gflags控制,你的程序需要使用[gflags](flags.md)。
+最常见的导出需求是通过HTTP接口查询和写入本地文件。前者在brpc中通过[/vars](vars.md)服务提供,后者则已实现在bvar中,由用户选择开启。该功能由5个gflags控制,你的程序需要使用[gflags](flags.md)。
![img](../images/bvar_dump_flags.png)
-用户可在程序启动前加上对应的gflags,在baidu-rpc中也可通过[/flags](flags.md)服务在启动后动态修改某个gflag。
+用户可在程序启动前加上对应的gflags,在brpc中也可通过[/flags](flags.md)服务在启动后动态修改某个gflag。
当bvar_dump_file不为空时,程序会启动一个后台导出线程以bvar_dump_interval指定的间隔更新bvar_dump_file,其中包含了被bvar_dump_include匹配且不被bvar_dump_exclude匹配的所有bvar。
@@ -171,7 +171,7 @@ rpc_server_8002_uptime_ms : 14740954
像”`iobuf_block_count : 8`”被bvar_dump_include过滤了,“`rpc_server_8002_error : 0`”则被bvar_dump_exclude排除了。
-如果你的程序没有使用baidu-rpc,仍需要动态修改gflag(一般不需要),可以调用google::SetCommandLineOption(),如下所示:
+如果你的程序没有使用brpc,仍需要动态修改gflag(一般不需要),可以调用google::SetCommandLineOption(),如下所示:
```c++
#include
...
diff --git a/docs/cn/case_baidu_dsp.md b/docs/cn/case_baidu_dsp.md
index 359968063d..6d2c0b88e8 100644
--- a/docs/cn/case_baidu_dsp.md
+++ b/docs/cn/case_baidu_dsp.md
@@ -1,6 +1,6 @@
# 背景
-baidu-dsp是联盟基于Ad Exchange和RTB模式的需求方平台,服务大客户、代理的投放产品体系。我们改造了多个模块,均取得了显著的效果。本文只介绍其中关于super-nova-as的改动。super-nova-as是的baidu-dsp的AS,之前使用ub-aserver编写,为了尽量减少改动,我们没有改造整个as,而只是把super-nova-as连接下游(ctr-server、cvr-server、super-nova-bs)的client从ubrpc升级为baidu-rpc。
+baidu-dsp是联盟基于Ad Exchange和RTB模式的需求方平台,服务大客户、代理的投放产品体系。我们改造了多个模块,均取得了显著的效果。本文只介绍其中关于super-nova-as的改动。super-nova-as是的baidu-dsp的AS,之前使用ub-aserver编写,为了尽量减少改动,我们没有改造整个as,而只是把super-nova-as连接下游(ctr-server、cvr-server、super-nova-bs)的client从ubrpc升级为brpc。
# 结论
@@ -10,11 +10,11 @@ baidu-dsp是联盟基于Ad Exchange和RTB模式的需求方平台,服务大客
# 测试过程
-1. 环境:1个as,1个bs,1个ctr,1个cvr;部署情况为:bs单机部署,as+ctr+cvr混布;ctr和cvr为baidu-rpc版本
+1. 环境:1个as,1个bs,1个ctr,1个cvr;部署情况为:bs单机部署,as+ctr+cvr混布;ctr和cvr为brpc版本
2. 分别采用1000,1500压力对ubrpc版本的as进行压测,发现1500压力下,as对bs有大量的超时,as到达瓶颈;
-3. 分别采用2000,2500压力对baidu-rpc版本的as进行压测,发现2500压力下,as机器的cpu_idle低于30%,as到达瓶颈。baidu-rpc对资源利用充分。
+3. 分别采用2000,2500压力对brpc版本的as进行压测,发现2500压力下,as机器的cpu_idle低于30%,as到达瓶颈。brpc对资源利用充分。
-| | ubrpc | baidu-rpc |
+| | ubrpc | brpc |
| -------- | ---------------------------------------- | ---------------------------------------- |
| 流量 | ![img](../images/baidu_dsp_compare_1.png) | ![img](../images/baidu_dsp_compare_2.png) |
| bs成功率 | ![img](../images/baidu_dsp_compare_3.png) | ![img](../images/baidu_dsp_compare_4.png) |
diff --git a/docs/cn/case_elf.md b/docs/cn/case_elf.md
index 9c4713e6f8..57c268ab5f 100644
--- a/docs/cn/case_elf.md
+++ b/docs/cn/case_elf.md
@@ -1,6 +1,6 @@
# 背景
-ELF(Essential/Extreme/Excellent Learning Framework) 框架为公司内外的大数据应用提供学习/挖掘算法开发支持。 平台主要包括数据迭代处理的框架支持,并行计算过程中的通信支持和用于存储大规模参数的分布式、快速、高可用参数服务器。应用于fcr-model,公有云bml,大数据实验室,语音技术部门等等。之前是基于[zeromq](http://zeromq.org/)封装的rpc,这次改用baidu-rpc。
+ELF(Essential/Extreme/Excellent Learning Framework) 框架为公司内外的大数据应用提供学习/挖掘算法开发支持。 平台主要包括数据迭代处理的框架支持,并行计算过程中的通信支持和用于存储大规模参数的分布式、快速、高可用参数服务器。应用于fcr-model,公有云bml,大数据实验室,语音技术部门等等。之前是基于[zeromq](http://zeromq.org/)封装的rpc,这次改用brpc。
# 结论
diff --git a/docs/cn/case_ubprc.md b/docs/cn/case_ubprc.md
index 05058498c7..c20ec66d68 100644
--- a/docs/cn/case_ubprc.md
+++ b/docs/cn/case_ubprc.md
@@ -1,12 +1,12 @@
# 背景
-云平台部把使用ubrpc的模块改造为使用baidu-rpc。由于使用了mcpack2pb的转换功能,这个模块既能被老的ubrpc client访问,也可以通过protobuf类的协议访问(标准协议,sofa-pbrpc协议等等)。
+云平台部把使用ubrpc的模块改造为使用brpc。由于使用了mcpack2pb的转换功能,这个模块既能被老的ubrpc client访问,也可以通过protobuf类的协议访问(标准协议,sofa-pbrpc协议等等)。
下面是原报告。
-原有使用43台机器(对ubrpc也有富余),baidu-rpc使用3台机器即可(此时访问redis的io达到瓶颈)。当前流量4w qps,支持流量增长,考虑跨机房冗余,避免redis和vip瓶颈,baidu-rpc实际使用8台机器提供服务。
+原有使用43台机器(对ubrpc也有富余),brpc使用3台机器即可(此时访问redis的io达到瓶颈)。当前流量4w qps,支持流量增长,考虑跨机房冗余,避免redis和vip瓶颈,brpc实际使用8台机器提供服务。
-baidu-rpc改造后的connecter收益明显,可以用较少的机器提供更优质的服务。收益分3个方面:
+brpc改造后的connecter收益明显,可以用较少的机器提供更优质的服务。收益分3个方面:
# 相同配置的机器qps和latency的比较
@@ -18,7 +18,7 @@ baidu-rpc改造后的connecter收益明显,可以用较少的机器提供更
混布情况:同机部署了逻辑层2.0/3.0和C逻辑层,均有流量
图中可以看到随着压力的增大:
-* baidu-rpc的延时,增加微乎其微,提供了较为一致的延时体验
+* brpc的延时,增加微乎其微,提供了较为一致的延时体验
* ubrpc的延时,快速增大,到了6000~8000qps的时候,出现*queue full*,服务不可用。
# 不同配置机器qps和延时的比较
@@ -27,13 +27,13 @@ qps固定为6500,观察延时。
| --------- | ---------------------------------------- | ---------------------------------------- |
| cpu | 24 Intel(R) Xeon(R) CPU E5645 @ 2.40GHz | 24 Intel(R) Xeon(R) CPU E5-2620 0 @ 2.00GHz |
| ubrpc | 8363.46(us) | 12649.5(us) |
-| baidu-rpc | 3364.66(us) | 3382.15(us) |
+| brpc | 3364.66(us) | 3382.15(us) |
有此可见:
* ubrpc在不同配置下性能表现差异大,在配置较低的机器下表现较差。
-* baidu-rpc表现的比ubrpc好,在较低配置的机器上也能有好的表现,因机器不同带来的差异不大。
+* brpc表现的比ubrpc好,在较低配置的机器上也能有好的表现,因机器不同带来的差异不大。
# 相同配置机器idle分布的比较
@@ -44,4 +44,4 @@ qps固定为6500,观察延时。
在线上缩容 不断增大压力过程中:
* ubrpc cpu idle分布在35%~60%,在55%最集中,最低30%;
-* baidu-rpc cpu idle分布在60%~85%,在75%最集中,最低50%; baidu-rpc比ubrpc对cpu的消耗低。
+* brpc cpu idle分布在60%~85%,在75%最集中,最低50%; brpc比ubrpc对cpu的消耗低。
diff --git a/docs/cn/client.md b/docs/cn/client.md
index fa4f198cd9..a30aaeed51 100644
--- a/docs/cn/client.md
+++ b/docs/cn/client.md
@@ -1,8 +1,8 @@
-Client指发起请求的一端,在baidu-rpc中没有对应的实体,取而代之的是[brpc::Channel](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/brpc/channel.h),它代表和一台或一组服务器的交互通道,Client和Channel在角色上的差别在实践中并不重要,你可以把Channel视作Client。
+Client指发起请求的一端,在brpc中没有对应的实体,取而代之的是[brpc::Channel](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/brpc/channel.h),它代表和一台或一组服务器的交互通道,Client和Channel在角色上的差别在实践中并不重要,你可以把Channel视作Client。
Channel可以被进程中的所有线程共用,你不需要为每个线程创建独立的Channel,也不需要用锁互斥。不过Channel的创建和析构并不是线程安全的,请确保在Init成功后再被多线程访问,在没有线程访问后再析构。
-一些RPC实现中有RpcClient的概念,包含了Client端的配置信息和资源管理。baidu-rpc不需要这些,以往在RpcClient中配置的线程数、长短连接等等要么被加入了Channel,要么可以通过gflags全局配置,这么做的好处:
+一些RPC实现中有RpcClient的概念,包含了Client端的配置信息和资源管理。brpc不需要这些,以往在RpcClient中配置的线程数、长短连接等等要么被加入了Channel,要么可以通过gflags全局配置,这么做的好处:
1. 方便。你不需要在创建Channel时传入RpcClient,也不需要存储RpcClient。以往不少代码需要传递RpcClient,比较麻烦。gflags使你无需写代码就能通过命令行或配置文件改变程序的行为。
2. 共用资源。比如server和channel可以共用后台线程。
@@ -146,7 +146,7 @@ locality-aware,优先选择延时低的下游,直到其延时高于其他机
发起RPC前需要设置Controller.set_request_code(),否则RPC会失败。request_code一般是请求中主键部分的32位哈希值,**不需要和负载均衡使用的哈希算法一致**。比如用c_murmurhash算法也可以用md5计算哈希值。
-[brpc/policy/hasher.h](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/brpc/policy/hasher.h)中包含了常用的hash函数。如果用std::string key代表请求的主键,controller.set_request_code(brpc::policy::MurmurHash32(key.data(), key.size()))就正确地设置了request_code。
+[brpc/policy/hasher.h](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/brpc/policy/hasher.h)中包含了常用的hash函数。如果用std::string key代表请求的主键,controller.set_request_code(brpc::policy::MurmurHash32(key.data(), key.size()))就正确地设置了request_code。
注意甄别请求中的“主键”部分和“属性”部分,不要为了偷懒或通用,就把请求的所有内容一股脑儿计算出哈希值,属性的变化会使请求的目的地发生剧烈的变化。另外也要注意padding问题,比如struct Foo { int32_t a; int64_t b; }在64位机器上a和b之间有4个字节的空隙,内容未定义,如果像hash(&foo, sizeof(foo))这样计算哈希值,结果就是未定义的,得把内容紧密排列或序列化后再算。
@@ -154,13 +154,13 @@ locality-aware,优先选择延时低的下游,直到其延时高于其他机
## 健康检查
-连接断开的server会被暂时隔离而不会被负载均衡算法选中,baidu-rpc会定期连接被隔离的server,间隔由参数-health_check_interval控制:
+连接断开的server会被暂时隔离而不会被负载均衡算法选中,brpc会定期连接被隔离的server,间隔由参数-health_check_interval控制:
| Name | Value | Description | Defined At |
| ------------------------- | ----- | ---------------------------------------- | ----------------------- |
| health_check_interval (R) | 3 | seconds between consecutive health-checkings | src/brpc/socket_map.cpp |
-一旦server被连接上,它会恢复为可用状态。如果在隔离过程中,server从名字服务中删除了,baidu-rpc也会停止连接尝试。
+一旦server被连接上,它会恢复为可用状态。如果在隔离过程中,server从名字服务中删除了,brpc也会停止连接尝试。
# 发起访问
@@ -230,7 +230,7 @@ request.set_foo(...);
cntl->set_timeout_ms(...);
stub.some_method(cntl, &request, response, google::protobuf::NewCallback(OnRPCDone, response, cntl));
```
-由于protobuf 3把NewCallback设置为私有,r32035后baidu-rpc把NewCallback独立于[src/brpc/callback.h](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/brpc/callback.h)。如果你的程序出现NewCallback相关的编译错误,把google::protobuf::NewCallback替换为brpc::NewCallback就行了。
+由于protobuf 3把NewCallback设置为私有,r32035后brpc把NewCallback独立于[src/brpc/callback.h](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/brpc/callback.h)。如果你的程序出现NewCallback相关的编译错误,把google::protobuf::NewCallback替换为brpc::NewCallback就行了。
### 继承google::protobuf::Closure
@@ -352,7 +352,7 @@ brpc::StartCancel(CallId)可取消任意RPC,CallId必须**在发起RPC前**通
## 获取Server的地址和端口
-remote_side()方法可知道request被送向了哪个server,返回值类型是[base::EndPoint](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/base/endpoint.h),包含一个ip4地址和端口。在RPC结束前调用这个方法都是没有意义的。
+remote_side()方法可知道request被送向了哪个server,返回值类型是[base::EndPoint](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/base/endpoint.h),包含一个ip4地址和端口。在RPC结束前调用这个方法都是没有意义的。
打印方式:
```c++
@@ -395,8 +395,8 @@ for (int i = 0; i < n; ++i) {
Client端的设置主要由三部分组成:
-- brpc::ChannelOptions: 定义在[src/brpc/channel.h](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/brpc/channel.h)中,用于初始化Channel,一旦初始化成功无法修改。
-- brpc::Controller: 定义在[src/brpc/controller.h](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/brpc/controller.h)中,用于在某次RPC中覆盖ChannelOptions中的选项,可根据上下文每次均不同。
+- brpc::ChannelOptions: 定义在[src/brpc/channel.h](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/brpc/channel.h)中,用于初始化Channel,一旦初始化成功无法修改。
+- brpc::Controller: 定义在[src/brpc/controller.h](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/brpc/controller.h)中,用于在某次RPC中覆盖ChannelOptions中的选项,可根据上下文每次均不同。
- 全局gflags:常用于调节一些底层代码的行为,一般不用修改。请自行阅读服务/flags页面中的说明。
Controller包含了request中没有的数据和选项。server端和client端的Controller结构体是一样的,但使用的字段可能是不同的,你需要仔细阅读Controller中的注释,明确哪些字段可以在server端使用,哪些可以在client端使用。
@@ -417,7 +417,7 @@ Controller的特点:
**ChannelOptions.connect_timeout_ms**是对应Channel上一次RPC的连接超时,单位毫秒,默认值1秒。-1表示等到连接建立或出错,此值被限制为不能超过timeout_ms。注意此超时独立于TCP的连接超时,一般来说前者小于后者,反之则可能在connect_timeout_ms未达到前由于TCP连接超时而出错。
-注意1:baidu-rpc中的超时是deadline,超过就意味着RPC结束。UB/hulu中的超时既有单次访问的,也有代表deadline的。迁移到baidu-rpc时请仔细区分。
+注意1:brpc中的超时是deadline,超过就意味着RPC结束。UB/hulu中的超时既有单次访问的,也有代表deadline的。迁移到brpc时请仔细区分。
注意2:r31711后超时的错误码为**ERPCTIMEDOUT (1008)**,ETIMEDOUT的意思是连接超时。r31711前,超时的错误码是ETIMEDOUT (110)。原因:RPC内很早就区分了这两者,但考虑到linux下的使用习惯,在RPC结束前把ERPCTIMEDOUT改为了ETIMEDOUT。使用中我们逐渐发现不管是RPC内部实现(比如组合channel)还是一些用户场景都需要区分RPC超时和连接超时,综合考虑后决定不再合并这两个错误。如果你的程序中有诸如cntl->ErrorCode() == ETIMEDOUT的代码,你考虑下这里到底是否用对了,如果其实是在判RPC超时的话,得改成ERPCTIMEDOUT。
@@ -453,9 +453,9 @@ Controller.set_max_retry()或ChannelOptions.max_retry设置最大重试次数,
一些错误重试是没有意义的,就不会重试,比如请求有错时(EREQUEST)不会重试,因为server总不会接受。
-r32009后用户可以通过继承[brpc::RetryPolicy](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/brpc/retry_policy.h)自定义重试条件。r34642后通过cntl->response()可获得对应RPC的response。对ERPCTIMEDOUT代表的RPC超时总是不重试,即使RetryPolicy中允许。
+r32009后用户可以通过继承[brpc::RetryPolicy](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/brpc/retry_policy.h)自定义重试条件。r34642后通过cntl->response()可获得对应RPC的response。对ERPCTIMEDOUT代表的RPC超时总是不重试,即使RetryPolicy中允许。
-比如baidu-rpc默认不重试HTTP相关的错误,而你的程序中希望在碰到HTTP_STATUS_FORBIDDEN (403)时重试,可以这么做:
+比如brpc默认不重试HTTP相关的错误,而你的程序中希望在碰到HTTP_STATUS_FORBIDDEN (403)时重试,可以这么做:
```c++
#include
@@ -495,8 +495,8 @@ Channel的默认协议是标准协议,可通过设置ChannelOptions.protocol
- PROTOCOL_SOFA_PBRPC 或 "sofa_pbrpc",sofa-pbrpc的协议,默认为单连接。
- PROTOCOL_PUBLIC_PBRPC 或 "public_pbrpc",public/pbrpc的协议,默认为连接池。
- PROTOCOL_UBRPC_COMPACK 或 "ubrpc_compack",public/ubrpc的协议,使用compack打包,默认为连接池。具体方法见[ubrpc (by protobuf)](ub_client.md)。相关的还有PROTOCOL_UBRPC_MCPACK2或ubrpc_mcpack2,使用mcpack2打包。
-- PROTOCOL_NSHEAD_CLIENT 或 "nshead_client",这是发送baidu-rpc-ub中所有UBXXXRequest需要的协议,默认为连接池。具体方法见[访问ub](ub_client.md)。
-- PROTOCOL_NSHEAD 或 "nshead",这是baidu-rpc中发送NsheadMessage需要的协议,默认为连接池。注意发送NsheadMessage的效果等同于发送baidu-rpc-ub中的UBRawBufferRequest,但更加方便一点。具体方法见[nshead+blob](ub_client.md#nshead-blob) 。
+- PROTOCOL_NSHEAD_CLIENT 或 "nshead_client",这是发送brpc-ub中所有UBXXXRequest需要的协议,默认为连接池。具体方法见[访问ub](ub_client.md)。
+- PROTOCOL_NSHEAD 或 "nshead",这是brpc中发送NsheadMessage需要的协议,默认为连接池。注意发送NsheadMessage的效果等同于发送brpc-ub中的UBRawBufferRequest,但更加方便一点。具体方法见[nshead+blob](ub_client.md#nshead-blob) 。
- PROTOCOL_MEMCACHE 或 "memcache",memcached的二进制协议,默认为单连接。具体方法见[访问memcached](memcache_client.md)。
- PROTOCOL_REDIS 或 "redis",redis 1.2后的协议(也是hiredis支持的协议),默认为单连接。具体方法见[访问Redis](redis_client.md)。
- PROTOCOL_ITP 或 "itp", 凤巢的协议,格式为nshead + control idl + user idl,使用mcpack2pb适配,默认为连接池。具体方法见[访问ITP](itp.md)。
@@ -505,7 +505,7 @@ Channel的默认协议是标准协议,可通过设置ChannelOptions.protocol
## 连接方式
-baidu-rpc支持以下连接方式:
+brpc支持以下连接方式:
- 短连接:每次RPC call前建立连接,结束后关闭连接。由于每次调用得有建立连接的开销,这种方式一般用于偶尔发起的操作,而不是持续发起请求的场景。
- 连接池:每次RPC call前取用空闲连接,结束后归还,一个连接上最多只有一个请求,对一台server可能有多条连接。各类使用nshead的协议和http 1.1都是这个方式。
@@ -533,7 +533,7 @@ baidu-rpc支持以下连接方式:
- 设置为“”(空字符串)则让框架选择协议对应的默认连接方式。
-r31468之后baidu-rpc支持[Streaming RPC](streaming_rpc.md),这是一种应用层的连接,用于传递流式数据。
+r31468之后brpc支持[Streaming RPC](streaming_rpc.md),这是一种应用层的连接,用于传递流式数据。
## 关闭连接池中的闲置连接
@@ -548,7 +548,7 @@ r31468之后baidu-rpc支持[Streaming RPC](streaming_rpc.md),这是一种应
多个channel可能通过引用计数引用同一个连接,当引用某个连接的最后一个channel析构时,该连接将被关闭。但在一些场景中,channel在使用前才被创建,用完立刻析构,这时其中一些连接就会被无谓地关闭再被打开,效果类似短连接。
-一个解决办法是用户把所有或常用的channel缓存下来,这样自然能避免channel频繁产生和析构,但目前baidu-rpc没有提供这样一个utility,用户自己(正确)实现有一些工作量。
+一个解决办法是用户把所有或常用的channel缓存下来,这样自然能避免channel频繁产生和析构,但目前brpc没有提供这样一个utility,用户自己(正确)实现有一些工作量。
另一个解决办法是设置全局选项-defer_close_second
@@ -649,7 +649,7 @@ set_request_compress_type()设置request的压缩方式,默认不压缩。注
# FAQ
-### Q: baidu-rpc能用unix domain socket吗
+### Q: brpc能用unix domain socket吗
不能。因为同机socket并不走网络,相比domain socket性能只会略微下降,替换为domain socket意义不大。以后可能会扩展支持。
@@ -697,7 +697,7 @@ struct ChannelOptions {
### Q: Invalid address=`bns://group.user-persona.dumi.nj03'是什么意思
```
-FATAL 04-07 20:00:03 7778 public/baidu-rpc/src/brpc/channel.cpp:123] Invalid address=`bns://group.user-persona.dumi.nj03'. You should use Init(naming_service_name, load_balancer_name, options) to access multiple servers.
+FATAL 04-07 20:00:03 7778 public/brpc/src/brpc/channel.cpp:123] Invalid address=`bns://group.user-persona.dumi.nj03'. You should use Init(naming_service_name, load_balancer_name, options) to access multiple servers.
```
访问bns要使用三个参数的Init,它第二个参数是load_balancer_name,而你这里用的是两个参数的Init,框架当你是访问单点,就会报这个错。
diff --git a/docs/cn/combo_channel.md b/docs/cn/combo_channel.md
index d9709b289a..30b6d55f56 100644
--- a/docs/cn/combo_channel.md
+++ b/docs/cn/combo_channel.md
@@ -15,11 +15,11 @@ ParallelChannel (“pchan”)同时访问其包含的sub channel,并合并它
- 可以取消。
- 支持超时。
-示例代码见[example/parallel_echo_c++](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/tree/example/parallel_echo_c++/)。
+示例代码见[example/parallel_echo_c++](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/tree/example/parallel_echo_c++/)。
任何brpc::ChannelBase的子类都可以加入ParallelChannel,包括ParallelChannel和其他组合Channel。用户可以设置ParallelChannelOptions.fail_limit来控制访问的最大失败次数(r31803前是ParallelChannel::set_fail_limit),当失败的访问达到这个数目时,RPC call会立刻结束而不等待超时。
-当baidu-rpc >= 1.0.155.31351时,一个sub channel可多次加入同一个ParallelChannel。当你需要对同一个服务发起多次异步访问并等待它们完成的话,这很有用。
+当brpc >= 1.0.155.31351时,一个sub channel可多次加入同一个ParallelChannel。当你需要对同一个服务发起多次异步访问并等待它们完成的话,这很有用。
ParallelChannel的内部结构大致如下:
@@ -36,13 +36,13 @@ int AddChannel(brpc::ChannelBase* sub_channel,
ResponseMerger* response_merger);
```
-当ownership为brpc::OWNS_CHANNEL时,sub_channel会在ParallelChannel析构时被删除。当baidu-rpc >= 1.0.155.31351时,由于一个sub channel可能会多次加入一个ParallelChannel,只要其中一个指明了ownership为brpc::OWNS_CHANNEL,那个sub channel就会在ParallelChannel析构时被删除(一次)。
+当ownership为brpc::OWNS_CHANNEL时,sub_channel会在ParallelChannel析构时被删除。当brpc >= 1.0.155.31351时,由于一个sub channel可能会多次加入一个ParallelChannel,只要其中一个指明了ownership为brpc::OWNS_CHANNEL,那个sub channel就会在ParallelChannel析构时被删除(一次)。
访问ParallelChannel时调用AddChannel是线程**不安全**的。
## CallMapper
-用于把对ParallelChannel的调用转化为对sub channel的调用。如果call_mapper是NULL,sub channel的请求就是ParallelChannel的请求,而response则New()自ParallelChannel的response。如果call_mapper不为NULL,则会在ParallelChannel析构时被删除。当baidu-rpc >= 1.0.105.30846时,call_mapper内含引用计数,一个call_mapper可与多个sub channel关联。
+用于把对ParallelChannel的调用转化为对sub channel的调用。如果call_mapper是NULL,sub channel的请求就是ParallelChannel的请求,而response则New()自ParallelChannel的response。如果call_mapper不为NULL,则会在ParallelChannel析构时被删除。当brpc >= 1.0.105.30846时,call_mapper内含引用计数,一个call_mapper可与多个sub channel关联。
```c++
class CallMapper {
@@ -148,14 +148,14 @@ const Controller* sub(int index) const;
# SelectiveChannel
-[SelectiveChannel](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/brpc/selective_channel.h) (“schan”)按负载均衡算法访问其包含的一个Channel,相比普通Channel它更加高层:把流量分给sub channel,而不是具体的Server。SelectiveChannel主要用来支持机器组之间的负载均衡,它具备Channel的主要属性:
+[SelectiveChannel](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/brpc/selective_channel.h) (“schan”)按负载均衡算法访问其包含的一个Channel,相比普通Channel它更加高层:把流量分给sub channel,而不是具体的Server。SelectiveChannel主要用来支持机器组之间的负载均衡,它具备Channel的主要属性:
- 支持同步和异步访问。
- 发起异步操作后可以立刻删除。
- 可以取消。
- 支持超时。
-示例代码见[example/selective_echo_c++](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/tree/example/selective_echo_c++/)。
+示例代码见[example/selective_echo_c++](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/tree/example/selective_echo_c++/)。
任何brpc::ChannelBase的子类都可加入SelectiveChannel,包括SelectiveChannel和其他组合Channel。
@@ -240,9 +240,9 @@ stub.FooMethod(&cntl, &request, &response, NULL);
# PartitionChannel
-[PartitionChannel](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/brpc/partition_channel.h)是特殊的ParallelChannel,它会根据名字服务中的tag自动建立对应分库的sub channel。这样用户就可以把所有的分库机器挂在一个名字服务内,通过tag来指定哪台机器对应哪个分库。示例代码见[example/partition_echo_c++](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/tree/example/partition_echo_c++/)。
+[PartitionChannel](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/brpc/partition_channel.h)是特殊的ParallelChannel,它会根据名字服务中的tag自动建立对应分库的sub channel。这样用户就可以把所有的分库机器挂在一个名字服务内,通过tag来指定哪台机器对应哪个分库。示例代码见[example/partition_echo_c++](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/tree/example/partition_echo_c++/)。
-ParititonChannel只能处理一种分库方法,当用户需要多种分库方法共存,或从一个分库方法平滑地切换为另一种分库方法时,可以使用DynamicPartitionChannel,它会根据不同的分库方式动态地建立对应的sub PartitionChannel,并根据容量把请求分配给不同的分库。示例代码见[example/dynamic_partition_echo_c++](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/tree/example/dynamic_partition_echo_c++/)。
+ParititonChannel只能处理一种分库方法,当用户需要多种分库方法共存,或从一个分库方法平滑地切换为另一种分库方法时,可以使用DynamicPartitionChannel,它会根据不同的分库方式动态地建立对应的sub PartitionChannel,并根据容量把请求分配给不同的分库。示例代码见[example/dynamic_partition_echo_c++](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/tree/example/dynamic_partition_echo_c++/)。
如果分库在不同的名字服务内,那么用户得自行用ParallelChannel组装,即每个sub channel对应一个分库(使用不同的名字服务)。ParellelChannel的使用方法请见上一节。
diff --git a/docs/cn/contention_profiler.md b/docs/cn/contention_profiler.md
index 361524f017..bc1f4c0cfc 100644
--- a/docs/cn/contention_profiler.md
+++ b/docs/cn/contention_profiler.md
@@ -1,14 +1,14 @@
-baidu-rpc可以分析花在等待锁上的时间及发生等待的函数。
+brpc可以分析花在等待锁上的时间及发生等待的函数。
# 开启方法
-按需开启。无需配置,不依赖tcmalloc,不需要链接frame pointer或libunwind。如果只是baidu-rpc client或没有使用baidu-rpc,看[这里](dummy_server.md)。
+按需开启。无需配置,不依赖tcmalloc,不需要链接frame pointer或libunwind。如果只是brpc client或没有使用brpc,看[这里](dummy_server.md)。
# 图示
当很多线程争抢同一把锁时,一些线程无法立刻获得锁,而必须睡眠直到某个线程退出临界区。这个争抢过程我们称之为**contention**。在多核机器上,当多个线程需要操作同一个资源却被一把锁挡住时,便无法充分发挥多个核心的并发能力。现代OS通过提供比锁更底层的同步原语,使得无竞争锁完全不需要系统调用,只是一两条wait-free,耗时10-20ns的原子操作,非常快。而锁一旦发生竞争,一些线程就要陷入睡眠,再次醒来触发了OS的调度代码,代价至少为3-5us。所以让锁尽量无竞争,让所有线程“一起飞”是需要高性能的server的永恒话题。
-r31906后baidu-rpc支持contention profiler,可以分析在等待锁上花费了多少时间。等待过程中线程是睡着的不会占用CPU,所以contention profiler中的时间并不是cpu时间,也不会出现在[cpu profiler](cpu_profiler.md)中。cpu profiler可以抓到特别频繁的锁(以至于花费了很多cpu),但耗时真正巨大的临界区往往不是那么频繁,而无法被cpu profiler发现。**contention profiler和cpu profiler好似互补关系,前者分析等待时间(被动),后者分析忙碌时间。**还有一类由用户基于condition或sleep发起的主动等待时间,无需分析。
+r31906后brpc支持contention profiler,可以分析在等待锁上花费了多少时间。等待过程中线程是睡着的不会占用CPU,所以contention profiler中的时间并不是cpu时间,也不会出现在[cpu profiler](cpu_profiler.md)中。cpu profiler可以抓到特别频繁的锁(以至于花费了很多cpu),但耗时真正巨大的临界区往往不是那么频繁,而无法被cpu profiler发现。**contention profiler和cpu profiler好似互补关系,前者分析等待时间(被动),后者分析忙碌时间。**还有一类由用户基于condition或sleep发起的主动等待时间,无需分析。
目前contention profiler支持pthread_mutex_t(非递归)和bthread_mutex_t,开启后每秒最多采集1000个竞争锁,这个数字由参数-bvar_collector_expected_per_second控制(同时影响rpc_dump)。
diff --git a/docs/cn/cpu_profiler.md b/docs/cn/cpu_profiler.md
index fa04a9fc54..28094c1656 100644
--- a/docs/cn/cpu_profiler.md
+++ b/docs/cn/cpu_profiler.md
@@ -1,4 +1,4 @@
-baidu-rpc可以分析程序中的热点函数。
+brpc可以分析程序中的热点函数。
# 开启方法
@@ -6,7 +6,7 @@ baidu-rpc可以分析程序中的热点函数。
1. 这么写也开启了tcmalloc,不建议单独链接cpu profiler而不链接tcmalloc,可能越界访问导致[crash](https://github.com/gperftools/gperftools/blob/master/README#L226)**。**可能由于tcmalloc不及时归还内存,越界访问不会crash。
2. 如果tcmalloc使用frame pointer而不是libunwind回溯栈,请确保在CXXFLAGS或CFLAGS中加上`-fno-omit-frame-pointer`,否则函数间的调用关系会丢失,最后产生的图片中都是彼此独立的函数方框。
2. 定义宏BRPC_ENABLE_CPU_PROFILER。在COMAKE中加入`CXXFLAGS('-DBRPC_ENABLE_CPU_PROFILER')`
-3. 如果只是baidu-rpc client或没有使用baidu-rpc,看[这里](dummy_server.md)。
+3. 如果只是brpc client或没有使用brpc,看[这里](dummy_server.md)。
注意要关闭Server端的认证,否则可能会看到这个:
@@ -38,7 +38,7 @@ cpu profiler的原理是在定期被调用的SIGPROF handler中采样所在线
![img](../images/echo_cpu_profiling.png)
-你也可以使用[pprof](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/tools/pprof)或gperftools中的pprof进行profiling。
+你也可以使用[pprof](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/tools/pprof)或gperftools中的pprof进行profiling。
比如`pprof --text localhost:9002 --seconds=5`的意思是统计运行在本机9002端口的server的cpu情况,时长5秒。一次运行的例子如下:
diff --git a/docs/cn/dummy_server.md b/docs/cn/dummy_server.md
index db80327947..a43b60d6de 100644
--- a/docs/cn/dummy_server.md
+++ b/docs/cn/dummy_server.md
@@ -1,15 +1,15 @@
-如果你的程序只使用了baidu-rpc的client或根本没有使用baidu-rpc,但你也想使用baidu-rpc的内置服务,只要在程序中启动一个空的server就行了,这种server我们称为**dummy server**。
+如果你的程序只使用了brpc的client或根本没有使用brpc,但你也想使用brpc的内置服务,只要在程序中启动一个空的server就行了,这种server我们称为**dummy server**。
-# 使用了baidu-rpc的client
+# 使用了brpc的client
只要在程序运行目录建立dummy_server.port文件,填入一个端口号(比如8888),程序会马上在这个端口上启动一个dummy server。在浏览器中访问它的内置服务,便可看到同进程内的所有bvar。
![img](../images/dummy_server_1.png) ![img](../images/dummy_server_2.png)
![img](../images/dummy_server_3.png)
-# 没有使用baidu-rpc
+# 没有使用brpc
-你必须手动加入dummy server。你得先查看[Getting Started](getting_started.md)如何下载和编译baidu-rpc,然后在程序入口处加入如下代码片段:
+你必须手动加入dummy server。你得先查看[Getting Started](getting_started.md)如何下载和编译brpc,然后在程序入口处加入如下代码片段:
```c++
#include
diff --git a/docs/cn/error_code.md b/docs/cn/error_code.md
index 4c65731a9a..9fe657a748 100644
--- a/docs/cn/error_code.md
+++ b/docs/cn/error_code.md
@@ -1,23 +1,23 @@
-baidu-rpc使用[brpc::Controller](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/brpc/controller.h)设置一次RPC的参数和获取一次RPC的结果,ErrorCode()和ErrorText()是Controller的两个方法,分别是该次RPC的错误码和错误描述,只在RPC结束后才能访问,否则结果未定义。ErrorText()由Controller的基类google::protobuf::RpcController定义,ErrorCode()则是brpc::Controller定义的。Controller还有个Failed()方法告知该次RPC是否失败,这三者的关系是:
+brpc使用[brpc::Controller](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/brpc/controller.h)设置一次RPC的参数和获取一次RPC的结果,ErrorCode()和ErrorText()是Controller的两个方法,分别是该次RPC的错误码和错误描述,只在RPC结束后才能访问,否则结果未定义。ErrorText()由Controller的基类google::protobuf::RpcController定义,ErrorCode()则是brpc::Controller定义的。Controller还有个Failed()方法告知该次RPC是否失败,这三者的关系是:
- 当Failed()为true时,ErrorCode()一定不为0,ErrorText()是非空的错误描述
-- 当Failed()为false时,ErrorCode()一定为0,ErrorText()是未定义的(目前在baidu-rpc中会为空,但你最好不要依赖这个事实)
+- 当Failed()为false时,ErrorCode()一定为0,ErrorText()是未定义的(目前在brpc中会为空,但你最好不要依赖这个事实)
# 标记RPC为错误
-baidu-rpc的client端和server端都有Controller,都可以通过SetFailed()修改其中的ErrorCode和ErrorText。当多次调用一个Controller的SetFailed时,ErrorCode会被覆盖,ErrorText则是**添加**而不是覆盖,在client端,框架会额外加上第几次重试,在server端,框架会额外加上server的地址信息。
+brpc的client端和server端都有Controller,都可以通过SetFailed()修改其中的ErrorCode和ErrorText。当多次调用一个Controller的SetFailed时,ErrorCode会被覆盖,ErrorText则是**添加**而不是覆盖,在client端,框架会额外加上第几次重试,在server端,框架会额外加上server的地址信息。
client端Controller的SetFailed()常由框架调用,比如发送request失败,接收到的response不符合要求等等。只有在进行较复杂的访问操作时用户才可能需要设置client端的错误,比如在访问后端前做额外的请求检查,发现有错误时需要把RPC设置为失败。
server端Controller的SetFailed()常由用户在服务回调中调用。当处理过程发生错误时,一般调用SetFailed()并释放资源后就return了。框架会把错误码和错误信息按交互协议填入response,client端的框架收到后会填入它那边的Controller中,从而让用户在RPC结束后取到。需要注意的是,**server端在SetFailed()时一般不需要再打条日志。**打日志是比较慢的,在繁忙的线上磁盘上,很容易出现巨大的lag。一个错误频发的client容易减慢整个server的速度而影响到其他的client,理论上来说这甚至能成为一种攻击手段。对于希望在server端看到错误信息的场景,可以打开**-log_error_text**开关(已上线服务可访问/flags/log_error_text?setvalue=true动态打开),server会在每次失败的RPC后把对应Controller的ErrorText()打印出来。
-# baidu-rpc的错误码
+# brpc的错误码
-baidu-rpc使用的所有ErrorCode都定义在[errno.proto](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/brpc/errno.proto)中,*SYS_*开头的来自linux系统,与/usr/include/errno.h中定义的精确一致,定义在proto中是为了跨语言。其余的是baidu-rpc自有的。
+brpc使用的所有ErrorCode都定义在[errno.proto](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/brpc/errno.proto)中,*SYS_*开头的来自linux系统,与/usr/include/errno.h中定义的精确一致,定义在proto中是为了跨语言。其余的是brpc自有的。
-[berror(error_code)](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/base/errno.h)可获得error_code的描述,berror()可获得[system errno](http://www.cplusplus.com/reference/cerrno/errno/)的描述。**ErrorText() != berror(****ErrorCode())**,ErrorText()会包含更具体的错误信息。baidu-rpc默认包含berror,你可以直接使用。
+[berror(error_code)](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/base/errno.h)可获得error_code的描述,berror()可获得[system errno](http://www.cplusplus.com/reference/cerrno/errno/)的描述。**ErrorText() != berror(****ErrorCode())**,ErrorText()会包含更具体的错误信息。brpc默认包含berror,你可以直接使用。
-baidu-rpc中常见错误的打印内容列表如下:
+brpc中常见错误的打印内容列表如下:
diff --git a/docs/cn/execution_queue.md b/docs/cn/execution_queue.md
index f854013ddf..0f7062d700 100644
--- a/docs/cn/execution_queue.md
+++ b/docs/cn/execution_queue.md
@@ -1,6 +1,6 @@
# 概述
-类似于kylin的ExecMan, [ExecutionQueue](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/bthread/execution_queue.h)提供了异步串行执行的功能。ExecutionQueue的相关技术最早使用在RPC中实现[多线程向同一个fd写数据](io.md#发消息). 在r31345之后加入到bthread。 ExecutionQueue 提供了如下基本功能:
+类似于kylin的ExecMan, [ExecutionQueue](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/bthread/execution_queue.h)提供了异步串行执行的功能。ExecutionQueue的相关技术最早使用在RPC中实现[多线程向同一个fd写数据](io.md#发消息). 在r31345之后加入到bthread。 ExecutionQueue 提供了如下基本功能:
- 异步有序执行: 任务在另外一个单独的线程中执行, 并且执行顺序严格和提交顺序一致.
- Multi Producer: 多个线程可以同时向一个ExecutionQueue提交任务
diff --git a/docs/cn/flags.md b/docs/cn/flags.md
index 51cd7254e4..3a905d3da0 100644
--- a/docs/cn/flags.md
+++ b/docs/cn/flags.md
@@ -1,10 +1,10 @@
-baidu-rpc使用gflags管理配置。如果你的程序也使用gflags,那么你应该已经可以修改和baidu-rpc相关的flags,你可以浏览[flags服务](http://brpc.baidu.com:8765/flags)了解每个flag的具体功能。如果你的程序还没有使用gflags,我们建议你使用,原因如下:
+brpc使用gflags管理配置。如果你的程序也使用gflags,那么你应该已经可以修改和brpc相关的flags,你可以浏览[flags服务](http://brpc.baidu.com:8765/flags)了解每个flag的具体功能。如果你的程序还没有使用gflags,我们建议你使用,原因如下:
- 命令行和文件均可传入,前者方便做测试,后者适合线上运维。放在文件中的gflags可以reload。而configure只支持从文件读取配置。
-- 你可以在浏览器中查看baidu-rpc服务器中所有gflags,并对其动态修改(如果允许的话)。configure不可能做到这点。
+- 你可以在浏览器中查看brpc服务器中所有gflags,并对其动态修改(如果允许的话)。configure不可能做到这点。
- gflags分散在和其作用紧密关联的文件中,更好管理。而使用configure需要聚集到一个庞大的读取函数中。
-如果你依赖了baidu-rpc,那么你已经依赖了third-64/gflags,如果你需要依赖某个特定版本的话,在COMAKE中加入CONFIGS('third-64/gflags@')。
+如果你依赖了brpc,那么你已经依赖了third-64/gflags,如果你需要依赖某个特定版本的话,在COMAKE中加入CONFIGS('third-64/gflags@')。
# Usage of gflags
diff --git a/docs/cn/getting_started.md b/docs/cn/getting_started.md
index 13a4fb7940..b4c519c671 100644
--- a/docs/cn/getting_started.md
+++ b/docs/cn/getting_started.md
@@ -1,6 +1,6 @@
# BUILD
-baidu-rpc prefers static linking if possible, so that deps don't have to be installed on every
+brpc prefers static linking if possible, so that deps don't have to be installed on every
machine running the code.
## Ubuntu/LinuxMint/WSL
@@ -60,7 +60,7 @@ no known issues.
Be compatible with pb 3.0 and pb 2.x with the same file:
Don't use new types in proto3 and start the proto file with `syntax="proto2";`
-[tools/add_syntax_equal_proto2_to_all.sh](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/tools/add_syntax_equal_proto2_to_all.sh)can add `syntax="proto2"` to all proto files without it.
+[tools/add_syntax_equal_proto2_to_all.sh](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/tools/add_syntax_equal_proto2_to_all.sh)can add `syntax="proto2"` to all proto files without it.
protobuf 3.3-3.4 is not tested yet.
## gflags: 2.0-2.21
@@ -73,9 +73,9 @@ required by https.
## tcmalloc: 1.7-2.5
-baidu-rpc does **not** link [tcmalloc](http://goog-perftools.sourceforge.net/doc/tcmalloc.html) by default. Users link tcmalloc on-demand.
+brpc does **not** link [tcmalloc](http://goog-perftools.sourceforge.net/doc/tcmalloc.html) by default. Users link tcmalloc on-demand.
-Comparing to ptmalloc embedded in glibc, tcmalloc often improves performance. However different versions of tcmalloc may behave really differently. For example, tcmalloc 2.1 may make multi-threaded examples in baidu-rpc perform significantly worse(due to a spinlock in tcmalloc) than the one using tcmalloc 1.7 and 2.5. Even different minor versions may differ. When you program behave unexpectedly, remove tcmalloc or try another version.
+Comparing to ptmalloc embedded in glibc, tcmalloc often improves performance. However different versions of tcmalloc may behave really differently. For example, tcmalloc 2.1 may make multi-threaded examples in brpc perform significantly worse(due to a spinlock in tcmalloc) than the one using tcmalloc 1.7 and 2.5. Even different minor versions may differ. When you program behave unexpectedly, remove tcmalloc or try another version.
Code compiled with gcc 4.8.2 when linking to a tcmalloc compiled with earlier GCC may crash or deadlock before main(), E.g:
@@ -91,8 +91,8 @@ When you remove tcmalloc, not only remove the linking with tcmalloc but also the
## valgrind: 3.8+
-baidu-rpc detects valgrind automatically (and registers stacks of bthread). Older valgrind (say 3.2) is not supported.
+brpc detects valgrind automatically (and registers stacks of bthread). Older valgrind (say 3.2) is not supported.
# Track instances
-We provide a program to help you to track and monitor all baidu-rpc instances. Just run [trackme_server](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/tree/tools/trackme_server/) somewhere and launch need-to-be-tracked instances with -trackme_server=SERVER. The trackme_server will receive pings from instances periodically and print logs when it does. You can aggregate instance addresses from the log and call builtin services of the instances for further information.
+We provide a program to help you to track and monitor all brpc instances. Just run [trackme_server](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/tree/tools/trackme_server/) somewhere and launch need-to-be-tracked instances with -trackme_server=SERVER. The trackme_server will receive pings from instances periodically and print logs when it does. You can aggregate instance addresses from the log and call builtin services of the instances for further information.
diff --git a/docs/cn/heap_profiler.md b/docs/cn/heap_profiler.md
index ba01da5ed6..1bdddb2dfd 100644
--- a/docs/cn/heap_profiler.md
+++ b/docs/cn/heap_profiler.md
@@ -1,4 +1,4 @@
-baidu-rpc可以分析内存是被哪些函数占据的。heap profiler的原理是每分配满一些内存就采样调用处的栈,“一些”由环境变量TCMALLOC_SAMPLE_PARAMETER控制,默认524288,即512K字节。根据栈表现出的函数调用关系汇总为我们看到的结果图。在实践中heap profiler对原程序的影响不明显。
+brpc可以分析内存是被哪些函数占据的。heap profiler的原理是每分配满一些内存就采样调用处的栈,“一些”由环境变量TCMALLOC_SAMPLE_PARAMETER控制,默认524288,即512K字节。根据栈表现出的函数调用关系汇总为我们看到的结果图。在实践中heap profiler对原程序的影响不明显。
# 开启方法
@@ -18,7 +18,7 @@ baidu-rpc可以分析内存是被哪些函数占据的。heap profiler的原理
/home/gejun/pprof/echo_server.1419559063.localhost.pprof.heap: header size >= 2**16
```
-4. 如果只是baidu-rpc client或没有使用baidu-rpc,看[这里](dummy_server.md)。
+4. 如果只是brpc client或没有使用brpc,看[这里](dummy_server.md)。
注意要关闭Server端的认证,否则可能会看到这个:
@@ -54,7 +54,7 @@ WARNING: 12-26 10:01:25: * 0 [src/brpc/input_messenger.cpp:132][4294969345] Au
![img](../images/heap_profiler_3.gif)
-你也可以使用pprof脚本(public/baidu-rpc/tools/pprof)在命令行中查看文本格式结果:
+你也可以使用pprof脚本(public/brpc/tools/pprof)在命令行中查看文本格式结果:
```
$ tools/pprof --text db-rpc-dev00.db01:8765/pprof/heap
@@ -101,7 +101,7 @@ Total: 38.9 MB
0.0 0.0% 100.0% 3.5 9.0% std::string::_Rep::_S_create
```
-baidu-rpc还提供一个类似的growth profiler分析内存的分配去向(不考虑释放)。
+brpc还提供一个类似的growth profiler分析内存的分配去向(不考虑释放)。
![img](../images/growth_profiler.png)
diff --git a/docs/cn/http_client.md b/docs/cn/http_client.md
index 56869a17c8..5d0fdd2a06 100644
--- a/docs/cn/http_client.md
+++ b/docs/cn/http_client.md
@@ -1,4 +1,4 @@
-http client的例子见[example/http_c++](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/example/http_c++/http_client.cpp)
+http client的例子见[example/http_c++](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/example/http_c++/http_client.cpp)
# 创建Channel
@@ -31,7 +31,7 @@ HTTP和protobuf无关,所以除了Controller和done,CallMethod的其他参
# POST
-默认的HTTP Method为GET,如果需要做POST,则需要设置。待POST的数据应置入request_attachment(),它([base::IOBuf](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/base/iobuf.h))可以直接append std::string或char*
+默认的HTTP Method为GET,如果需要做POST,则需要设置。待POST的数据应置入request_attachment(),它([base::IOBuf](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/base/iobuf.h))可以直接append std::string或char*
```c++
brpc::Controller cntl;
@@ -153,7 +153,7 @@ Notes on http header:
# 解压response body
-出于通用性考虑且解压代码不复杂,baidu-rpc不会自动解压response body,用户可以自己做,方法如下:
+出于通用性考虑且解压代码不复杂,brpc不会自动解压response body,用户可以自己做,方法如下:
```c++
#include
@@ -172,9 +172,9 @@ if (encoding != NULL && *encoding == "gzip") {
# 持续下载
-r33796前baidu-rpc client在下载一个超长的body时,需要一直等待直到body完整才会视作RPC结束,这个过程中超长body都会存在内存中,如果body是无限长的(比如直播用的flv文件),那么内存会持续增长,直到超时。换句话说,r33796前的baidu-rpc client不适合下载大文件。
+r33796前brpc client在下载一个超长的body时,需要一直等待直到body完整才会视作RPC结束,这个过程中超长body都会存在内存中,如果body是无限长的(比如直播用的flv文件),那么内存会持续增长,直到超时。换句话说,r33796前的brpc client不适合下载大文件。
-r33796后baidu-rpc client支持在读取完body前就结束RPC,让用户在RPC结束后再读取持续增长的body。注意这个功能不等同于“支持http chunked mode”,baidu-rpc的http实现一直支持解析chunked mode,这里的问题是如何让用户处理超长或无限长的body,和body是否以chunked mode传输无关。
+r33796后brpc client支持在读取完body前就结束RPC,让用户在RPC结束后再读取持续增长的body。注意这个功能不等同于“支持http chunked mode”,brpc的http实现一直支持解析chunked mode,这里的问题是如何让用户处理超长或无限长的body,和body是否以chunked mode传输无关。
使用方法如下:
@@ -204,7 +204,7 @@ r33796后baidu-rpc client支持在读取完body前就结束RPC,让用户在RPC
OnReadOnePart在每读到一段数据时被调用,OnEndOfMessage在数据结束或连接断开时调用,实现前仔细阅读注释。
2. 发起RPC前设置`cntl.response_will_be_read_progressively();`
- 这告诉baidu-rpc在读取http response时只要读完header部分RPC就可以结束了。
+ 这告诉brpc在读取http response时只要读完header部分RPC就可以结束了。
3. RPC结束后调用`cntl.ReadProgressiveAttachmentBy(new MyProgressiveReader);`
MyProgressiveReader就是用户实现ProgressiveReader的实例。用户可以在这个实例的OnEndOfMessage接口中删除这个实例。
diff --git a/docs/cn/http_service.md b/docs/cn/http_service.md
index 38407238e9..14daf7866a 100644
--- a/docs/cn/http_service.md
+++ b/docs/cn/http_service.md
@@ -1,4 +1,4 @@
-这里特指“纯粹"的HTTP service,而不是可通过HTTP访问的pb服务。虽然用不到pb消息,但“纯粹”的HTTP Service也必须定义在.proto文件中,只是request和response都是空的结构体。这么做是确保所有的服务声明集中在proto文件中,而不是散列在.proto、程序、配置等多个地方。示例代码见[http_server.cpp](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/example/http_c++/http_server.cpp)。
+这里特指“纯粹"的HTTP service,而不是可通过HTTP访问的pb服务。虽然用不到pb消息,但“纯粹”的HTTP Service也必须定义在.proto文件中,只是request和response都是空的结构体。这么做是确保所有的服务声明集中在proto文件中,而不是散列在.proto、程序、配置等多个地方。示例代码见[http_server.cpp](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/example/http_c++/http_server.cpp)。
# URL前缀为/ServiceName/MethodName
@@ -106,7 +106,7 @@ public:
# Restful URL
-r32097后,baidu-rpc支持为service中的每个方法指定一个URL。接口如下:
+r32097后,brpc支持为service中的每个方法指定一个URL。接口如下:
```c++
// 如果restful_mappings不为空, service中的方法可通过指定的URL被HTTP协议访问,而不是/ServiceName/MethodName.
@@ -154,7 +154,7 @@ if (server.AddService(&queue_svc,
}
```
-上面代码中AddService的第三个参数分了三行,但实际上是一个字符串。这个字符串包含以逗号(,)分隔的三个映射关系,每个映射告诉baidu-rpc:在遇到箭头左侧的URL时调用右侧的方法。"/v1/queue/stats/*"中的星号可匹配任意字串。在r33521前星号只能加在URL最后。
+上面代码中AddService的第三个参数分了三行,但实际上是一个字符串。这个字符串包含以逗号(,)分隔的三个映射关系,每个映射告诉brpc:在遇到箭头左侧的URL时调用右侧的方法。"/v1/queue/stats/*"中的星号可匹配任意字串。在r33521前星号只能加在URL最后。
关于映射规则:
@@ -226,7 +226,7 @@ cntl->http_response().set_content_type("text/html");
## Status Code
-status code是http response特有的字段,标记http请求的完成情况。请使用定义在[http_status_code.h](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/brpc/http_status_code.h)中的enum,遵守HTTP协议。
+status code是http response特有的字段,标记http请求的完成情况。请使用定义在[http_status_code.h](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/brpc/http_status_code.h)中的enum,遵守HTTP协议。
```c++
// Get Status Code
@@ -250,7 +250,7 @@ cntl->http_response().SetHeader("Location", "http://bj.bs.bae.baidu.com/family/i
## Query String
-如上面的[HTTP headers](http_service.md#http-headers)中提到的那样,我们按约定成俗的方式来理解query string,即key1=value1&key2=value2&...。只有key而没有value也是可以的,仍然会被GetQuery查询到,只是值为空字符串,这常被用做bool型的开关。接口定义在[uri.h](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/brpc/uri.h)。
+如上面的[HTTP headers](http_service.md#http-headers)中提到的那样,我们按约定成俗的方式来理解query string,即key1=value1&key2=value2&...。只有key而没有value也是可以的,仍然会被GetQuery查询到,只是值为空字符串,这常被用做bool型的开关。接口定义在[uri.h](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/brpc/uri.h)。
```c++
const std::string* time_value = cntl->http_request().uri().GetQuery("time");
@@ -274,7 +274,7 @@ http服务常对http body进行压缩,对于文本网页可以有效减少传
# 解压request body
-出于通用性考虑且解压代码不复杂,baidu-rpc不会自动解压request body,用户可以自己做,方法如下:
+出于通用性考虑且解压代码不复杂,brpc不会自动解压request body,用户可以自己做,方法如下:
```c++
#include
@@ -340,14 +340,14 @@ bool Controller::is_ssl() const;
没有极端性能要求的产品线都有使用HTTP协议的倾向,特别是移动端产品线,所以我们很重视HTTP的实现质量,具体来说:
-- 使用了node.js的[http parser](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/brpc/details/http_parser.h)(部分来自nginx)解析http消息,这是一个轻量、优秀的实现。
+- 使用了node.js的[http parser](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/brpc/details/http_parser.h)(部分来自nginx)解析http消息,这是一个轻量、优秀的实现。
- 使用[rapidjson](https://github.com/miloyip/rapidjson)解析json,这是一个主打性能的json库,由一位腾讯专家开发。
- 在最差情况下解析http请求的时间复杂度也是O(N),其中N是请求的字节数。反过来说,如果解析代码要求http请求是完整的,那么它可能会花费O(N^2)的时间。HTTP请求普遍较大,这一点意义还是比较大的。
- 来自不同client的http消息是高度并发的,即使相当复杂的http消息也不会影响对其他客户端的响应。其他rpc和[基于单线程reactor](threading_overview.md#单线程reactor)的各类http server往往难以做到这一点。
# 持续发送
-r33796前baidu-rpc server不适合发送超大或无限长的body。r33796后baidu-rpc server支持。方法如下:
+r33796前brpc server不适合发送超大或无限长的body。r33796后brpc server支持。方法如下:
1. 调用Controller::CreateProgressiveAttachment()创建可持续发送的body。
`boost::intrusive_ptr pa(cntl->CreateProgressiveAttachment());`
@@ -358,17 +358,17 @@ r33796前baidu-rpc server不适合发送超大或无限长的body。r33796后bai
# 持续接收
-目前baidu-rpc server不支持在接受完http请求的header部分就调用用户的服务回调,即baidu-rpc server不适合接收超长或无限长的body。
+目前brpc server不支持在接受完http请求的header部分就调用用户的服务回调,即brpc server不适合接收超长或无限长的body。
# FAQ
-### Q: baidu-rpc前的nginx报了final fail (ff)
+### Q: brpc前的nginx报了final fail (ff)
-baidu-rpc server同端口支持多种协议,当它遇到非法HTTP请求并解析失败后,无法说这个请求一定是HTTP。在r31355之后,server会对query-string及之后出现解析错误的请求返回HTTP 400错误并关闭连接(因为有很大概率是HTTP请求),但如果是HTTP method错误,诸如出现GET、POST、HEAD等标准方法之外的东西或严重的格式错误(可能由HTTP client有bug导致),server仍会直接断开连接,导致nginx的ff。
+brpc server同端口支持多种协议,当它遇到非法HTTP请求并解析失败后,无法说这个请求一定是HTTP。在r31355之后,server会对query-string及之后出现解析错误的请求返回HTTP 400错误并关闭连接(因为有很大概率是HTTP请求),但如果是HTTP method错误,诸如出现GET、POST、HEAD等标准方法之外的东西或严重的格式错误(可能由HTTP client有bug导致),server仍会直接断开连接,导致nginx的ff。
解决方案: 在使用Nginx转发流量时,可以对$HTTP_method做一下过滤,只放行允许的方法。或者干脆在proxy时设置proxy_method为指定方法,来避免ff。
-### Q: baidu-rpc支持http chunked方式传输吗
+### Q: brpc支持http chunked方式传输吗
支持。
diff --git a/docs/cn/io.md b/docs/cn/io.md
index 18e7bf9df2..e174ef8a51 100644
--- a/docs/cn/io.md
+++ b/docs/cn/io.md
@@ -8,25 +8,25 @@ linux一般使用non-blocking IO提高IO并发度。当IO并发度很低时,no
# 收消息
-“消息”指从连接读入的有边界的二进制串,可能是来自上游client的request或来自下游server的response。baidu-rpc使用一个或多个[EventDispatcher](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/brpc/event_dispatcher.h)(简称为EDISP)等待任一fd发生事件。和常见的“IO线程”不同,EDISP不负责读取。IO线程的问题在于一个线程同时只能读一个fd,当多个繁忙的fd聚集在一个IO线程中时,一些读取就被延迟了。多租户、复杂分流算法,[Streaming RPC](streaming_rpc.md)等功能会加重这个问题。高负载下偶尔的长延时read也会拖慢一个IO线程中所有fd的读取,对可用性的影响幅度较大。
+“消息”指从连接读入的有边界的二进制串,可能是来自上游client的request或来自下游server的response。brpc使用一个或多个[EventDispatcher](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/brpc/event_dispatcher.h)(简称为EDISP)等待任一fd发生事件。和常见的“IO线程”不同,EDISP不负责读取。IO线程的问题在于一个线程同时只能读一个fd,当多个繁忙的fd聚集在一个IO线程中时,一些读取就被延迟了。多租户、复杂分流算法,[Streaming RPC](streaming_rpc.md)等功能会加重这个问题。高负载下偶尔的长延时read也会拖慢一个IO线程中所有fd的读取,对可用性的影响幅度较大。
-由于epoll的[一个bug](https://patchwork.kernel.org/patch/1970231/)及epoll_ctl较大的开销,EDISP使用Edge triggered模式。当收到事件时,EDISP给一个原子变量加1,只有当加1前的值是0时启动一个bthread处理对应fd上的数据。在背后,EDISP把所在的pthread让给了新建的bthread,使其有更好的cache locality,可以尽快地读取fd上的数据。而EDISP所在的bthread会被偷到另外一个pthread继续执行,这个过程即是bthread的work stealing调度。要准确理解那个原子变量的工作方式可以先阅读[atomic instructions](atomic_instructions.md),再看[Socket::StartInputEvent](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/brpc/socket.cpp)。这些方法使得baidu-rpc读取同一个fd时产生的竞争是[wait-free](http://en.wikipedia.org/wiki/Non-blocking_algorithm#Wait-freedom)的。
+由于epoll的[一个bug](https://patchwork.kernel.org/patch/1970231/)及epoll_ctl较大的开销,EDISP使用Edge triggered模式。当收到事件时,EDISP给一个原子变量加1,只有当加1前的值是0时启动一个bthread处理对应fd上的数据。在背后,EDISP把所在的pthread让给了新建的bthread,使其有更好的cache locality,可以尽快地读取fd上的数据。而EDISP所在的bthread会被偷到另外一个pthread继续执行,这个过程即是bthread的work stealing调度。要准确理解那个原子变量的工作方式可以先阅读[atomic instructions](atomic_instructions.md),再看[Socket::StartInputEvent](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/brpc/socket.cpp)。这些方法使得brpc读取同一个fd时产生的竞争是[wait-free](http://en.wikipedia.org/wiki/Non-blocking_algorithm#Wait-freedom)的。
-[InputMessenger](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/brpc/input_messenger.h)负责从fd上切割和处理消息,它通过用户回调函数理解不同的格式。Parse一般是把消息从二进制流上切割下来,运行时间较固定;Process则是进一步解析消息(比如反序列化为protobuf)后调用用户回调,时间不确定。InputMessenger会逐一尝试用户指定的多套回调,当某一个Parse成功切割下一个消息后,调用对应的Process。由于一个连接上往往只有一种消息格式,InputMessenger会记录下上次的选择,而避免每次都重复尝试。若一次从某个fd读取出n个消息(n > 1),InputMessenger会启动n-1个bthread分别处理前n-1个消息,最后一个消息则会在原地被Process。
+[InputMessenger](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/brpc/input_messenger.h)负责从fd上切割和处理消息,它通过用户回调函数理解不同的格式。Parse一般是把消息从二进制流上切割下来,运行时间较固定;Process则是进一步解析消息(比如反序列化为protobuf)后调用用户回调,时间不确定。InputMessenger会逐一尝试用户指定的多套回调,当某一个Parse成功切割下一个消息后,调用对应的Process。由于一个连接上往往只有一种消息格式,InputMessenger会记录下上次的选择,而避免每次都重复尝试。若一次从某个fd读取出n个消息(n > 1),InputMessenger会启动n-1个bthread分别处理前n-1个消息,最后一个消息则会在原地被Process。
-可以看到,fd间和fd内的消息都会在baidu-rpc中获得并发,这使baidu-rpc非常擅长大消息的读取,在高负载时仍能及时处理不同来源的消息,减少长尾的存在。
+可以看到,fd间和fd内的消息都会在brpc中获得并发,这使brpc非常擅长大消息的读取,在高负载时仍能及时处理不同来源的消息,减少长尾的存在。
# 发消息
-"消息”指向连接写出的有边界的二进制串,可能是发向上游client的response或下游server的request。多个线程可能会同时向一个fd发送消息,而写fd又是非原子的,所以如何高效率地排队不同线程写出的数据包是这里的关键。baidu-rpc使用一种wait-free MPSC链表来实现这个功能。所有待写出的数据都放在一个单链表节点中,next指针初始化为一个特殊值(Socket::WriteRequest::UNCONNECTED)。当一个线程想写出数据前,它先尝试和对应的链表头(Socket::_write_head)做原子交换,返回值是交换前的链表头。如果返回值为空,说明它获得了写出的权利,它会在原地写一次数据。否则说明有另一个线程在写,它把next指针指向返回的头,那样正在写的线程之后会看到并写出这块数据。这套方法可以让写竞争是wait-free的,而获得写权利的线程虽然在原理上不是wait-free也不是lock-free,可能会被一个值仍为UNCONNECTED的节点锁定(这需要发起写的线程正好在原子交换后,在设置next指针前,仅仅一条指令的时间内被OS换出),但在实践中很少出现。在当前的实现中,如果获得写权利的线程一下子无法写出所有的数据,会启动一个KeepWrite线程继续写,直到所有的数据都被写出。这套逻辑非常复杂,大致原理如下图,细节请阅读[socket.cpp](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/brpc/socket.cpp)。
+"消息”指向连接写出的有边界的二进制串,可能是发向上游client的response或下游server的request。多个线程可能会同时向一个fd发送消息,而写fd又是非原子的,所以如何高效率地排队不同线程写出的数据包是这里的关键。brpc使用一种wait-free MPSC链表来实现这个功能。所有待写出的数据都放在一个单链表节点中,next指针初始化为一个特殊值(Socket::WriteRequest::UNCONNECTED)。当一个线程想写出数据前,它先尝试和对应的链表头(Socket::_write_head)做原子交换,返回值是交换前的链表头。如果返回值为空,说明它获得了写出的权利,它会在原地写一次数据。否则说明有另一个线程在写,它把next指针指向返回的头,那样正在写的线程之后会看到并写出这块数据。这套方法可以让写竞争是wait-free的,而获得写权利的线程虽然在原理上不是wait-free也不是lock-free,可能会被一个值仍为UNCONNECTED的节点锁定(这需要发起写的线程正好在原子交换后,在设置next指针前,仅仅一条指令的时间内被OS换出),但在实践中很少出现。在当前的实现中,如果获得写权利的线程一下子无法写出所有的数据,会启动一个KeepWrite线程继续写,直到所有的数据都被写出。这套逻辑非常复杂,大致原理如下图,细节请阅读[socket.cpp](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/brpc/socket.cpp)。
![img](../images/write.png)
-由于baidu-rpc的写出总能很快地返回,调用线程可以更快地处理新任务,后台写线程也能每次拿到一批任务批量写出,在大吞吐时容易形成流水线效应而提高IO效率。
+由于brpc的写出总能很快地返回,调用线程可以更快地处理新任务,后台写线程也能每次拿到一批任务批量写出,在大吞吐时容易形成流水线效应而提高IO效率。
# Socket
-和fd相关的数据均在[Socket](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/brpc/socket.h)中,是rpc最复杂的结构之一,这个结构的独特之处在于用64位的SocketId指代Socket对象以方便在多线程环境下使用fd。常用的三个方法:
+和fd相关的数据均在[Socket](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/brpc/socket.h)中,是rpc最复杂的结构之一,这个结构的独特之处在于用64位的SocketId指代Socket对象以方便在多线程环境下使用fd。常用的三个方法:
- Create:创建Socket,并返回其SocketId。
- Address:取得id对应的Socket,包装在一个会自动释放的unique_ptr中(SocketUniquePtr),当Socket被SetFailed后,返回指针为空。只要Address返回了非空指针,其内容保证不会变化,直到指针自动析构。这个函数是wait-free的。
@@ -34,7 +34,7 @@ linux一般使用non-blocking IO提高IO并发度。当IO并发度很低时,no
可以看到Socket类似[shared_ptr](http://en.cppreference.com/w/cpp/memory/shared_ptr),SocketId类似[weak_ptr](http://en.cppreference.com/w/cpp/memory/weak_ptr),但Socket独有的SetFailed可以在需要时确保Socket不能被继续Address而最终引用计数归0,单纯使用shared_ptr/weak_ptr则无法保证这点,当一个server需要退出时,如果请求仍频繁地到来,对应Socket的引用计数可能迟迟无法清0而导致server无法退出。另外weak_ptr无法直接作为epoll的data,而SocketId可以。这些因素使我们设计了Socket,这个类的核心部分自14年10月完成后很少改动,非常稳定。
-存储SocketUniquePtr还是SocketId取决于是否需要强引用。像Controller贯穿了RPC的整个流程,和Socket中的数据有大量交互,它存放的是SocketUniquePtr。epoll主要是提醒对应fd上发生了事件,如果Socket回收了,那这个事件是可有可无的,所以它存放了SocketId。由于SocketUniquePtr只要有效,其中的数据就不会变,这个机制使用户不用关心麻烦的race conditon和ABA problem,可以放心地对共享的fd进行操作。这种方法也规避了隐式的引用计数,内存的ownership明确,程序的质量有很好的保证。baidu-rpc中有大量的SocketUniquePtr和SocketId,它们确实简化了我们的开发。
+存储SocketUniquePtr还是SocketId取决于是否需要强引用。像Controller贯穿了RPC的整个流程,和Socket中的数据有大量交互,它存放的是SocketUniquePtr。epoll主要是提醒对应fd上发生了事件,如果Socket回收了,那这个事件是可有可无的,所以它存放了SocketId。由于SocketUniquePtr只要有效,其中的数据就不会变,这个机制使用户不用关心麻烦的race conditon和ABA problem,可以放心地对共享的fd进行操作。这种方法也规避了隐式的引用计数,内存的ownership明确,程序的质量有很好的保证。brpc中有大量的SocketUniquePtr和SocketId,它们确实简化了我们的开发。
事实上,Socket不仅仅用于管理原生的fd,它也被用来管理其他资源。比如SelectiveChannel中的每个Sub Channel都被置入了一个Socket中,这样SelectiveChannel可以像普通channel选择下游server那样选择一个Sub Channel进行发送。这个假Socket甚至还实现了健康检查。Streaming RPC也使用了Socket以复用wait-free的写出过程。
diff --git a/docs/cn/iobuf.md b/docs/cn/iobuf.md
index 9faea204b3..511d0fbc6b 100644
--- a/docs/cn/iobuf.md
+++ b/docs/cn/iobuf.md
@@ -1,4 +1,4 @@
-baidu-rpc使用[base::IOBuf](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/base/iobuf.h)作为存储附件或http body的数据结构,它是一种非连续零拷贝缓冲,在其他项目中得到了验证并有出色的性能。IOBuf的接口和std::string类似,但不相同。
+brpc使用[base::IOBuf](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/base/iobuf.h)作为存储附件或http body的数据结构,它是一种非连续零拷贝缓冲,在其他项目中得到了验证并有出色的性能。IOBuf的接口和std::string类似,但不相同。
如果你之前使用Kylin中的BufHandle,你将更能感受到IOBuf的便利性:前者几乎没有实现完整,直接暴露了内部结构,用户得小心翼翼地处理引用计数,极易出错。BufHandle是很多bug的诱因。
diff --git a/docs/cn/lalb.md b/docs/cn/lalb.md
index cc667fb338..025bb288bd 100644
--- a/docs/cn/lalb.md
+++ b/docs/cn/lalb.md
@@ -1,6 +1,6 @@
# 概述
-LALB全称Locality-aware load balancing,是一个能把请求及时、自动地送到延时最低的下游的负载均衡算法,特别适合混合部署环境。该算法产生自DP系统,现已加入baidu-rpc!
+LALB全称Locality-aware load balancing,是一个能把请求及时、自动地送到延时最低的下游的负载均衡算法,特别适合混合部署环境。该算法产生自DP系统,现已加入brpc!
LALB可以解决的问题:
@@ -101,7 +101,7 @@ LoadBalancer是一个读远多于写的数据结构:大部分时候,所有
- 不同的读之间没有竞争,高度并发。
- 如果没有写,读总是能无竞争地获取和释放thread-local锁,一般小于25ns,对延时基本无影响。如果有写,由于其临界区极小(拿到立刻释放),读在大部分时候仍能快速地获得锁,少数时候释放锁时可能有唤醒写线程的代价。由于写本身就是少数情况,读整体上几乎不会碰到竞争锁。
-完成这些功能的数据结构是[DoublyBufferedData<>](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/base/containers/doubly_buffered_data.h),我们常简称为DBD。baidu-rpc中的所有load balancer都使用了这个数据结构,使不同线程在分流时几乎不会互斥。而其他rpc实现往往使用了全局锁,这使得它们无法写出复杂的分流算法:否则分流代码将会成为竞争热点。
+完成这些功能的数据结构是[DoublyBufferedData<>](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/base/containers/doubly_buffered_data.h),我们常简称为DBD。brpc中的所有load balancer都使用了这个数据结构,使不同线程在分流时几乎不会互斥。而其他rpc实现往往使用了全局锁,这使得它们无法写出复杂的分流算法:否则分流代码将会成为竞争热点。
这个结构有广泛的应用场景:
@@ -112,7 +112,7 @@ LoadBalancer是一个读远多于写的数据结构:大部分时候,所有
LALB的查找过程是按权值分流,O(N)方法如下:获得所有权值的和total,产生一个间于[0, total-1]的随机数R,逐个遍历权值,直到当前权值之和不大于R,而下一个权值之和大于R。
-这个方法可以工作,也好理解,但当N达到几百时性能已经很差,这儿的主要因素是cache一致性:LALB是一个基于反馈的算法,RPC结束时信息会被反馈入LALB,被遍历的数据结构也一直在被修改。这意味着前台的O(N)读必须刷新每一行cacheline。当N达到数百时,一次查找过程可能会耗时百微秒,更别提更大的N了,LALB(将)作为baidu-rpc的默认分流算法,这个性能开销是无法接受的。
+这个方法可以工作,也好理解,但当N达到几百时性能已经很差,这儿的主要因素是cache一致性:LALB是一个基于反馈的算法,RPC结束时信息会被反馈入LALB,被遍历的数据结构也一直在被修改。这意味着前台的O(N)读必须刷新每一行cacheline。当N达到数百时,一次查找过程可能会耗时百微秒,更别提更大的N了,LALB(将)作为brpc的默认分流算法,这个性能开销是无法接受的。
另一个办法是用完全二叉树。每个节点记录了左子树的权值之和,这样我们就能在O(logN)时间内完成查找。当N为1024时,我们最多跳转10次内存,总耗时可控制在1微秒内,这个性能是可接受的。这个方法的难点是如何和DoublyBufferedData结合。
diff --git a/docs/cn/load_balancing.md b/docs/cn/load_balancing.md
index 1ddac24bf7..fa6a13d65b 100644
--- a/docs/cn/load_balancing.md
+++ b/docs/cn/load_balancing.md
@@ -2,10 +2,10 @@
# 名字服务
-在baidu-rpc中,[NamingService](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/brpc/naming_service.h)用于获得服务名对应的所有节点。一个直观的做法是定期调用一个函数以获取最新的节点列表。但这会带来一定的延时(定期调用的周期一般在若干秒左右),作为通用接口不太合适。特别当名字服务提供事件通知时(比如zk),这个特性没有被利用。所以我们反转了控制权:不是我们调用用户函数,而是用户在获得列表后调用我们的接口,对应[NamingServiceActions](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/brpc/naming_service.h)。当然我们还是得启动进行这一过程的函数,对应NamingService::RunNamingService。下面以三个实现解释这套方式:
+在brpc中,[NamingService](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/brpc/naming_service.h)用于获得服务名对应的所有节点。一个直观的做法是定期调用一个函数以获取最新的节点列表。但这会带来一定的延时(定期调用的周期一般在若干秒左右),作为通用接口不太合适。特别当名字服务提供事件通知时(比如zk),这个特性没有被利用。所以我们反转了控制权:不是我们调用用户函数,而是用户在获得列表后调用我们的接口,对应[NamingServiceActions](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/brpc/naming_service.h)。当然我们还是得启动进行这一过程的函数,对应NamingService::RunNamingService。下面以三个实现解释这套方式:
-- bns:没有事件通知,所以我们只能定期去获得最新列表,默认间隔是[5秒](http://brpc.baidu.com:8765/flags/ns_access_interval)。为了简化这类定期获取的逻辑,baidu-rpc提供了[PeriodicNamingService](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/brpc/periodic_naming_service.h) 供用户继承,用户只需要实现单次如何获取(GetServers)。获取后调用NamingServiceActions::ResetServers告诉框架。框架会对列表去重,和之前的列表比较,通知对列表有兴趣的观察者(NamingServiceWatcher)。这套逻辑会运行在独立的bthread中,即NamingServiceThread。一个NamingServiceThread可能被多个Channel共享,通过intrusive_ptr管理ownership。
-- file:列表即文件。合理的方式是在文件更新后重新读取。[该实现](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/brpc/policy/file_naming_service.cpp)使用[FileWatcher](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/base/files/file_watcher.h)关注文件的修改时间,当文件修改后,读取并调用NamingServiceActions::ResetServers告诉框架。
+- bns:没有事件通知,所以我们只能定期去获得最新列表,默认间隔是[5秒](http://brpc.baidu.com:8765/flags/ns_access_interval)。为了简化这类定期获取的逻辑,brpc提供了[PeriodicNamingService](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/brpc/periodic_naming_service.h) 供用户继承,用户只需要实现单次如何获取(GetServers)。获取后调用NamingServiceActions::ResetServers告诉框架。框架会对列表去重,和之前的列表比较,通知对列表有兴趣的观察者(NamingServiceWatcher)。这套逻辑会运行在独立的bthread中,即NamingServiceThread。一个NamingServiceThread可能被多个Channel共享,通过intrusive_ptr管理ownership。
+- file:列表即文件。合理的方式是在文件更新后重新读取。[该实现](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/brpc/policy/file_naming_service.cpp)使用[FileWatcher](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/base/files/file_watcher.h)关注文件的修改时间,当文件修改后,读取并调用NamingServiceActions::ResetServers告诉框架。
- list:列表就在服务名里(逗号分隔)。在读取完一次并调用NamingServiceActions::ResetServers后就退出了,因为列表再不会改变了。
如果用户需要建立这些对象仍然是不够方便的,因为总是需要一些工厂代码根据配置项建立不同的对象,鉴于此,我们把工厂类做进了框架,并且是非常方便的形式:
@@ -20,7 +20,7 @@ list://addr1,addr2,... # use the addresses separated by comma
http:// # Domain Naming Service, aka DNS.
```
-这套方式是可扩展的,实现了新的NamingService后在[global.cpp](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/brpc/global.cpp)中依葫芦画瓢注册下就行了,如下图所示:
+这套方式是可扩展的,实现了新的NamingService后在[global.cpp](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/brpc/global.cpp)中依葫芦画瓢注册下就行了,如下图所示:
![img](../images/register_ns.png)
@@ -28,7 +28,7 @@ http:// # Domain Naming Service, aka DNS.
# 负载均衡
-baidu-rpc中[LoadBalancer](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/brpc/load_balancer.h)从多个服务节点中选择一个节点,目前的实现见[负载均衡](client.md#负载均衡)。
+brpc中[LoadBalancer](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/brpc/load_balancer.h)从多个服务节点中选择一个节点,目前的实现见[负载均衡](client.md#负载均衡)。
Load balancer最重要的是如何让不同线程中的负载均衡不互斥,解决这个问题的技术是[DoublyBufferedData](lalb.md#doublybuffereddata)。
@@ -38,9 +38,9 @@ Load balancer最重要的是如何让不同线程中的负载均衡不互斥,
# 健康检查
-对于那些无法连接却仍在NamingService的节点,baidu-rpc会定期连接它们,成功后对应的Socket将被”复活“,并可能被LoadBalancer选择上,这个过程就是健康检查。注意:被健康检查或在LoadBalancer中的节点一定在NamingService中。换句话说,只要一个节点不从NamingService删除,它要么是正常的(会被LoadBalancer选上),要么在做健康检查。
+对于那些无法连接却仍在NamingService的节点,brpc会定期连接它们,成功后对应的Socket将被”复活“,并可能被LoadBalancer选择上,这个过程就是健康检查。注意:被健康检查或在LoadBalancer中的节点一定在NamingService中。换句话说,只要一个节点不从NamingService删除,它要么是正常的(会被LoadBalancer选上),要么在做健康检查。
-传统的做法是使用一个线程做所有连接的健康检查,baidu-rpc简化了这个过程:为需要的连接动态创建一个bthread专门做健康检查(Socket::HealthCheckThread)。这个线程的生命周期被对应连接管理。具体来说,当Socket被SetFailed后,健康检查线程就可能启动(如果SocketOptions.health_check_interval为正数的话):
+传统的做法是使用一个线程做所有连接的健康检查,brpc简化了这个过程:为需要的连接动态创建一个bthread专门做健康检查(Socket::HealthCheckThread)。这个线程的生命周期被对应连接管理。具体来说,当Socket被SetFailed后,健康检查线程就可能启动(如果SocketOptions.health_check_interval为正数的话):
- 健康检查线程先在确保没有其他人在使用Socket了后关闭连接。目前是通过对Socket的引用计数判断的。这个方法之所以有效在于Socket被SetFailed后就不能被Address了,所以引用计数只减不增。
- 定期连接直到远端机器被连接上,在这个过程中,如果Socket析构了,那么该线程也就随之退出了。
diff --git a/docs/cn/memcache_client.md b/docs/cn/memcache_client.md
index 077c5b92b8..7c3a5b6bb7 100644
--- a/docs/cn/memcache_client.md
+++ b/docs/cn/memcache_client.md
@@ -1,6 +1,6 @@
-[memcached](http://memcached.org/)是常用的缓存服务,为了使用户更快捷地访问memcached并充分利用bthread的并发能力,baidu-rpc直接支持memcache协议。示例程序:[example/memcache_c++](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/tree/example/memcache_c++/)
+[memcached](http://memcached.org/)是常用的缓存服务,为了使用户更快捷地访问memcached并充分利用bthread的并发能力,brpc直接支持memcache协议。示例程序:[example/memcache_c++](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/tree/example/memcache_c++/)
-**注意**:baidu-rpc只支持memcache的二进制协议。memcached在1.3前只有文本协议,但在当前看来支持的意义甚微。如果你的memcached早于1.3,升级版本。
+**注意**:brpc只支持memcache的二进制协议。memcached在1.3前只有文本协议,但在当前看来支持的意义甚微。如果你的memcached早于1.3,升级版本。
相比使用[libmemcached](http://libmemcached.org/libMemcached.html)(官方client)的优势有:
@@ -9,7 +9,7 @@
- 有明确的request和response。而libmemcached是没有的,收到的消息不能直接和发出的消息对应上,用户需要自己做维护工作。
- 支持多种[连接方式](client.md#连接方式)。支持超时、backup request、取消、tracing、内置服务等一系列RPC基本福利。
-当前实现充分利用了RPC的并发机制并尽量避免了拷贝。一个client可以轻松地把一个同机memcached实例(版本1.4.15)压到极限:单连接9万,多连接33万。在大部分情况下,baidu-rpc应该能充分发挥memcached的性能。
+当前实现充分利用了RPC的并发机制并尽量避免了拷贝。一个client可以轻松地把一个同机memcached实例(版本1.4.15)压到极限:单连接9万,多连接33万。在大部分情况下,brpc应该能充分发挥memcached的性能。
# 访问单台memcached
diff --git a/docs/cn/memory_management.md b/docs/cn/memory_management.md
index b1681f32e7..73fce35bd8 100644
--- a/docs/cn/memory_management.md
+++ b/docs/cn/memory_management.md
@@ -7,7 +7,7 @@
- 大多数结构是等长的。
-这个属性可以大幅简化内存分配的过程,获得比通用malloc更稳定、快速的性能。baidu-rpc中的ResourcePool和ObjectPool即提供这类分配。
+这个属性可以大幅简化内存分配的过程,获得比通用malloc更稳定、快速的性能。brpc中的ResourcePool和ObjectPool即提供这类分配。
> 这篇文章不鼓励用户使用ResourcePool或ObjectPool,事实上我们反对用户在程序中使用这两个类。因为”等长“的副作用是某个类型独占了一部分内存,这些内存无法再被其他类型使用,如果不加控制的滥用,反而会在程序中产生大量彼此隔离的内存分配体系,既浪费内存也不见得会有更好的性能。
@@ -25,17 +25,17 @@
# ObjectPool
-这是ResourcePool的变种,不返回偏移量,而直接返回对象指针。内部结构和ResourcePool类似,一些代码更加简单。对于用户来说,这就是一个多线程下的对象池,baidu-rpc里也是这么用的。比如Socket::Write中把每个待写出的请求包装为WriteRequest,这个对象就是用ObjectPool分配的。
+这是ResourcePool的变种,不返回偏移量,而直接返回对象指针。内部结构和ResourcePool类似,一些代码更加简单。对于用户来说,这就是一个多线程下的对象池,brpc里也是这么用的。比如Socket::Write中把每个待写出的请求包装为WriteRequest,这个对象就是用ObjectPool分配的。
# 生成bthread_t
-用户期望通过创建bthread获得更高的并发度,所以创建bthread必须很快。 在目前的实现中创建一个bthread的平均耗时小于200ns。如果每次都要从头创建,是不可能这么快的。创建过程更像是从一个bthread池子中取一个实例,我们又同时需要一个id来指代一个bthread,所以这儿正是ResourcePool的用武之地。bthread在代码中被称作Task,其结构被称为TaskMeta,定义在[task_meta.h](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/bthread/task_meta.h)中,所有的TaskMeta由ResourcePool分配。
+用户期望通过创建bthread获得更高的并发度,所以创建bthread必须很快。 在目前的实现中创建一个bthread的平均耗时小于200ns。如果每次都要从头创建,是不可能这么快的。创建过程更像是从一个bthread池子中取一个实例,我们又同时需要一个id来指代一个bthread,所以这儿正是ResourcePool的用武之地。bthread在代码中被称作Task,其结构被称为TaskMeta,定义在[task_meta.h](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/bthread/task_meta.h)中,所有的TaskMeta由ResourcePool分配。
bthread的大部分函数都需要在O(1)时间内通过bthread_t访问到TaskMeta,并且当bthread_t失效后,访问应返回NULL以让函数做出返回错误。解决方法是:bthread_t由32位的版本和32位的偏移量组成。版本解决[ABA问题](http://en.wikipedia.org/wiki/ABA_problem),偏移量由ResourcePool分配。查找时先通过偏移量获得TaskMeta,再检查版本,如果版本不匹配,说明bthread失效了。注意:这只是大概的说法,在多线程环境下,即使版本相等,bthread仍可能随时失效,在不同的bthread函数中处理方法都是不同的,有些函数会加锁,有些则能忍受版本不相等。
![img](../images/resource_pool.png)
-这种id生成方式在baidu-rpc中应用广泛,baidu-rpc中的SocketId,bthread_id_t也是用类似的方法分配的。
+这种id生成方式在brpc中应用广泛,brpc中的SocketId,bthread_id_t也是用类似的方法分配的。
# 栈
diff --git a/docs/cn/new_protocol.md b/docs/cn/new_protocol.md
index a638a987f9..077f6766b8 100644
--- a/docs/cn/new_protocol.md
+++ b/docs/cn/new_protocol.md
@@ -1,6 +1,6 @@
# server端多协议
-baidu-rpc server在同端口支持所有的协议,大部分时候这对部署和运维更加方便。由于不同协议的格式大相径庭,严格地来说,同端口很难无二义地支持所有协议。出于解耦和可扩展性的考虑,也不太可能集中式地构建一个针对所有协议的分类器。我们的做法就是把协议归三类后逐个尝试:
+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个字节就可以知道协议是否匹配,最先尝试这类协议。这些协议在同一个连接上也可以共存。
- 第二类协议:有较为复杂的语法,没有固定的协议标记或特殊字符,可能在解析一段输入后才能判断是否匹配,目前此类协议只有http。
@@ -14,13 +14,13 @@ baidu-rpc server在同端口支持所有的协议,大部分时候这对部署
# 支持新协议
-baidu-rpc就是设计为可随时扩展新协议的,步骤如下:
+brpc就是设计为可随时扩展新协议的,步骤如下:
> 以nshead开头的协议有统一支持,看[这里](nshead_service.md)。
## 增加ProtocolType
-在[options.proto](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/brpc/options.proto)的ProtocolType中增加新协议类型,如果你需要的话可以联系我们增加,以确保不会和其他人的需求重合。
+在[options.proto](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/brpc/options.proto)的ProtocolType中增加新协议类型,如果你需要的话可以联系我们增加,以确保不会和其他人的需求重合。
目前的ProtocolType(16年底):
```c++
@@ -34,7 +34,7 @@ enum ProtocolType {
PROTOCOL_HTTP = 6;
PROTOCOL_PUBLIC_PBRPC = 7;
PROTOCOL_NOVA_PBRPC = 8;
- PROTOCOL_NSHEAD_CLIENT = 9; // implemented in baidu-rpc-ub
+ PROTOCOL_NSHEAD_CLIENT = 9; // implemented in brpc-ub
PROTOCOL_NSHEAD = 10;
PROTOCOL_HADOOP_RPC = 11;
PROTOCOL_HADOOP_SERVER_RPC = 12;
@@ -52,7 +52,7 @@ enum ProtocolType {
```
## 实现回调
-均定义在struct Protocol中,该结构定义在[protocol.h](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/brpc/protocol.h)。其中的parse必须实现,除此之外server端至少要实现process_request,client端至少要实现serialize_request,pack_request,process_response;
+均定义在struct Protocol中,该结构定义在[protocol.h](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/brpc/protocol.h)。其中的parse必须实现,除此之外server端至少要实现process_request,client端至少要实现serialize_request,pack_request,process_response;
实现协议回调还是比较困难的,这块的代码不会像供普通用户使用的那样,有较好的提示和保护,你得先靠自己搞清楚其他协议中的类似代码,然后再动手,最后发给我们做code review。
@@ -137,7 +137,7 @@ typedef const std::string& (*GetMethodName)(const google::protobuf::MethodDescri
## 注册到全局
-实现好的协议要调用RegisterProtocol[注册到全局](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/brpc/global.cpp),以便baidu-rpc发现。就像这样:
+实现好的协议要调用RegisterProtocol[注册到全局](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/brpc/global.cpp),以便brpc发现。就像这样:
```c++
Protocol http_protocol = { ParseHttpMessage,
SerializeHttpRequest, PackHttpRequest,
@@ -155,7 +155,7 @@ if (RegisterProtocol(PROTOCOL_HTTP, http_protocol) != 0) {
为了进一步简化protocol的实现逻辑,r34386是一个不兼容改动,主要集中在下面几点:
-- ProcessXXX必须在处理结束时调用msg_base->Destroy()。在之前的版本中,这是由框架完成的。这个改动帮助我们隐藏处理EOF的代码(很晦涩),还可以在未来支持更异步的处理(退出ProcessXXX不意味着处理结束)。为了确保所有的退出分支都会调用msg_base->Destroy(),可以使用定义在[destroying_ptr.h](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/brpc/destroying_ptr.h)中的DestroyingPtr<>,可能像这样:
+- ProcessXXX必须在处理结束时调用msg_base->Destroy()。在之前的版本中,这是由框架完成的。这个改动帮助我们隐藏处理EOF的代码(很晦涩),还可以在未来支持更异步的处理(退出ProcessXXX不意味着处理结束)。为了确保所有的退出分支都会调用msg_base->Destroy(),可以使用定义在[destroying_ptr.h](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/brpc/destroying_ptr.h)中的DestroyingPtr<>,可能像这样:
```c++
void ProcessXXXRequest(InputMessageBase* msg_base) {
DestroyingPtr msg(static_cast(msg_base));
@@ -163,7 +163,7 @@ void ProcessXXXRequest(InputMessageBase* msg_base) {
}
```
-- 具体请参考[其他协议](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/brpc/policy/baidu_rpc_protocol.cpp)的实现。
+- 具体请参考[其他协议](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/brpc/policy/baidu_rpc_protocol.cpp)的实现。
- InputMessageBase::socket_id()被移除,而通过socket()可以直接访问到对应Socket的指针。ProcessXXX函数中Address Socket的代码可以移除。
ProcessXXXRequest开头的修改一般是这样:
```c++
diff --git a/docs/cn/nshead_service.md b/docs/cn/nshead_service.md
index 393f3f9a22..c67c2403b1 100644
--- a/docs/cn/nshead_service.md
+++ b/docs/cn/nshead_service.md
@@ -1,16 +1,16 @@
-ub是百度内广泛使用的老RPC框架,在迁移ub服务时不可避免地需要[访问ub-server](ub_client.md)或被ub-client访问。ub使用的协议种类很多,但都以nshead作为二进制包的头部,这类服务在baidu-rpc中统称为**“nshead service”**。
+ub是百度内广泛使用的老RPC框架,在迁移ub服务时不可避免地需要[访问ub-server](ub_client.md)或被ub-client访问。ub使用的协议种类很多,但都以nshead作为二进制包的头部,这类服务在brpc中统称为**“nshead service”**。
-nshead后大都使用mcpack/compack作为序列化格式,注意这不是“协议”。"协议"除了序列化格式,还涉及到各种特殊字段的定义,一种序列化格式可能会衍生出很多协议。ub没有定义标准协议,所以即使都使用mcpack/compack,产品线的通信协议也是五花八门,无法互通。鉴于此,我们提供了一套接口,让用户能够灵活的处理自己产品线的协议,同时享受baidu-rpc提供的builtin services等一系列框架福利。
+nshead后大都使用mcpack/compack作为序列化格式,注意这不是“协议”。"协议"除了序列化格式,还涉及到各种特殊字段的定义,一种序列化格式可能会衍生出很多协议。ub没有定义标准协议,所以即使都使用mcpack/compack,产品线的通信协议也是五花八门,无法互通。鉴于此,我们提供了一套接口,让用户能够灵活的处理自己产品线的协议,同时享受brpc提供的builtin services等一系列框架福利。
# 使用ubrpc的服务
ubrpc协议的基本形式是nshead+compack或mcpack2,但compack或mcpack2中包含一些RPC过程需要的特殊字段。
-在baidu-rpc r31687之后,用protobuf写的服务可以通过mcpack2pb被ubrpc client访问,步骤如下:
+在brpc r31687之后,用protobuf写的服务可以通过mcpack2pb被ubrpc client访问,步骤如下:
## 把idl文件转化为proto文件
-使用脚本[idl2proto](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/tools/idl2proto)把idl文件自动转化为proto文件,下面是转化后的proto文件。
+使用脚本[idl2proto](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/tools/idl2proto)把idl文件自动转化为proto文件,下面是转化后的proto文件。
```protobuf
// Converted from echo.idl by public/mcpack2pb/idl2proto
@@ -124,11 +124,11 @@ brpc::ServerOptions option;
option.nshead_service = new brpc::policy::UbrpcCompackAdaptor; // mcpack2用UbrpcMcpack2Adaptor
```
-例子见[example/echo_c++_ubrpc_compack](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/example/echo_c++_ubrpc_compack/)。
+例子见[example/echo_c++_ubrpc_compack](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/example/echo_c++_ubrpc_compack/)。
# 使用nshead+blob的服务
-[NsheadService](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/brpc/nshead_service.h)是baidu-rpc中所有处理nshead打头协议的基类,实现好的NsheadService实例得赋值给ServerOptions.nshead_service才能发挥作用。不赋值的话,默认是NULL,代表不支持任何nshead开头的协议,这个server被nshead开头的数据包访问时会报错。明显地,**一个Server只能处理一种以nshead开头的协议。**
+[NsheadService](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/brpc/nshead_service.h)是brpc中所有处理nshead打头协议的基类,实现好的NsheadService实例得赋值给ServerOptions.nshead_service才能发挥作用。不赋值的话,默认是NULL,代表不支持任何nshead开头的协议,这个server被nshead开头的数据包访问时会报错。明显地,**一个Server只能处理一种以nshead开头的协议。**
NsheadService的接口如下,基本上用户只需要实现`ProcessNsheadRequest`这个函数。
@@ -139,7 +139,7 @@ struct NsheadMessage {
base::IOBuf body;
};
-// 实现这个类并复制给ServerOptions.nshead_service来让baidu-rpc处理nshead请求。
+// 实现这个类并复制给ServerOptions.nshead_service来让brpc处理nshead请求。
class NsheadService : public Describable {
public:
NsheadService();
@@ -164,11 +164,11 @@ public:
};
```
-完整的example在[example/nshead_extension_c++](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/tree/example/nshead_extension_c++/)。
+完整的example在[example/nshead_extension_c++](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/tree/example/nshead_extension_c++/)。
# 使用nshead+mcpack/compack/idl的服务
-idl是mcpack/compack的前端,用户只要在idl文件中描述schema,就可以生成一些C++结构体,这些结构体可以打包为mcpack/compack。如果你的服务仍在大量地使用idl生成的结构体,且短期内难以修改,同时想要使用baidu-rpc提升性能和开发效率的话,可以实现[NsheadService](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/brpc/nshead_service.h),其接口接受nshead + 二进制包为request,用户填写自己的处理逻辑,最后的response也是nshead+二进制包。流程与protobuf方法保持一致,但过程中不涉及任何protobuf的序列化和反序列化,用户可以自由地理解nshead后的二进制包,包括用idl加载mcpack/compack数据包。
+idl是mcpack/compack的前端,用户只要在idl文件中描述schema,就可以生成一些C++结构体,这些结构体可以打包为mcpack/compack。如果你的服务仍在大量地使用idl生成的结构体,且短期内难以修改,同时想要使用brpc提升性能和开发效率的话,可以实现[NsheadService](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/brpc/nshead_service.h),其接口接受nshead + 二进制包为request,用户填写自己的处理逻辑,最后的response也是nshead+二进制包。流程与protobuf方法保持一致,但过程中不涉及任何protobuf的序列化和反序列化,用户可以自由地理解nshead后的二进制包,包括用idl加载mcpack/compack数据包。
不过,你应当充分意识到这么改造的坏处:
@@ -178,7 +178,7 @@ idl是mcpack/compack的前端,用户只要在idl文件中描述schema,就可
# 使用nshead+protobuf的服务
-如果你的协议已经使用了nshead + protobuf,或者你想把你的协议适配为protobuf格式,那可以使用另一种模式:实现[NsheadPbServiceAdaptor](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/brpc/nshead_pb_service_adaptor.h)(NsheadService的子类)。
+如果你的协议已经使用了nshead + protobuf,或者你想把你的协议适配为protobuf格式,那可以使用另一种模式:实现[NsheadPbServiceAdaptor](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/brpc/nshead_pb_service_adaptor.h)(NsheadService的子类)。
工作步骤:
@@ -186,7 +186,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在[这里](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/tree/example/nshead_pb_extension_c++/)。
+这样做的好处是,这个服务还可以被其他使用protobuf的协议访问,比如标准协议,hulu协议,sofa协议等等。NsheadPbServiceAdaptor的主要接口如下。完整的example在[这里](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/tree/example/nshead_pb_extension_c++/)。
```c++
class NsheadPbServiceAdaptor : public NsheadService {
diff --git a/docs/cn/redis_client.md b/docs/cn/redis_client.md
index 888e2f5bfa..f0618de1c9 100644
--- a/docs/cn/redis_client.md
+++ b/docs/cn/redis_client.md
@@ -1,4 +1,4 @@
-[redis](http://redis.io/)是最近几年比较火的缓存服务,相比memcached在server端提供了更多的数据结构和操作方法,简化了用户的开发工作,在百度内有比较广泛的应用。为了使用户更快捷地访问redis并充分利用bthread的并发能力,baidu-rpc直接支持redis协议。示例程序:[example/redis_c++](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/tree/example/redis_c++/)
+[redis](http://redis.io/)是最近几年比较火的缓存服务,相比memcached在server端提供了更多的数据结构和操作方法,简化了用户的开发工作,在百度内有比较广泛的应用。为了使用户更快捷地访问redis并充分利用bthread的并发能力,brpc直接支持redis协议。示例程序:[example/redis_c++](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/tree/example/redis_c++/)
相比使用[hiredis](https://github.com/redis/hiredis)(官方client)的优势有:
@@ -7,7 +7,7 @@
- 支持多种[连接方式](client.md#连接方式)。支持超时、backup request、取消、tracing、内置服务等一系列RPC基本福利。
- 一个进程和一个redis-server只有一个连接。多个线程同时访问一个redis-server时更高效(见[性能](#性能))。无论reply的组成多复杂,内存都会连续成块地分配,并支持短串优化(SSO)。
-像http一样,baidu-rpc保证在最差情况下解析redis reply的时间复杂度也是O(N),N是reply的字节数,而不是O(N^2)。当reply是个较大的数组时,这是比较重要的。
+像http一样,brpc保证在最差情况下解析redis reply的时间复杂度也是O(N),N是reply的字节数,而不是O(N^2)。当reply是个较大的数组时,这是比较重要的。
r32037后加上[-redis_verbose](#查看发出的请求和收到的回复)后会在stderr上打印出所有的redis request和response供调试。
@@ -103,7 +103,7 @@ CHECK_EQ(-10, response.reply(3).integer());
# RedisRequest
-一个[RedisRequest](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/brpc/redis.h)可包含多个Command,调用AddCommand*增加命令,成功返回true,失败返回false并会打印调用处的栈。
+一个[RedisRequest](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/brpc/redis.h)可包含多个Command,调用AddCommand*增加命令,成功返回true,失败返回false并会打印调用处的栈。
```c++
bool AddCommand(const char* fmt, ...);
@@ -123,7 +123,7 @@ command_size()可获得(成功)加入的命令个数。
# RedisResponse
-[RedisResponse](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/brpc/redis.h)可能包含一个或多个[RedisReply](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/brpc/redis_reply.h),reply_size()可获得reply的个数,reply(i)可获得第i个reply的引用(从0计数)。注意在hiredis中,如果请求包含了N个command,获取结果也要调用N次redisGetReply。但在baidu-rpc中这是不必要的,RedisResponse已经包含了N个reply,通过reply(i)获取就行了。只要RPC成功,response.reply_size()应与request.command_size()相等,除非redis-server有bug(redis-server工作的基本前提就是response和request按序一一对应)
+[RedisResponse](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/brpc/redis.h)可能包含一个或多个[RedisReply](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/brpc/redis_reply.h),reply_size()可获得reply的个数,reply(i)可获得第i个reply的引用(从0计数)。注意在hiredis中,如果请求包含了N个command,获取结果也要调用N次redisGetReply。但在brpc中这是不必要的,RedisResponse已经包含了N个reply,通过reply(i)获取就行了。只要RPC成功,response.reply_size()应与request.command_size()相等,除非redis-server有bug(redis-server工作的基本前提就是response和request按序一一对应)
每个reply可能是:
@@ -142,7 +142,7 @@ response中的所有reply的ownership属于response。当response析构时,rep
# 访问redis集群
-暂时请沿用常见的[twemproxy](https://github.com/twitter/twemproxy)方案,像访问单点一样访问proxy。如果你之前用hiredis访问BDRP(使用了twemproxy),那把client更换成baidu-rpc就行了。通过client(一致性哈希)直接访问redis集群虽然能降低延时,但同时也(可能)意味着无法直接利用BDRP的托管服务,这一块还不是很确定。
+暂时请沿用常见的[twemproxy](https://github.com/twitter/twemproxy)方案,像访问单点一样访问proxy。如果你之前用hiredis访问BDRP(使用了twemproxy),那把client更换成brpc就行了。通过client(一致性哈希)直接访问redis集群虽然能降低延时,但同时也(可能)意味着无法直接利用BDRP的托管服务,这一块还不是很确定。
如果你自己维护了redis集群,和memcache类似,应该是可以用一致性哈希访问的。但每个RedisRequest应只包含一个command或确保所有的command始终落在同一台server。如果request包含了多个command,在当前实现下总会送向同一个server。比方说一个request中包含了多个Get,而对应的key分布在多个server上,那么结果就肯定不对了,这个情况下你必须把一个request分开为多个。
@@ -180,7 +180,7 @@ TRACE: 02-13 19:43:49: * 0 client.cpp:180] Accessing redis server at qps=41167
TRACE: 02-13 19:43:50: * 0 client.cpp:180] Accessing redis server at qps=412583 latency=482
```
-200个线程后qps基本到极限了。这里的极限qps比hiredis高很多,原因在于baidu-rpc默认以单链接访问redis-server,多个线程在写出时会[以wait-free的方式合并](io.md#发消息),从而让redis-server就像被批量访问一样,每次都能从那个连接中读出一批请求,从而获得远高于非批量时的qps。下面通过连接池访问redis-server时qps的大幅回落是另外一个证明。
+200个线程后qps基本到极限了。这里的极限qps比hiredis高很多,原因在于brpc默认以单链接访问redis-server,多个线程在写出时会[以wait-free的方式合并](io.md#发消息),从而让redis-server就像被批量访问一样,每次都能从那个连接中读出一批请求,从而获得远高于非批量时的qps。下面通过连接池访问redis-server时qps的大幅回落是另外一个证明。
分别使用1,50,200个bthread一次发送10个同步压测同机redis-server,延时单位均为微秒。
@@ -225,7 +225,7 @@ TRACE: 02-13 18:07:42: * 0 client.cpp:180] Accessing redis server at qps=75238
# Command Line Interface
-example/redis_c++/redis_cli是一个类似于官方CLI的命令行工具,以展示baidu-rpc对redis协议的处理能力。当使用baidu-rpc访问redis-server出现不符合预期的行为时,也可以使用这个CLI进行交互式的调试。
+example/redis_c++/redis_cli是一个类似于官方CLI的命令行工具,以展示brpc对redis协议的处理能力。当使用brpc访问redis-server出现不符合预期的行为时,也可以使用这个CLI进行交互式的调试。
```
$ ./redis_cli
@@ -236,7 +236,7 @@ $ ./redis_cli
/_.___/\__,_/_/\__,_/\__,_/ /_/ / .___/\___/
/_/
This command-line tool mimics the look-n-feel of official redis-cli, as a
-demostration of baidu-rpc's capability of talking to redis server. The
+demostration of brpc's capability of talking to redis server. The
output and behavior is not exactly same with the official one.
redis 127.0.0.1:6379> mset key1 foo key2 bar key3 17
@@ -245,10 +245,10 @@ redis 127.0.0.1:6379> mget key1 key2 key3
["foo", "bar", "17"]
redis 127.0.0.1:6379> incrby key3 10
(integer) 27
-redis 127.0.0.1:6379> client setname baidu-rpc-cli
+redis 127.0.0.1:6379> client setname brpc-cli
OK
redis 127.0.0.1:6379> client getname
-"baidu-rpc-cli"
+"brpc-cli"
```
和官方CLI类似,redis_cli 也可以直接运行命令,-server参数可以指定redis-server的地址。
diff --git a/docs/cn/rpc_press.md b/docs/cn/rpc_press.md
index 50c53f7dc1..7558297a22 100644
--- a/docs/cn/rpc_press.md
+++ b/docs/cn/rpc_press.md
@@ -8,7 +8,7 @@ rpc_press无需写代码就压测各种rpc server,目前支持的协议有:
# 获取工具
-先按照[Getting Started](getting_started.md)编译好baidu-rpc,再去tools/rpc_press编译。
+先按照[Getting Started](getting_started.md)编译好brpc,再去tools/rpc_press编译。
在CentOS 6.3上如果出现找不到libssl.so.4的错误,可执行`ln -s /usr/lib64/libssl.so.6 libssl.so.4临时解决`
@@ -34,7 +34,7 @@ json也可以写在文件中,假如./input.json包含了上述两个请求,-
- -inc: 包含被import的proto文件的路径。rpc_press默认支持import目录下的其他proto文件,但如果proto文件在其他目录,就要通过这个参数指定,多个路径用分号(;)分隔。
- -lb_policy: 指定负载均衡算法,默认为空,可选项为: rr random la c_murmurhash c_md5,具体见[负载均衡](client.md#负载均衡)。
- -timeout_ms: 设定超时,单位是毫秒(milliseconds),默认是1000(1秒)
-- -max_retry: 最大的重试次数,默认是3, 一般无需修改. baidu-rpc的重试行为具体请见[这里](client.md#重试).
+- -max_retry: 最大的重试次数,默认是3, 一般无需修改. brpc的重试行为具体请见[这里](client.md#重试).
- -protocol: 连接server使用的协议,可选项见[协议](client.md#协议), 默认是baidu_std(标准协议)
- -connection_type: 连接方式,可选项为: single pooled short,具体见[连接方式](client.md#连接方式)。默认会根据协议自动选择,无需指定.
- -output: 如果不为空,response会转为json并写入这个文件,默认为空。
@@ -60,7 +60,7 @@ json也可以写在文件中,假如./input.json包含了上述两个请求,-
rpc_press启动后会默认在8888端口启动一个dummy server,用于观察rpc_press本身的运行情况:
```
-./rpc_press -proto=latest_baidu_rpc/public/baidu-rpc/example/multi_threaded_echo_c++/echo.proto -service=example.EchoService -method=Echo -server=0.0.0.0:8002 -input=./input.json -duration=0 -qps=100
+./rpc_press -proto=echo.proto -service=example.EchoService -method=Echo -server=0.0.0.0:8002 -input=./input.json -duration=0 -qps=100
TRACE: 01-30 16:10:04: * 0 src/brpc/server.cpp:733] Server[dummy_servers] is serving on port=8888.
TRACE: 01-30 16:10:04: * 0 src/brpc/server.cpp:742] Check out http://db-rpc-dev00.db01.baidu.com:8888 in your web browser.
```
diff --git a/docs/cn/rpc_replay.md b/docs/cn/rpc_replay.md
index 0e74d3f152..0686fd3b59 100644
--- a/docs/cn/rpc_replay.md
+++ b/docs/cn/rpc_replay.md
@@ -1,14 +1,14 @@
-r31658后,baidu-rpc能随机地把一部分请求写入一些文件中,并通过rpc_replay工具回放。目前支持的协议有:baidu_std, hulu_pbrpc, sofa_pbrpc。
+r31658后,brpc能随机地把一部分请求写入一些文件中,并通过rpc_replay工具回放。目前支持的协议有:baidu_std, hulu_pbrpc, sofa_pbrpc。
# 获取工具
-先按照[Getting Started](getting_started.md)编译好baidu-rpc,再去tools/rpc_replay编译。
+先按照[Getting Started](getting_started.md)编译好brpc,再去tools/rpc_replay编译。
在CentOS 6.3上如果出现找不到libssl.so.4的错误,可执行`ln -s /usr/lib64/libssl.so.6 libssl.so.4临时解决`
# 采样
-baidu-rpc通过如下flags打开和控制如何保存请求,包含(R)后缀的flag都可以动态设置。
+brpc通过如下flags打开和控制如何保存请求,包含(R)后缀的flag都可以动态设置。
![img](../images/rpc_replay_1.png)
@@ -16,12 +16,12 @@ baidu-rpc通过如下flags打开和控制如何保存请求,包含(R)后缀的
参数说明:
-- -rpc_dump是主开关,关闭时其他以rpc_dump开头的flag都无效。当打开-rpc_dump后,baidu-rpc会以一定概率采集请求,如果服务的qps很高,baidu-rpc会调节采样比例,使得每秒钟采样的请求个数不超过-bvar_collector_expected_per_second对应的值。这个值在目前同样影响rpcz和contention profiler,一般不用改动,以后会对不同的应用独立开来。
+- -rpc_dump是主开关,关闭时其他以rpc_dump开头的flag都无效。当打开-rpc_dump后,brpc会以一定概率采集请求,如果服务的qps很高,brpc会调节采样比例,使得每秒钟采样的请求个数不超过-bvar_collector_expected_per_second对应的值。这个值在目前同样影响rpcz和contention profiler,一般不用改动,以后会对不同的应用独立开来。
- -rpc_dump_dir:设置存放被dump请求的目录
- -rpc_dump_max_files: 设置目录下的最大文件数,当超过限制时,老文件会被删除以腾出空间。
- -rpc_dump_max_requests_in_one_file:一个文件内的最大请求数,超过后写新文件。
-baidu-rpc通过一个[bvar::Collector](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/bvar/collector.h)来汇总来自不同线程的被采样请求,不同线程之间没有竞争,开销很小。
+brpc通过一个[bvar::Collector](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/bvar/collector.h)来汇总来自不同线程的被采样请求,不同线程之间没有竞争,开销很小。
写出的内容依次存放在rpc_dump_dir目录下的多个文件内,这个目录默认在./rpc_dump_,其中是程序名。不同程序在同一个目录下同时采样时会写入不同的目录。如果程序启动时rpc_dump_dir已经存在了,目录将被清空。目录中的每个文件以requests.yyyymmdd_hhmmss_uuuuus命名,以保证按时间有序方便查找,比如:
@@ -43,7 +43,7 @@ serialized request (body_size - meta_size bytes, including attachment)
> 一个文件可能包含多种协议的请求,如果server被多种协议访问的话。回放时被请求的server也将收到不同协议的请求。
-baidu-rpc提供了[SampleIterator](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/brpc/rpc_dump.h)从一个采样目录下的所有文件中依次读取所有的被采样请求,用户可根据需求把serialized request反序列化为protobuf请求,做一些二次开发。
+brpc提供了[SampleIterator](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/brpc/rpc_dump.h)从一个采样目录下的所有文件中依次读取所有的被采样请求,用户可根据需求把serialized request反序列化为protobuf请求,做一些二次开发。
```c++
#include
@@ -59,7 +59,7 @@ for (SampleRequest* req = it->Next(); req != NULL; req = it->Next()) {
# 回放
-baidu-rpc在[tools/rpc_replay](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/tree/tools/rpc_replay/)提供了默认的回放工具。运行方式如下:
+brpc在[tools/rpc_replay](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/tree/tools/rpc_replay/)提供了默认的回放工具。运行方式如下:
![img](../images/rpc_replay_4.png)
diff --git a/docs/cn/rpc_view.md b/docs/cn/rpc_view.md
index 7c7c4fcabd..cdd39ea81a 100644
--- a/docs/cn/rpc_view.md
+++ b/docs/cn/rpc_view.md
@@ -2,7 +2,7 @@ rpc_view可以查看端口不在8000-8999的server的内置服务。之前如果
# 获取工具
-先按照[Getting Started](getting_started.md)编译好baidu-rpc,再去tools/rpc_view编译。
+先按照[Getting Started](getting_started.md)编译好brpc,再去tools/rpc_view编译。
在CentOS 6.3上如果出现找不到libssl.so.4的错误,可执行`ln -s /usr/lib64/libssl.so.6 libssl.so.4临时解决`
diff --git a/docs/cn/rpcz.md b/docs/cn/rpcz.md
index b5330468c5..dc858e0734 100644
--- a/docs/cn/rpcz.md
+++ b/docs/cn/rpcz.md
@@ -1,4 +1,4 @@
-用户能通过/rpcz看到最近请求的详细信息,并可以插入注释(annotation),不同于tracing system(如[dapper](http://static.googleusercontent.com/media/research.google.com/en//pubs/archive/36356.pdf))以全局视角看到整体系统的延时分布,rpcz更多是一个调试工具,虽然角色有所不同,但在baidu-rpc中rpcz和tracing的数据来源是一样的。当每秒请求数小于1万时,rpcz会记录所有的请求,超过1万时,rpcz会随机忽略一些请求把采样数控制在1万左右。rpcz可以淘汰时间窗口之前的数据,通过-span_keeping_seconds选项设置,默认1小时。[一个长期运行的例子](http://brpc.baidu.com:8765/rpcz)。
+用户能通过/rpcz看到最近请求的详细信息,并可以插入注释(annotation),不同于tracing system(如[dapper](http://static.googleusercontent.com/media/research.google.com/en//pubs/archive/36356.pdf))以全局视角看到整体系统的延时分布,rpcz更多是一个调试工具,虽然角色有所不同,但在brpc中rpcz和tracing的数据来源是一样的。当每秒请求数小于1万时,rpcz会记录所有的请求,超过1万时,rpcz会随机忽略一些请求把采样数控制在1万左右。rpcz可以淘汰时间窗口之前的数据,通过-span_keeping_seconds选项设置,默认1小时。[一个长期运行的例子](http://brpc.baidu.com:8765/rpcz)。
关于开销:我们的实现完全规避了线程竞争,开销极小,在qps 30万的测试场景中,观察不到明显的性能变化,对大部分应用而言应该是“free”的。即使采集了几千万条请求,rpcz也不会增加很多内存,一般在50兆以内。rpcz会占用一些磁盘空间(就像日志一样),如果设定为存一个小时的数据,一般在几百兆左右。
@@ -20,7 +20,7 @@
![img](../images/rpcz_5.png)
-如果只是baidu-rpc client或没有使用baidu-rpc,看[这里](dummy_server.md)。
+如果只是brpc client或没有使用brpc,看[这里](dummy_server.md)。
## 数据展现
@@ -48,7 +48,7 @@
## Annotation
-只要你使用了baidu-rpc,就可以使用[TRACEPRINTF](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/brpc/traceprintf.h)打印内容到事件流中,比如:
+只要你使用了brpc,就可以使用[TRACEPRINTF](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/brpc/traceprintf.h)打印内容到事件流中,比如:
```c++
TRACEPRINTF("Hello rpcz %d", 123);
diff --git a/docs/cn/server.md b/docs/cn/server.md
index 608b7c5d95..d46f47618c 100644
--- a/docs/cn/server.md
+++ b/docs/cn/server.md
@@ -52,7 +52,7 @@ public:
**controller**
-在baidu-rpc中可以静态转为brpc::Controller(前提是这运行baidu-rpc的Server中),包含了所有request和response之外的参数集合,具体接口查阅[controller.h](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/brpc/controller.h)
+在brpc中可以静态转为brpc::Controller(前提是这运行brpc的Server中),包含了所有request和response之外的参数集合,具体接口查阅[controller.h](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/brpc/controller.h)
**request**
@@ -127,13 +127,13 @@ public:
};
```
-Service在插入[brpc::Server](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/brpc/server.h)后才可能提供服务。
+Service在插入[brpc::Server](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/brpc/server.h)后才可能提供服务。
## 标记当前调用为失败
调用Controller.SetFailed()可以把当前调用设置为失败,当发送过程出现错误时,框架也会调用这个函数。用户一般是在服务的CallMethod里调用这个函数,比如某个处理环节出错,SetFailed()后便可调用done->Run()并跳出函数了(如果使用了ClosureGuard的话在跳出函数时会自动调用done,不用手动)。Server端的done的逻辑主要是发送response回client,当其发现用户调用了SetFailed()后,会把错误信息送回client。client收到后,它的Controller::Failed()会为true(成功时为false),Controller::ErrorCode()和Controller::ErrorText()则分别是错误码和错误信息。
-对于http访问,用户还可以设置[status-code](http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html),在server端一般是调用controller.http_response().set_status_code(),标准的status-code定义在[http_status_code.h](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/brpc/http_status_code.h)中。如果SetFailed了但没有设置status-code,默认设为brpc::HTTP_STATUS_INTERNAL_SERVER_ERROR(500错误)
+对于http访问,用户还可以设置[status-code](http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html),在server端一般是调用controller.http_response().set_status_code(),标准的status-code定义在[http_status_code.h](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/brpc/http_status_code.h)中。如果SetFailed了但没有设置status-code,默认设为brpc::HTTP_STATUS_INTERNAL_SERVER_ERROR(500错误)
## 获取Client的地址和端口
@@ -165,7 +165,7 @@ printf("local_side=%s\n", base::endpoint2str(cntl->local_side()).c_str());
有些server以等待后端服务返回结果为主,且处理时间特别长,为了及时地释放出线程资源,更好的办法是把done注册到被等待事件的回调中,等到事件发生后再调用done->Run(),这种是**异步service**。
-异步service的最后一行一般是done_guard.release()以确保done_guard在析构时不会调用done->Run(),而是在事件回调中调用。例子请看[example/session_data_and_thread_local](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/tree/example/session_data_and_thread_local/)。
+异步service的最后一行一般是done_guard.release()以确保done_guard在析构时不会调用done->Run(),而是在事件回调中调用。例子请看[example/session_data_and_thread_local](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/tree/example/session_data_and_thread_local/)。
Service和Channel都可以使用done来表达后续的操作,但它们是完全不同的,请勿混淆:
@@ -208,7 +208,7 @@ int Start(int port, const ServerOptions* opt);
int Start(const char *ip_str, PortRange port_range, const ServerOptions *opt); // r32009后增加
```
-"localhost:9000", "cq01-cos-dev00.cq01:8000", “127.0.0.1:7000"都是合法的"ip_and_port_str"。其他重载形式请阅读[server.h](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/brpc/server.h)。
+"localhost:9000", "cq01-cos-dev00.cq01:8000", “127.0.0.1:7000"都是合法的"ip_and_port_str"。其他重载形式请阅读[server.h](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/brpc/server.h)。
options为NULL时所有参数取默认值,如果你要使用非默认值,这么做就行了:
@@ -236,7 +236,7 @@ r28921之前:如果closewait_ms不会0,且还有请求在被处理,那么S
r28921之后:closewait_ms失效,不管它是什么值,server在退出时总会等待所有正在被处理的请求完成,同时对新请求立刻回复ELOGOFF错误。这么做的原因在于只要server退出时仍有处理线程运行,就有访问到已释放内存的风险。如果你的server“退不掉”,很有可能是由于某个检索线程hang住了,
-当client看到ELOGOFF时,会跳过对应的server,并在其他server上重试对应的请求。所以在一般情况下baidu-rpc总是“优雅退出”的,重启或上线时几乎不会或只会丢失很少量的流量。
+当client看到ELOGOFF时,会跳过对应的server,并在其他server上重试对应的请求。所以在一般情况下brpc总是“优雅退出”的,重启或上线时几乎不会或只会丢失很少量的流量。
r31371后增加了RunUntilAskedToQuit()函数,简化了大部分情况下server的运转和停止代码。在server.Start后,只需如下代码即会让server运行直到按到Ctrl-C。
@@ -276,7 +276,7 @@ r34532后增加选项-pb_enum_as_number,开启后pb中的enum会转化为它
## 兼容(很)老版本client
-15年时,baidu-rpc允许一个pb service被http协议访问时,不设置pb请求,即使里面有required字段。一般来说这种service会自行解析http请求和设置http回复,并不会访问pb请求。但这也是非常危险的行为,毕竟这是pb service,但pb请求却是未定义的。这种服务在升级到新版本rpc时会遇到障碍,因为baidu-rpc早不允许这种行为。为了帮助这种服务升级,r34953后baidu-rpc允许用户经过一些设置后不把http body自动转化为pb(从而可自行处理),方法如下:
+15年时,brpc允许一个pb service被http协议访问时,不设置pb请求,即使里面有required字段。一般来说这种service会自行解析http请求和设置http回复,并不会访问pb请求。但这也是非常危险的行为,毕竟这是pb service,但pb请求却是未定义的。这种服务在升级到新版本rpc时会遇到障碍,因为brpc早不允许这种行为。为了帮助这种服务升级,r34953后brpc允许用户经过一些设置后不把http body自动转化为pb(从而可自行处理),方法如下:
```c++
brpc::ServiceOptions svc_opt;
@@ -362,7 +362,7 @@ Server.set_version(...)可以为server设置一个名称+版本,可通过/vers
## 在每条日志后打印hostname
-此功能只对[base/logging.h](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/base/logging.h)中的日志宏有效。打开[-log_hostname](http://brpc.baidu.com:8765/flags/log_hostname)后每条日志后都会带本机名称,如果所有的日志需要汇总到一起进行分析,这个功能可以帮助你了解某条日志来自哪台机器。
+此功能只对[base/logging.h](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/base/logging.h)中的日志宏有效。打开[-log_hostname](http://brpc.baidu.com:8765/flags/log_hostname)后每条日志后都会带本机名称,如果所有的日志需要汇总到一起进行分析,这个功能可以帮助你了解某条日志来自哪台机器。
## 打印FATAL日志后退出程序
@@ -372,7 +372,7 @@ Server.set_version(...)可以为server设置一个名称+版本,可通过/vers
## 最低日志级别
-此功能只对[base/logging.h](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/base/logging.h)中的日志宏有效。设置[-min_log_level](http://brpc.baidu.com:8765/flags/min_log_level)后只有**不低于**被设置日志级别的日志才会被打印,这个选项可以动态修改。设置值和日志级别的对应关系:0=INFO 1=NOTICE 2=WARNING 3=ERROR 4=FATAL
+此功能只对[base/logging.h](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/base/logging.h)中的日志宏有效。设置[-min_log_level](http://brpc.baidu.com:8765/flags/min_log_level)后只有**不低于**被设置日志级别的日志才会被打印,这个选项可以动态修改。设置值和日志级别的对应关系:0=INFO 1=NOTICE 2=WARNING 3=ERROR 4=FATAL
被拦住的日志产生的开销只是一次if判断,也不会评估参数(比如某个参数调用了函数,日志不打,这个函数就不会被调用),这和comlog是完全不同的。如果日志最终打印到comlog,那么还要经过comlog中的日志级别的过滤。
@@ -396,7 +396,7 @@ protobuf中有[类似的限制](https://github.com/google/protobuf/blob/master/s
FATAL: 05-10 13:35:02: * 0 google/protobuf/io/coded_stream.cc:156] A protocol message was rejected because it was too big (more than 67108864 bytes). To increase the limit (or to disable these warnings), see CodedInputStream::SetTotalBytesLimit() in google/protobuf/io/coded_stream.h.
```
-在r34677后,baidu-rpc移除了protobuf中的限制,只要-max_body_size足够大,protobuf不会再打印限制错误。此功能对protobuf的版本没有要求。
+在r34677后,brpc移除了protobuf中的限制,只要-max_body_size足够大,protobuf不会再打印限制错误。此功能对protobuf的版本没有要求。
## 压缩
@@ -476,15 +476,15 @@ option.auth = &auth;
你不能认为Server就用了这么多线程,因为进程内的所有Server和Channel会共享线程资源,线程总数是所有ServerOptions.num_threads和bthread_concurrency中的最大值。Channel没有相应的选项,但可以通过--bthread_concurrency调整。比如一个程序内有两个Server,num_threads分别为24和36,bthread_concurrency为16。那么worker线程数为max(24, 36, 16) = 36。这不同于其他RPC实现中往往是加起来。
-另外,baidu-rpc**不区分**io线程和worker线程。baidu-rpc知道如何编排IO和处理代码,以获得更高的并发度和线程利用率。
+另外,brpc**不区分**io线程和worker线程。brpc知道如何编排IO和处理代码,以获得更高的并发度和线程利用率。
## 限制最大并发
-“并发”在中文背景下有两种含义,一种是连接数,一种是同时在处理的请求数。有了[epoll](https://linux.die.net/man/4/epoll)之后我们就不太关心连接数了,baidu-rpc在所有上下文中提到的并发(concurrency)均指同时在处理的请求数,不是连接数。
+“并发”在中文背景下有两种含义,一种是连接数,一种是同时在处理的请求数。有了[epoll](https://linux.die.net/man/4/epoll)之后我们就不太关心连接数了,brpc在所有上下文中提到的并发(concurrency)均指同时在处理的请求数,不是连接数。
-在传统的同步rpc server中,最大并发不会超过worker线程数(上面的num_threads选项),设定worker数量一般也限制了并发。但baidu-rpc的请求运行于bthread中,M个bthread会映射至N个worker中(一般M大于N),所以同步server的并发度可能超过worker数量。另一方面,异步server虽然占用的线程较少,但有时也需要控制并发量。
+在传统的同步rpc server中,最大并发不会超过worker线程数(上面的num_threads选项),设定worker数量一般也限制了并发。但brpc的请求运行于bthread中,M个bthread会映射至N个worker中(一般M大于N),所以同步server的并发度可能超过worker数量。另一方面,异步server虽然占用的线程较少,但有时也需要控制并发量。
-baidu-rpc支持设置server级和method级的最大并发,当server或method同时处理的请求数超过并发度限制时,它会立刻给client回复ELIMIT错误,而不会调用服务回调。看到ELIMIT错误的client应尝试另一个server。在一些情况下,这个选项可以防止server出现过度排队,或用于限制server占用的资源,但在大部分情况下并无必要。
+brpc支持设置server级和method级的最大并发,当server或method同时处理的请求数超过并发度限制时,它会立刻给client回复ELIMIT错误,而不会调用服务回调。看到ELIMIT错误的client应尝试另一个server。在一些情况下,这个选项可以防止server出现过度排队,或用于限制server占用的资源,但在大部分情况下并无必要。
### 为什么超过最大并发要立刻给client返回错误而不是排队?
@@ -521,9 +521,9 @@ server.MaxConcurrencyOf(&service, "Echo") = 10;
用户代码(客户端的done,服务器端的CallMethod)默认在栈为1M的bthread中运行。但有些用户代码无法在bthread中运行,比如:
- JNI会检查stack layout而无法在bthread中运行。
-- 代码中广泛地使用pthread local传递session数据(跨越了某次RPC),短时间内无法修改。请注意,如果代码中完全不使用baidu-rpc的客户端,在bthread中运行是没有问题的,只要代码没有明确地支持bthread就会阻塞pthread,并不会产生问题。
+- 代码中广泛地使用pthread local传递session数据(跨越了某次RPC),短时间内无法修改。请注意,如果代码中完全不使用brpc的客户端,在bthread中运行是没有问题的,只要代码没有明确地支持bthread就会阻塞pthread,并不会产生问题。
-对于这些情况,baidu-rpc提供了pthread模式,开启**-usercode_in_pthread**后,用户代码均会在pthread中运行,原先阻塞bthread的函数转而阻塞pthread。
+对于这些情况,brpc提供了pthread模式,开启**-usercode_in_pthread**后,用户代码均会在pthread中运行,原先阻塞bthread的函数转而阻塞pthread。
**r33447前请勿在开启-usercode_in_pthread的代码中发起同步RPC,只要同时进行的同步RPC个数超过工作线程数就会死锁。**
@@ -534,7 +534,7 @@ server.MaxConcurrencyOf(&service, "Echo") = 10;
- bthread端支持一个独特的功能:把当前使用的pthread worker 让给另一个bthread运行,以消除一次上下文切换。client端的实现利用了这点,从而使一次RPC过程中3次上下文切换变为了2次。在高QPS系统中,消除上下文切换可以明显改善性能和延时分布。但pthread模式不具备这个能力,在高QPS系统中性能会有一定下降。
- pthread模式中线程资源是硬限,一旦线程被打满,请求就会迅速拥塞而造成大量超时。比如下游服务大量超时后,上游服务可能由于线程大都在等待下游也被打满从而影响性能。开启pthread模式后请考虑设置ServerOptions.max_concurrency以控制server的最大并发。而在bthread模式中bthread个数是软限,对此类问题的反应会更加平滑。
-打开pthread模式可以让一些产品快速尝试baidu-rpc,但我们仍然建议产品线逐渐地把代码改造为使用bthread local从而最终能关闭这个开关。
+打开pthread模式可以让一些产品快速尝试brpc,但我们仍然建议产品线逐渐地把代码改造为使用bthread local从而最终能关闭这个开关。
## 安全模式
@@ -572,11 +572,11 @@ curl -s -m 1 :/flags/enable_dir_service,enable_threads_service |
## 定制/health页面
-/health页面默认返回"OK",r32162后可以定制/health页面的内容:先继承[HealthReporter](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/brpc/health_reporter.h),在其中实现生成页面的逻辑(就像实现其他http service那样),然后把实例赋给ServerOptions.health_reporter,这个实例不被server拥有,必须保证在server运行期间有效。用户在定制逻辑中可以根据业务的运行状态返回更多样的状态信息。
+/health页面默认返回"OK",r32162后可以定制/health页面的内容:先继承[HealthReporter](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/brpc/health_reporter.h),在其中实现生成页面的逻辑(就像实现其他http service那样),然后把实例赋给ServerOptions.health_reporter,这个实例不被server拥有,必须保证在server运行期间有效。用户在定制逻辑中可以根据业务的运行状态返回更多样的状态信息。
## 私有变量
-百度内的检索程序大量地使用了[thread-local storage](https://en.wikipedia.org/wiki/Thread-local_storage) (缩写tls),有些是为了缓存频繁访问的对象以避免反复创建,有些则是为了在全局函数间隐式地传递状态。你应当尽量避免后者,这样的函数难以测试,不设置thread-local变量甚至无法运行。baidu-rpc中有三套机制解决和thread-local相关的问题。
+百度内的检索程序大量地使用了[thread-local storage](https://en.wikipedia.org/wiki/Thread-local_storage) (缩写tls),有些是为了缓存频繁访问的对象以避免反复创建,有些则是为了在全局函数间隐式地传递状态。你应当尽量避免后者,这样的函数难以测试,不设置thread-local变量甚至无法运行。brpc中有三套机制解决和thread-local相关的问题。
### session-local
@@ -637,7 +637,7 @@ struct ServerOptions {
**实现session_local_data_factory**
-session_local_data_factory的类型为[DataFactory](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/brpc/data_factory.h),你需要实现其中的CreateData和DestroyData。
+session_local_data_factory的类型为[DataFactory](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/brpc/data_factory.h),你需要实现其中的CreateData和DestroyData。
注意:CreateData和DestroyData会被多个线程同时调用,必须线程安全。
@@ -723,7 +723,7 @@ struct ServerOptions {
**实现thread_local_data_factory:**
-thread_local_data_factory的类型为[DataFactory](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/brpc/data_factory.h),你需要实现其中的CreateData和DestroyData。
+thread_local_data_factory的类型为[DataFactory](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/brpc/data_factory.h),你需要实现其中的CreateData和DestroyData。
注意:CreateData和DestroyData会被多个线程同时调用,必须线程安全。
@@ -755,11 +755,11 @@ Session-local和server-thread-local对大部分server已经够用。不过在一
这些函数同时支持bthread和pthread,当它们在bthread中被调用时,获得的是bthread私有变量,而当它们在pthread中被调用时,获得的是pthread私有变量。但注意,这里的“pthread私有变量”不是pthread_key_create创建的pthread-local,使用pthread_key_create创建的pthread-local是无法被bthread_getspecific访问到的,这是两个独立的体系。由于pthread与LWP是1:1的关系,由gcc的__thread,c++11的thread_local等声明的变量也可视作pthread-local,同样无法被bthread_getspecific访问到。
-由于baidu-rpc会为每个请求建立一个bthread,server中的bthread-local行为特殊:当一个检索bthread退出时,它并不删除bthread-local,而是还回server的一个pool中,以被其他bthread复用。这可以避免bthread-local随着bthread的创建和退出而不停地构造和析构。这对于用户是透明的。
+由于brpc会为每个请求建立一个bthread,server中的bthread-local行为特殊:当一个检索bthread退出时,它并不删除bthread-local,而是还回server的一个pool中,以被其他bthread复用。这可以避免bthread-local随着bthread的创建和退出而不停地构造和析构。这对于用户是透明的。
-**在使用bthread-local前确保baidu-rpc的版本 >= 1.0.130.31109**
+**在使用bthread-local前确保brpc的版本 >= 1.0.130.31109**
-在那个版本之前的bthread-local没有在不同bthread间重用线程私有的存储(keytable)。由于baidu-rpc server会为每个请求创建一个bthread, bthread-local函数会频繁地创建和删除thread-local数据,性能表现不佳。之前的实现也无法在pthread中使用。
+在那个版本之前的bthread-local没有在不同bthread间重用线程私有的存储(keytable)。由于brpc server会为每个请求创建一个bthread, bthread-local函数会频繁地创建和删除thread-local数据,性能表现不佳。之前的实现也无法在pthread中使用。
**主要接口:**
@@ -784,11 +784,11 @@ extern int bthread_key_delete(bthread_key_t key) __THROW;
// bthread_setspecific() is callable from within destructor. If the application
// does so, destructors will be repeatedly called for at most
// PTHREAD_DESTRUCTOR_ITERATIONS times to clear the slots.
-// NOTE: If the thread is not created by baidu-rpc server and lifetime is
+// NOTE: If the thread is not created by brpc server and lifetime is
// very short(doing a little thing and exit), avoid using bthread-local. The
// reason is that bthread-local always allocate keytable on first call to
// bthread_setspecific, the overhead is negligible in long-lived threads,
-// but noticeable in shortly-lived threads. Threads in baidu-rpc server
+// but noticeable in shortly-lived threads. Threads in brpc server
// are special since they reuse keytables from a bthread_keytable_pool_t
// in the server.
// Returns 0 on success, error code otherwise.
@@ -885,7 +885,7 @@ A: 一般是client端使用了连接池或短连接模式,在RPC超时后会
### Q: 为什么server端线程数设了没用
-baidu-rpc同一个进程中所有的server[共用线程](#worker线程数),如果创建了多个server,最终的工作线程数是最大的那个。
+brpc同一个进程中所有的server[共用线程](#worker线程数),如果创建了多个server,最终的工作线程数是最大的那个。
### Q: 为什么client端的延时远大于server端的延时
@@ -893,7 +893,7 @@ baidu-rpc同一个进程中所有的server[共用线程](#worker线程数),如
### Q: 程序切换到rpc之后,会出现莫名其妙的core,像堆栈被写坏
-baidu-rpc的Server是运行在bthread之上,默认栈大小为1M,而pthread默认栈大小为10M,所以在pthread上正常运行的程序,在bthread上可能遇到栈不足。
+brpc的Server是运行在bthread之上,默认栈大小为1M,而pthread默认栈大小为10M,所以在pthread上正常运行的程序,在bthread上可能遇到栈不足。
解决方案:添加以下gflag,调整栈大小。第一个表示调整栈大小为10M左右,如有必要,可以更大。第二个表示每个工作线程cache的栈个数
diff --git a/docs/cn/server_debugging.md b/docs/cn/server_debugging.md
index 113aac57ca..ae807be67b 100644
--- a/docs/cn/server_debugging.md
+++ b/docs/cn/server_debugging.md
@@ -158,6 +158,6 @@ void search() {
你可以在子函数中继续这个过程,增加更多bvar,并比对不同的分布,最后定位来源。
-### 只使用了baidu-rpc client
+### 只使用了brpc client
得打开dummy server提供内置服务,方法见[这里](dummy_server.md)。
diff --git a/docs/cn/status.md b/docs/cn/status.md
index 1b5517d8f4..18961e800d 100644
--- a/docs/cn/status.md
+++ b/docs/cn/status.md
@@ -18,7 +18,7 @@
- **processing**: 正在处理的请求个数。如果持续不为0(特别是在压力归0后),应考虑程序是否有bug。
-用户可通过让对应Service实现[brpc::Describable](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/brpc/describable.h)自定义在/status页面上的描述.
+用户可通过让对应Service实现[brpc::Describable](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/brpc/describable.h)自定义在/status页面上的描述.
```c++
class MyService : public XXXService, public brpc::Describable {
diff --git a/docs/cn/streaming_log.md b/docs/cn/streaming_log.md
index ac35cba9ae..71579f0c1a 100644
--- a/docs/cn/streaming_log.md
+++ b/docs/cn/streaming_log.md
@@ -321,4 +321,4 @@ TEST_F(StreamingLogTest, log_at) {
定义在base/comlog_sink.h中,把日志打印入comlog,主要用于线上系统,用法见[SYNOPSIS](#SYNOPSIS)一段。
-使用ComlogSink的streaming log可以和com_writelog, ul_writelog混用。你并不需要把程序中所有日志都换成streaming log。
\ No newline at end of file
+使用ComlogSink的streaming log可以和com_writelog, ul_writelog混用。你并不需要把程序中所有日志都换成streaming log。
diff --git a/docs/cn/streaming_rpc.md b/docs/cn/streaming_rpc.md
index 183af20466..82d1356195 100644
--- a/docs/cn/streaming_rpc.md
+++ b/docs/cn/streaming_rpc.md
@@ -17,7 +17,7 @@ Streaming RPC保证:
目前的实现还没有自动切割过大的消息,同一个tcp连接上的多个Stream之间可能有[Head-of-line blocking](https://en.wikipedia.org/wiki/Head-of-line_blocking)问题,请尽量避免过大的单个消息,实现自动切割后我们会告知并更新文档。
-例子见[example/streaming_echo_c++](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/tree/example/streaming_echo_c++/)。
+例子见[example/streaming_echo_c++](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/tree/example/streaming_echo_c++/)。
# 建立Stream
diff --git a/docs/cn/thread_local.md b/docs/cn/thread_local.md
index 2f5e6a21bc..f8e1a491ea 100644
--- a/docs/cn/thread_local.md
+++ b/docs/cn/thread_local.md
@@ -62,4 +62,4 @@ Use *p ... - still the errno of original pthread, undefined b
把`__const__`定义为空对程序其他部分的影响几乎为0。另外如果你没有**直接**使用errno(即你的项目中没有出现errno),或使用的是gcc
3.4,即使没有定义`-D__const__=`,程序的正确性也不会受影响,但为了防止未来可能的问题,我们强烈建议加上。
-需要说明的是,和errno类似,pthread_self也有类似的问题,不过一般pthread_self除了打日志没有其他用途,影响面较小,在`-D__const__=`后pthread_self也会正常。
\ No newline at end of file
+需要说明的是,和errno类似,pthread_self也有类似的问题,不过一般pthread_self除了打日志没有其他用途,影响面较小,在`-D__const__=`后pthread_self也会正常。
diff --git a/docs/cn/timer_keeping.md b/docs/cn/timer_keeping.md
index 6def7a01ee..55213b0bbe 100644
--- a/docs/cn/timer_keeping.md
+++ b/docs/cn/timer_keeping.md
@@ -22,7 +22,7 @@
另外,更并发的数据结构也难以奏效,感兴趣的同学可以去搜索"concurrent priority queue"或"concurrent skip list",这些数据结构一般假设插入的数值较为散开,所以可以同时修改结构内的不同部分。但这在RPC场景中也不成立,相互竞争的线程设定的时间往往聚集在同一个区域,因为程序的超时大都是一个值,加上当前时间后都差不多。
-这些因素让TimerThread的设计相当棘手。由于大部分用户的qps较低,不足以明显暴露这个扩展性问题,在r31791前我们一直沿用“用一把锁保护的TimerThread”。TimerThread是baidu-rpc在默认配置下唯一的高频竞争点,这个问题是我们一直清楚的技术债。随着baidu-rpc在高qps系统中应用越来越多,是时候解决这个问题了。r31791后的TimerThread解决了上述三个难点,timer操作几乎对RPC性能没有影响,我们先看下性能差异。
+这些因素让TimerThread的设计相当棘手。由于大部分用户的qps较低,不足以明显暴露这个扩展性问题,在r31791前我们一直沿用“用一把锁保护的TimerThread”。TimerThread是brpc在默认配置下唯一的高频竞争点,这个问题是我们一直清楚的技术债。随着brpc在高qps系统中应用越来越多,是时候解决这个问题了。r31791后的TimerThread解决了上述三个难点,timer操作几乎对RPC性能没有影响,我们先看下性能差异。
> 在示例程序example/mutli_threaded_echo_c++中,r31791后TimerThread相比老TimerThread在24核E5-2620上(超线程),以50个bthread同步发送时,节省4%cpu(差不多1个核),qps提升10%左右;在400个bthread同步发送时,qps从30万上升到60万。新TimerThread的表现和完全关闭超时时接近。
@@ -34,7 +34,7 @@
- 删除时通过id直接定位到timer内存结构,修改一个标志,timer结构总是由TimerThread释放。
- TimerThread被唤醒后首先把全局nearest_run_time设置为几乎无限大(max of int64),然后取出所有Bucket内的链表,并把Bucket的nearest_run_time设置为几乎无限大(max of int64)。TimerThread把未删除的timer插入小顶堆中维护,这个堆就它一个线程用。在每次运行回调或准备睡眠前都会检查全局nearest_run_time, 如果全局更早,说明有更早的时间加入了,重复这个过程。
-这里勾勒了TimerThread的大致工作原理,工程实现中还有不少细节问题,具体请阅读[timer_thread.h](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/bthread/timer_thread.h)和[timer_thread.cpp](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/bthread/timer_thread.cpp)。
+这里勾勒了TimerThread的大致工作原理,工程实现中还有不少细节问题,具体请阅读[timer_thread.h](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/bthread/timer_thread.h)和[timer_thread.cpp](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/src/bthread/timer_thread.cpp)。
这个方法之所以有效:
@@ -46,10 +46,10 @@
- TimerThread自己维护小顶堆,没有任何cache bouncing,效率很高。
- TimerThread醒来的频率大约是RPC超时的倒数,比如超时=100ms,TimerThread一秒内大约醒10次,已经最优。
-至此baidu-rpc在默认配置下不再有全局竞争点,在400个线程同时运行时,profiling也显示几乎没有对锁的等待。
+至此brpc在默认配置下不再有全局竞争点,在400个线程同时运行时,profiling也显示几乎没有对锁的等待。
下面是一些和linux下时间管理相关的知识:
- epoll_wait的超时精度是毫秒,较差。pthread_cond_timedwait的超时使用timespec,精度到纳秒,一般是60微秒左右的延时。
- 出于性能考虑,TimerThread使用wall-time,而不是单调时间,可能受到系统时间调整的影响。具体来说,如果在测试中把系统时间往前或往后调一个小时,程序行为将完全undefined。未来可能会让用户选择单调时间。
-- 在cpu支持nonstop_tsc和constant_tsc的机器上,baidu-rpc和bthread会优先使用基于rdtsc的cpuwide_time_us。那两个flag表示rdtsc可作为wall-time使用,不支持的机器上会转而使用较慢的内核时间。我们的机器(Intel Xeon系列)大都有那两个flag。rdtsc作为wall-time使用时是否会受到系统调整时间的影响,未测试不清楚。
+- 在cpu支持nonstop_tsc和constant_tsc的机器上,brpc和bthread会优先使用基于rdtsc的cpuwide_time_us。那两个flag表示rdtsc可作为wall-time使用,不支持的机器上会转而使用较慢的内核时间。我们的机器(Intel Xeon系列)大都有那两个flag。rdtsc作为wall-time使用时是否会受到系统调整时间的影响,未测试不清楚。
diff --git a/docs/cn/ub_client.md b/docs/cn/ub_client.md
index 30fe15ba13..4ea75bf274 100644
--- a/docs/cn/ub_client.md
+++ b/docs/cn/ub_client.md
@@ -1,12 +1,12 @@
-baidu-rpc可通过多种方式访问用ub搭建的服务。
+brpc可通过多种方式访问用ub搭建的服务。
# ubrpc (by protobuf)
-r31687后,baidu-rpc支持通过protobuf访问ubrpc,不需要baidu-rpc-ub,也不依赖idl-compiler。(也可以让protobuf服务被ubrpc client访问,方法见[使用ubrpc的服务](nshead_service.md#使用ubrpc的服务))。
+r31687后,brpc支持通过protobuf访问ubrpc,不需要baidu-rpc-ub,也不依赖idl-compiler。(也可以让protobuf服务被ubrpc client访问,方法见[使用ubrpc的服务](nshead_service.md#使用ubrpc的服务))。
**步骤:**
-1. 用[idl2proto](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/tools/idl2proto)把idl文件转化为proto文件,老版本idl2proto不会转化idl中的service,需要手动转化。
+1. 用[idl2proto](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/tools/idl2proto)把idl文件转化为proto文件,老版本idl2proto不会转化idl中的service,需要手动转化。
```protobuf
// Converted from echo.idl by public/mcpack2pb/idl2proto
@@ -146,7 +146,7 @@ r31687后,baidu-rpc支持通过protobuf访问ubrpc,不需要baidu-rpc-ub,
// cntl.idl_result();
```
- 例子详见[example/echo_c++_ubrpc_compack](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/example/echo_c++_ubrpc_compack/)。
+ 例子详见[example/echo_c++_ubrpc_compack](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/example/echo_c++_ubrpc_compack/)。
# ubrpc (by baidu-rpc-ub)
@@ -154,7 +154,7 @@ server端由public/ubrpc搭建,request/response使用idl文件描述字段,
**步骤:**
-1. 依赖[public/baidu-rpc-ub](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob)模块,在COMAKE中增加依赖:`CONFIGS('public/baidu-rpc-ub@ci-base')。`这个模块是baidu-rpc的扩展,不需要的用户不会依赖idl/mcpack/compack等模块。baidu-rpc-ub只包含扩展代码,baidu-rpc中的新特性会自动体现在这个模块中。
+1. 依赖[public/baidu-rpc-ub](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob)模块,在COMAKE中增加依赖:`CONFIGS('public/baidu-rpc-ub@ci-base')。`这个模块是brpc的扩展,不需要的用户不会依赖idl/mcpack/compack等模块。baidu-rpc-ub只包含扩展代码,brpc中的新特性会自动体现在这个模块中。
2. 编写一个proto文件,其中定义了service,名字和idl中的相同,但请求类型必须是baidu.rpc.UBRequest,回复类型必须是baidu.rpc.UBResponse。这两个类型定义在brpc/ub.proto中,使用时得import。
@@ -219,7 +219,7 @@ server端由public/ubrpc搭建,request/response使用idl文件描述字段,
...
```
- 具体example代码可以参考[echo_c++_compack_ubrpc](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/tree/example/echo_c++_compack_ubrpc/),类似的还有[echo_c++_mcpack_ubrpc](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/tree/example/echo_c++_mcpack_ubrpc/)。
+ 具体example代码可以参考[echo_c++_compack_ubrpc](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/tree/example/echo_c++_compack_ubrpc/),类似的还有[echo_c++_mcpack_ubrpc](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/tree/example/echo_c++_mcpack_ubrpc/)。
# nshead+idl
@@ -258,7 +258,7 @@ channel.CallMethod(NULL, &cntl, &request, &response, NULL); // 假设channel
response.message();
```
-具体example代码可以参考[echo_c++_mcpack_ub](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/example/echo_c++_mcpack_ub/),compack情况类似,不再赘述
+具体example代码可以参考[echo_c++_mcpack_ub](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/example/echo_c++_mcpack_ub/),compack情况类似,不再赘述
# nshead+mcpack(非idl产生的)
@@ -305,11 +305,11 @@ const mc_pack_t* res_pack = response.McpackHandle();
mc_pack_get_str(res_pack, "mystr");
```
-具体example代码可以参考[echo_c++_raw_mcpack](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/example/echo_c++_raw_mcpack/)。
+具体example代码可以参考[echo_c++_raw_mcpack](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/example/echo_c++_raw_mcpack/)。
# nshead+blob
-r32897后baidu-rpc直接支持用nshead+blob访问老server(而不用依赖baidu-rpc-ub)。example代码可以参考[nshead_extension_c++](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/example/nshead_extension_c++/client.cpp)。
+r32897后brpc直接支持用nshead+blob访问老server(而不用依赖baidu-rpc-ub)。example代码可以参考[nshead_extension_c++](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/example/nshead_extension_c++/client.cpp)。
```c++
#include
@@ -342,7 +342,7 @@ if (cntl.Failed()) {
// response.head and response.body contains nshead_t and blob respectively.
```
-或者用户也可以使用baidu-rpc-ub中的UBRawBufferRequest和UBRawBufferResponse来访问。example代码可以参考[echo_c++_raw_buffer](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/example/echo_c++_raw_buffer/)。
+或者用户也可以使用baidu-rpc-ub中的UBRawBufferRequest和UBRawBufferResponse来访问。example代码可以参考[echo_c++_raw_buffer](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/blob/example/echo_c++_raw_buffer/)。
```c++
brpc::Channel channel;
diff --git a/docs/cn/vars.md b/docs/cn/vars.md
index c49780b598..0e9baeccd8 100644
--- a/docs/cn/vars.md
+++ b/docs/cn/vars.md
@@ -1,4 +1,4 @@
-[public/bvar](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/tree/src/bvar/)是多线程环境下的计数器类库,方便记录和查看用户程序中的各类数值,它利用了thread local存储避免了cache bouncing,相比UbMonitor几乎不会给程序增加性能开销,也快于竞争频繁的原子操作。baidu-rpc集成了bvar,[/vars](http://brpc.baidu.com:8765/vars)可查看所有曝光的bvar,[/vars/VARNAME](http://brpc.baidu.com:8765/vars/rpc_socket_count)可查阅某个bvar,增加计数器的方法请查看[bvar](bvar.md)。baidu-rpc大量使用了bvar提供统计数值,当你需要在多线程环境中计数并展现时,应该第一时间想到bvar。但bvar不能代替所有的计数器,它的本质是把写时的竞争转移到了读:读得合并所有写过的线程中的数据,而不可避免地变慢了。当你读写都很频繁并得基于数值做一些逻辑判断时,你不应该用bvar。
+[public/bvar](http://icode.baidu.com/repo/baidu/opensource/brpc/files/master/tree/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,增加计数器的方法请查看[bvar](bvar.md)。brpc大量使用了bvar提供统计数值,当你需要在多线程环境中计数并展现时,应该第一时间想到bvar。但bvar不能代替所有的计数器,它的本质是把写时的竞争转移到了读:读得合并所有写过的线程中的数据,而不可避免地变慢了。当你读写都很频繁并得基于数值做一些逻辑判断时,你不应该用bvar。
## 查询方法
@@ -65,11 +65,11 @@ x%分位值(percentile)是指把一段时间内的N个统计值排序,排
上图是按时间变化曲线。包含了4条曲线,横轴是时间,纵轴从上到下分别对应99.9%,99%,90%,50%分位值。颜色从上到下也越来越浅(从橘红到土黄)。滑动鼠标可以阅读对应数据点的值,上图中显示是”39秒种前的99%分位值是330微秒”。这幅图中不包含99.99%的曲线,因为99.99%分位值常明显大于99.9%及以下的分位值,画在一起的话会使得其他曲线变得很”矮“,难以辨认。你可以点击以"_latency_9999"结尾的bvar独立查看99.99%曲线,当然,你也可以独立查看50%,90%,99%,99.9%等曲线。按时间变化曲线可以看到分位值的变化趋势,对分析系统的性能变化很实用。
-baidu-rpc的服务都会自动统计延时分布,用户不用自己加了。如下图所示:
+brpc的服务都会自动统计延时分布,用户不用自己加了。如下图所示:
![img](../images/vars_6.png)
-你可以用bvar::LatencyRecorder统计非baidu-rpc服务的延时,这么做(更具体的使用方法请查看[bvar-c++](bvar_c++.md)):
+你可以用bvar::LatencyRecorder统计非brpc服务的延时,这么做(更具体的使用方法请查看[bvar-c++](bvar_c++.md)):
```c++
#include
@@ -84,10 +84,10 @@ void foo() {
}
```
-如果这个程序使用了baidu-rpc server,那么你应该已经可以在/vars看到client_latency, client_latency_cdf等变量,点击便可查看动态曲线。如下图所示:
+如果这个程序使用了brpc server,那么你应该已经可以在/vars看到client_latency, client_latency_cdf等变量,点击便可查看动态曲线。如下图所示:
![img](../images/vars_7.png)
-## 非baidu-rpc server
+## 非brpc server
-如果这个程序只是一个baidu-rpc client或根本没有使用baidu-rpc,并且你也想看到动态曲线,看[这里](dummy_server.md)。
+如果这个程序只是一个brpc client或根本没有使用brpc,并且你也想看到动态曲线,看[这里](dummy_server.md)。
diff --git a/example/http_c++/http_client.cpp b/example/http_c++/http_client.cpp
index 115c7f13a5..8b152f6a15 100644
--- a/example/http_c++/http_client.cpp
+++ b/example/http_c++/http_client.cpp
@@ -75,7 +75,7 @@ int main(int argc, char* argv[]) {
std::cerr << cntl.ErrorText() << std::endl;
return -1;
}
- // If -http_verbose is on, baidu-rpc already prints the response to stderr.
+ // If -http_verbose is on, brpc already prints the response to stderr.
if (!brpc::FLAGS_http_verbose) {
std::cout << cntl.response_attachment() << std::endl;
}
diff --git a/example/nshead_extension_c++/server.cpp b/example/nshead_extension_c++/server.cpp
index a1d7012959..6b231acc56 100644
--- a/example/nshead_extension_c++/server.cpp
+++ b/example/nshead_extension_c++/server.cpp
@@ -24,7 +24,7 @@ DEFINE_int32(idle_timeout_s, -1, "Connection will be closed if there is no "
"read/write operations during the last `idle_timeout_s'");
DEFINE_int32(max_concurrency, 0, "Limit of request processing in parallel");
-// Adapt your own nshead-based protocol to use baidu-rpc
+// Adapt your own nshead-based protocol to use brpc
class MyNsheadProtocol : public brpc::NsheadService {
public:
void ProcessNsheadRequest(const brpc::Server&,
diff --git a/example/parallel_echo_c++/client.cpp b/example/parallel_echo_c++/client.cpp
index c60f80d97a..fc97426dfb 100644
--- a/example/parallel_echo_c++/client.cpp
+++ b/example/parallel_echo_c++/client.cpp
@@ -111,7 +111,7 @@ int main(int argc, char* argv[]) {
// channels are disabled in ParallelChannel.
if (FLAGS_same_channel) {
- // For baidu-rpc >= 1.0.155.31351, a sub channel can be added into
+ // For brpc >= 1.0.155.31351, a sub channel can be added into
// a ParallelChannel more than once.
brpc::Channel* sub_channel = new brpc::Channel;
// Initialize the channel, NULL means using default options.
diff --git a/example/redis_c++/redis_cli.cpp b/example/redis_c++/redis_cli.cpp
index 440ceab0d9..f7f85a338a 100644
--- a/example/redis_c++/redis_cli.cpp
+++ b/example/redis_c++/redis_cli.cpp
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-// A baidu-rpc based command-line interface to talk with redis-server
+// A brpc based command-line interface to talk with redis-server
#include
#include
@@ -102,7 +102,7 @@ int main(int argc, char* argv[]) {
// Print welcome information.
printf("%s\n", brpc::logo());
printf("This command-line tool mimics the look-n-feel of official "
- "redis-cli, as a demostration of baidu-rpc's capability of"
+ "redis-cli, as a demostration of brpc's capability of"
" talking to redis-server. The output and behavior is "
"not exactly same with the official one.\n\n");
@@ -129,7 +129,7 @@ int main(int argc, char* argv[]) {
add_history(command.get());
if (!strcmp(command.get(), "help")) {
- printf("This is a redis CLI written in baidu-rpc.\n");
+ printf("This is a redis CLI written in brpc.\n");
continue;
}
if (!strcmp(command.get(), "quit")) {
diff --git a/src/base/third_party/valgrind/LICENSE b/src/base/third_party/valgrind/LICENSE
index 2a121f7528..0c29118cca 100644
--- a/src/base/third_party/valgrind/LICENSE
+++ b/src/base/third_party/valgrind/LICENSE
@@ -1,5 +1,5 @@
Notice that the following BSD-style license applies to the Valgrind header
- files used by baidu-rpc (valgrind.h). However, the rest of Valgrind is
+ files used by brpc (valgrind.h). However, the rest of Valgrind is
licensed under the terms of the GNU General Public License, version 2,
unless otherwise indicated.
diff --git a/src/brpc/adaptive_connection_type.h b/src/brpc/adaptive_connection_type.h
index f98ab9fa78..52b1ec6ec2 100644
--- a/src/brpc/adaptive_connection_type.h
+++ b/src/brpc/adaptive_connection_type.h
@@ -17,7 +17,7 @@
#ifndef BRPC_ADAPTIVE_CONNECTION_TYPE_H
#define BRPC_ADAPTIVE_CONNECTION_TYPE_H
-// To baidu-rpc developers: This is a header included by user, don't depend
+// To brpc developers: This is a header included by user, don't depend
// on internal structures, use opaque pointers instead.
#include "base/strings/string_piece.h"
diff --git a/src/brpc/adaptive_protocol_type.h b/src/brpc/adaptive_protocol_type.h
index caa99ca160..de5d6f57b0 100644
--- a/src/brpc/adaptive_protocol_type.h
+++ b/src/brpc/adaptive_protocol_type.h
@@ -15,7 +15,7 @@
#ifndef BRPC_ADAPTIVE_PROTOCOL_TYPE_H
#define BRPC_ADAPTIVE_PROTOCOL_TYPE_H
-// To baidu-rpc developers: This is a header included by user, don't depend
+// To brpc developers: This is a header included by user, don't depend
// on internal structures, use opaque pointers instead.
#include "base/strings/string_piece.h"
diff --git a/src/brpc/builtin/common.h b/src/brpc/builtin/common.h
index 247ee1546f..c6e7dca65d 100644
--- a/src/brpc/builtin/common.h
+++ b/src/brpc/builtin/common.h
@@ -27,7 +27,7 @@ namespace brpc {
class Controller;
-// These static strings are referenced more than once in baidu-rpc.
+// These static strings are referenced more than once in brpc.
// Don't turn them to std::strings whose constructing sequences are undefined.
const char* const UNKNOWN_METHOD_STR = "unknown_method";
const char* const TRACE_ID_STR = "trace";
diff --git a/src/brpc/channel.h b/src/brpc/channel.h
index f13be5fbed..9edc0026f0 100644
--- a/src/brpc/channel.h
+++ b/src/brpc/channel.h
@@ -18,7 +18,7 @@
#ifndef BRPC_CHANNEL_H
#define BRPC_CHANNEL_H
-// To baidu-rpc developers: This is a header included by user, don't depend
+// To brpc developers: This is a header included by user, don't depend
// on internal structures, use opaque pointers instead.
#include // std::ostream
diff --git a/src/brpc/channel_base.h b/src/brpc/channel_base.h
index fe0dceca8b..709f80dd9f 100644
--- a/src/brpc/channel_base.h
+++ b/src/brpc/channel_base.h
@@ -23,13 +23,13 @@
#include // google::protobuf::RpcChannel
#include "brpc/describable.h"
-// To baidu-rpc developers: This is a header included by user, don't depend
+// To brpc developers: This is a header included by user, don't depend
// on internal structures, use opaque pointers instead.
namespace brpc {
-// Base of all baidu-rpc channels.
+// Base of all brpc channels.
class ChannelBase : public google::protobuf::RpcChannel/*non-copyable*/,
public Describable {
public:
diff --git a/src/brpc/controller.h b/src/brpc/controller.h
index 5aab4003df..137466c487 100644
--- a/src/brpc/controller.h
+++ b/src/brpc/controller.h
@@ -17,7 +17,7 @@
#ifndef BRPC_CONTROLLER_H
#define BRPC_CONTROLLER_H
-// To baidu-rpc developers: This is a header included by user, don't depend
+// To brpc developers: This is a header included by user, don't depend
// on internal structures, use opaque pointers instead.
#include // Users often need gflags
diff --git a/src/brpc/data_factory.h b/src/brpc/data_factory.h
index dc53b71e71..3f04a5daf8 100644
--- a/src/brpc/data_factory.h
+++ b/src/brpc/data_factory.h
@@ -17,7 +17,7 @@
#ifndef BRPC_DATA_FACTORY_H
#define BRPC_DATA_FACTORY_H
-// To baidu-rpc developers: This is a header included by user, don't depend
+// To brpc developers: This is a header included by user, don't depend
// on internal structures, use opaque pointers instead.
namespace brpc {
diff --git a/src/brpc/details/controller_private_accessor.h b/src/brpc/details/controller_private_accessor.h
index bad625d25f..d7f6164109 100644
--- a/src/brpc/details/controller_private_accessor.h
+++ b/src/brpc/details/controller_private_accessor.h
@@ -130,7 +130,7 @@ class ControllerPrivateAccessor {
};
// Inherit this class to intercept Controller::IssueRPC. This is an internal
-// utility only useable by baidu-rpc developers.
+// utility only useable by brpc developers.
class RPCSender {
public:
virtual ~RPCSender() {}
diff --git a/src/brpc/details/http_message.cpp b/src/brpc/details/http_message.cpp
index ad0838ca5b..4b2e977c7c 100644
--- a/src/brpc/details/http_message.cpp
+++ b/src/brpc/details/http_message.cpp
@@ -579,7 +579,7 @@ void SerializeHttpRequest(base::IOBuf* request,
}
// The fake "curl" user-agent may let servers return plain-text results.
if (h->GetHeader("User-Agent") == NULL) {
- os << "User-Agent: baidu-rpc/1.0 curl/7.0" BRPC_CRLF;
+ os << "User-Agent: brpc/1.0 curl/7.0" BRPC_CRLF;
}
const std::string& user_info = h->uri().user_info();
if (!user_info.empty() && h->GetHeader("Authorization") == NULL) {
diff --git a/src/brpc/nshead_service.h b/src/brpc/nshead_service.h
index 3d943fa87e..26957a4e67 100644
--- a/src/brpc/nshead_service.h
+++ b/src/brpc/nshead_service.h
@@ -81,7 +81,7 @@ struct NsheadServiceOptions {
size_t additional_space;
};
-// Inherit this class to let baidu-rpc server understands nshead requests.
+// Inherit this class to let brpc server understands nshead requests.
class NsheadService : public Describable {
public:
NsheadService();
diff --git a/src/brpc/parallel_channel.h b/src/brpc/parallel_channel.h
index eef94f267f..ad1e569aea 100644
--- a/src/brpc/parallel_channel.h
+++ b/src/brpc/parallel_channel.h
@@ -17,7 +17,7 @@
#ifndef BRPC_PARALLEL_CHANNEL_H
#define BRPC_PARALLEL_CHANNEL_H
-// To baidu-rpc developers: This is a header included by user, don't depend
+// To brpc developers: This is a header included by user, don't depend
// on internal structures, use opaque pointers instead.
#include
diff --git a/src/brpc/partition_channel.h b/src/brpc/partition_channel.h
index f66185625a..c0b731933c 100644
--- a/src/brpc/partition_channel.h
+++ b/src/brpc/partition_channel.h
@@ -17,7 +17,7 @@
#ifndef BRPC_PARTITION_CHANNEL_H
#define BRPC_PARTITION_CHANNEL_H
-// To baidu-rpc developers: This is a header included by user, don't depend
+// To brpc developers: This is a header included by user, don't depend
// on internal structures, use opaque pointers instead.
#include "brpc/parallel_channel.h"
diff --git a/src/brpc/policy/http_rpc_protocol.cpp b/src/brpc/policy/http_rpc_protocol.cpp
index 84d5f43764..713ae80461 100644
--- a/src/brpc/policy/http_rpc_protocol.cpp
+++ b/src/brpc/policy/http_rpc_protocol.cpp
@@ -58,7 +58,7 @@ DEFINE_int32(http_body_compress_threshold, 512, "Not compress http body when "
DEFINE_string(http_header_of_user_ip, "", "http requests sent by proxies may "
"set the client ip in http headers. When this flag is non-empty, "
- "baidu-rpc will read ip:port from the specified header for "
+ "brpc will read ip:port from the specified header for "
"authorization and set Controller::remote_side()");
DEFINE_bool(pb_enum_as_number, false, "[Not recommended] Convert enums in "
@@ -100,7 +100,7 @@ CommonStrings::CommonStrings()
: ACCEPT("accept")
, DEFAULT_ACCEPT("*/*")
, USER_AGENT("user-agent")
- , DEFAULT_USER_AGENT("baidu-rpc/1.0 curl/7.0")
+ , DEFAULT_USER_AGENT("brpc/1.0 curl/7.0")
, CONTENT_TYPE("content-type")
, CONTENT_TYPE_TEXT("text/plain")
, CONTENT_TYPE_JSON("application/json")
diff --git a/src/brpc/protocol.cpp b/src/brpc/protocol.cpp
index 38fe43f457..2792acdfe4 100644
--- a/src/brpc/protocol.cpp
+++ b/src/brpc/protocol.cpp
@@ -48,7 +48,7 @@ DEFINE_bool(log_error_text, false,
BRPC_VALIDATE_GFLAG(log_error_text, PassValidate);
// Not using ProtocolType_MAX as the boundary because others may define new
-// protocols outside baidu-rpc.
+// protocols outside brpc.
const size_t MAX_PROTOCOL_SIZE = 128;
struct ProtocolEntry {
base::atomic valid;
diff --git a/src/brpc/protocol.h b/src/brpc/protocol.h
index 3903f4450b..b152f60a4d 100644
--- a/src/brpc/protocol.h
+++ b/src/brpc/protocol.h
@@ -18,7 +18,7 @@
#ifndef BRPC_PROTOCOL_H
#define BRPC_PROTOCOL_H
-// To baidu-rpc developers: This is a header included by user, don't depend
+// To brpc developers: This is a header included by user, don't depend
// on internal structures, use opaque pointers instead.
#include // std::vector
diff --git a/src/brpc/reloadable_flags.h b/src/brpc/reloadable_flags.h
index c0f4f9168f..b37c27cd5c 100644
--- a/src/brpc/reloadable_flags.h
+++ b/src/brpc/reloadable_flags.h
@@ -17,13 +17,13 @@
#ifndef BRPC_RELOADABLE_FLAGS_H
#define BRPC_RELOADABLE_FLAGS_H
-// To baidu-rpc developers: This is a header included by user, don't depend
+// To brpc developers: This is a header included by user, don't depend
// on internal structures, use opaque pointers instead.
#include
// Register an always-true valiator to a gflag so that the gflag is treated as
-// reloadable by baidu-rpc. If a validator exists, abort the program.
+// reloadable by brpc. If a validator exists, abort the program.
// You should call this macro within global scope. for example:
//
// DEFINE_int32(foo, 0, "blah blah");
diff --git a/src/brpc/retry_policy.h b/src/brpc/retry_policy.h
index 965b9cbc29..f7e45e522c 100644
--- a/src/brpc/retry_policy.h
+++ b/src/brpc/retry_policy.h
@@ -68,7 +68,7 @@ class RetryPolicy {
// don't forget the const modifier
};
-// Get the RetryPolicy used by baidu-rpc.
+// Get the RetryPolicy used by brpc.
const RetryPolicy* DefaultRetryPolicy();
} // namespace brpc
diff --git a/src/brpc/selective_channel.h b/src/brpc/selective_channel.h
index 6f8f77d116..3f63f3a967 100644
--- a/src/brpc/selective_channel.h
+++ b/src/brpc/selective_channel.h
@@ -17,7 +17,7 @@
#ifndef BRPC_SELECTIVE_CHANNEL_H
#define BRPC_SELECTIVE_CHANNEL_H
-// To baidu-rpc developers: This is a header included by user, don't depend
+// To brpc developers: This is a header included by user, don't depend
// on internal structures, use opaque pointers instead.
#include "brpc/socket_id.h"
diff --git a/src/brpc/server.h b/src/brpc/server.h
index 7bebaa9c7e..b968edfa6c 100644
--- a/src/brpc/server.h
+++ b/src/brpc/server.h
@@ -18,7 +18,7 @@
#ifndef BRPC_SERVER_H
#define BRPC_SERVER_H
-// To baidu-rpc developers: This is a header included by user, don't depend
+// To brpc developers: This is a header included by user, don't depend
// on internal structures, use opaque pointers instead.
#include "bthread/errno.h" // Redefine errno
@@ -157,7 +157,7 @@ struct ServerOptions {
// you can't assume that the server uses exactly so many pthreads because
// pthread workers are shared by all servers and channels inside a
// process. And there're no "io-thread" and "worker-thread" anymore,
- // baidu-rpc automatically schedules "io" and "worker" code for better
+ // brpc automatically schedules "io" and "worker" code for better
// parallelism and less context switches.
// If this option <= 0, number of pthread workers is not changed.
// Default: #cpu-cores
@@ -167,7 +167,7 @@ struct ServerOptions {
// concurrency of a method, use server.MaxConcurrencyOf("xxx") instead.
//
// In a traditional server, number of pthread workers also limits
- // concurrency. However baidu-rpc runs requests in bthreads which are
+ // concurrency. However brpc runs requests in bthreads which are
// mapped to pthread workers, when a bthread context switches, it gives
// the pthread worker to another bthread, yielding a higher concurrency
// than number of pthreads. In some situation, higher concurrency may
@@ -326,7 +326,7 @@ struct ServiceOptions {
// when the pb schema is non-empty in http servings. The body must be
// valid json or protobuf(wire-format) otherwise the request is rejected.
// This option does not affect pure-http services (pb schema is empty).
- // Services that use older versions of baidu-rpc may need to turn this
+ // Services that use older versions of brpc may need to turn this
// conversion off and handle http requests by their own to keep compatible
// with existing clients.
// Default: true
diff --git a/src/brpc/server_id.h b/src/brpc/server_id.h
index f250f689e2..0f92d66a6c 100644
--- a/src/brpc/server_id.h
+++ b/src/brpc/server_id.h
@@ -17,7 +17,7 @@
#ifndef BRPC_SERVER_ID_H
#define BRPC_SERVER_ID_H
-// To baidu-rpc developers: This is a header included by user, don't depend
+// To brpc developers: This is a header included by user, don't depend
// on internal structures, use opaque pointers instead.
#include "base/containers/hash_tables.h" // hash
diff --git a/src/brpc/socket_id.h b/src/brpc/socket_id.h
index 8753492e70..324d8b6bc1 100644
--- a/src/brpc/socket_id.h
+++ b/src/brpc/socket_id.h
@@ -17,7 +17,7 @@
#ifndef BRPC_SOCKET_ID_H
#define BRPC_SOCKET_ID_H
-// To baidu-rpc developers: This is a header included by user, don't depend
+// To brpc developers: This is a header included by user, don't depend
// on internal structures, use opaque pointers instead.
#include // uint64_t
diff --git a/src/brpc/traceprintf.h b/src/brpc/traceprintf.h
index f69d723967..5cc2edf084 100644
--- a/src/brpc/traceprintf.h
+++ b/src/brpc/traceprintf.h
@@ -19,7 +19,7 @@
#include "base/macros.h"
-// To baidu-rpc developers: This is a header included by user, don't depend
+// To brpc developers: This is a header included by user, don't depend
// on internal structures, use opaque pointers instead.
diff --git a/src/brpc/trackme.cpp b/src/brpc/trackme.cpp
index e7207dfb84..68cba01d6f 100644
--- a/src/brpc/trackme.cpp
+++ b/src/brpc/trackme.cpp
@@ -155,11 +155,11 @@ static void HandleTrackMeResponse(Controller* cntl, TrackMeResponse* res) {
case TrackMeOK:
break;
case TrackMeFatal:
- LOG(ERROR) << "Your baidu-rpc (r" << g_rpc_version
+ LOG(ERROR) << "Your brpc (r" << g_rpc_version
<< ") is affected by: " << res->error_text();
break;
case TrackMeWarning:
- LOG(WARNING) << "Your baidu-rpc (r" << g_rpc_version
+ LOG(WARNING) << "Your brpc (r" << g_rpc_version
<< ") is affected by: " << res->error_text();
break;
default:
diff --git a/src/brpc/uri.h b/src/brpc/uri.h
index 02d226db14..e52a466051 100644
--- a/src/brpc/uri.h
+++ b/src/brpc/uri.h
@@ -23,7 +23,7 @@
#include "base/status.h"
#include "base/string_splitter.h"
-// To baidu-rpc developers: This is a class exposed to end-user. DON'T put impl.
+// To brpc developers: This is a class exposed to end-user. DON'T put impl.
// details in this header, use opaque pointers instead.
diff --git a/src/bthread/bthread.h b/src/bthread/bthread.h
index 6e0c6503ba..2663f08507 100644
--- a/src/bthread/bthread.h
+++ b/src/bthread/bthread.h
@@ -283,11 +283,11 @@ extern int bthread_key_delete(bthread_key_t key) __THROW;
// bthread_setspecific() is callable from within destructor. If the application
// does so, destructors will be repeatedly called for at most
// PTHREAD_DESTRUCTOR_ITERATIONS times to clear the slots.
-// NOTE: If the thread is not created by baidu-rpc server and lifetime is
+// NOTE: If the thread is not created by brpc server and lifetime is
// very short(doing a little thing and exit), avoid using bthread-local. The
// reason is that bthread-local always allocate keytable on first call to
// bthread_setspecific, the overhead is negligible in long-lived threads,
-// but noticeable in shortly-lived threads. Threads in baidu-rpc server
+// but noticeable in shortly-lived threads. Threads in brpc server
// are special since they reuse keytables from a bthread_keytable_pool_t
// in the server.
// Returns 0 on success, error code otherwise.
diff --git a/src/bthread/list_of_abafree_id.h b/src/bthread/list_of_abafree_id.h
index 5424fa5f83..b1f9a421c3 100644
--- a/src/bthread/list_of_abafree_id.h
+++ b/src/bthread/list_of_abafree_id.h
@@ -55,7 +55,7 @@ namespace bthread {
// }
// This container is NOT thread-safe right now, and shouldn't be
-// an issue in current usages throughout baidu-rpc.
+// an issue in current usages throughout brpc.
template
class ListOfABAFreeId {
public:
diff --git a/src/bthread/task_group_inl.h b/src/bthread/task_group_inl.h
index 97e9c3bf90..7aab041e53 100644
--- a/src/bthread/task_group_inl.h
+++ b/src/bthread/task_group_inl.h
@@ -83,7 +83,7 @@ inline void TaskGroup::push_rq(bthread_t tid) {
// into other TaskGroup does not help.
// * Insertions into other TaskGroups perform worse when all workers
// are busy at creating bthreads (proved by test_input_messenger in
- // baidu-rpc)
+ // brpc)
flush_nosignal_tasks();
LOG_EVERY_SECOND(ERROR) << "_rq is full, capacity=" << _rq.capacity();
// TODO(gejun): May cause deadlock when all workers are spinning here.
diff --git a/src/bvar/variable.cpp b/src/bvar/variable.cpp
index 0f7c38f0a7..80c4d83535 100644
--- a/src/bvar/variable.cpp
+++ b/src/bvar/variable.cpp
@@ -797,7 +797,7 @@ static bool validate_bvar_dump(const char*, bool enabled) {
const bool ALLOW_UNUSED dummy_bvar_dump = ::google::RegisterFlagValidator(
&FLAGS_bvar_dump, validate_bvar_dump);
-// validators (to make these gflags reloadable in baidu-rpc)
+// validators (to make these gflags reloadable in brpc)
static bool validate_bvar_dump_interval(const char*, int32_t v) {
// FIXME: -bvar_dump_interval is actually unreloadable but we need to
// check validity of it, so we still add this validator. In practice
diff --git a/src/mcpack2pb/parser.h b/src/mcpack2pb/parser.h
index 56bca6ce6f..8435268f16 100644
--- a/src/mcpack2pb/parser.h
+++ b/src/mcpack2pb/parser.h
@@ -26,7 +26,7 @@
#include "mcpack2pb/field_type.h"
// CAUTION: Methods in this header is not intended to be public to users of
-// baidu-rpc, and subject to change at any future time.
+// brpc, and subject to change at any future time.
namespace mcpack2pb {
diff --git a/src/mcpack2pb/serializer.h b/src/mcpack2pb/serializer.h
index a5ff234633..cd5f9512f4 100644
--- a/src/mcpack2pb/serializer.h
+++ b/src/mcpack2pb/serializer.h
@@ -26,7 +26,7 @@
#include "mcpack2pb/field_type.h"
// CAUTION: Methods in this header is not intended to be public to users of
-// baidu-rpc, and subject to change at any future time.
+// brpc, and subject to change at any future time.
namespace mcpack2pb {
diff --git a/test/brpc_http_message_unittest.cpp b/test/brpc_http_message_unittest.cpp
index b9cd8d38c4..1f10d7507f 100644
--- a/test/brpc_http_message_unittest.cpp
+++ b/test/brpc_http_message_unittest.cpp
@@ -334,22 +334,22 @@ TEST(HttpMessageTest, serialize_http_request) {
base::IOBuf content;
content.append("data");
SerializeHttpRequest(&request, &header, ep, &content);
- ASSERT_EQ("POST / HTTP/1.1\r\nContent-Length: 4\r\nHost: 127.0.0.1:1234\r\nFoo: Bar\r\nAccept: */*\r\nUser-Agent: baidu-rpc/1.0 curl/7.0\r\n\r\ndata", request);
+ ASSERT_EQ("POST / HTTP/1.1\r\nContent-Length: 4\r\nHost: 127.0.0.1:1234\r\nFoo: Bar\r\nAccept: */*\r\nUser-Agent: brpc/1.0 curl/7.0\r\n\r\ndata", request);
// user-set content-length is ignored.
header.SetHeader("Content-Length", "100");
SerializeHttpRequest(&request, &header, ep, &content);
- ASSERT_EQ("POST / HTTP/1.1\r\nContent-Length: 4\r\nHost: 127.0.0.1:1234\r\nFoo: Bar\r\nAccept: */*\r\nUser-Agent: baidu-rpc/1.0 curl/7.0\r\n\r\ndata", request);
+ ASSERT_EQ("POST / HTTP/1.1\r\nContent-Length: 4\r\nHost: 127.0.0.1:1234\r\nFoo: Bar\r\nAccept: */*\r\nUser-Agent: brpc/1.0 curl/7.0\r\n\r\ndata", request);
// user-host overwrites passed-in remote_side
header.SetHeader("Host", "MyHost: 4321");
SerializeHttpRequest(&request, &header, ep, &content);
- ASSERT_EQ("POST / HTTP/1.1\r\nContent-Length: 4\r\nFoo: Bar\r\nHost: MyHost: 4321\r\nAccept: */*\r\nUser-Agent: baidu-rpc/1.0 curl/7.0\r\n\r\ndata", request);
+ ASSERT_EQ("POST / HTTP/1.1\r\nContent-Length: 4\r\nFoo: Bar\r\nHost: MyHost: 4321\r\nAccept: */*\r\nUser-Agent: brpc/1.0 curl/7.0\r\n\r\ndata", request);
// user-set accept
header.SetHeader("accePT"/*intended uppercase*/, "blahblah");
SerializeHttpRequest(&request, &header, ep, &content);
- ASSERT_EQ("POST / HTTP/1.1\r\nContent-Length: 4\r\naccePT: blahblah\r\nFoo: Bar\r\nHost: MyHost: 4321\r\nUser-Agent: baidu-rpc/1.0 curl/7.0\r\n\r\ndata", request);
+ ASSERT_EQ("POST / HTTP/1.1\r\nContent-Length: 4\r\naccePT: blahblah\r\nFoo: Bar\r\nHost: MyHost: 4321\r\nUser-Agent: brpc/1.0 curl/7.0\r\n\r\ndata", request);
// user-set UA
header.SetHeader("user-AGENT", "myUA");