Skip to content

Commit

Permalink
Change base in docs to butil
Browse files Browse the repository at this point in the history
  • Loading branch information
gejun committed Sep 8, 2017
1 parent 80f9f2f commit 8dfaf1a
Show file tree
Hide file tree
Showing 25 changed files with 80 additions and 87 deletions.
2 changes: 1 addition & 1 deletion docs/cn/atomic_instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
- 一个依赖全局多生产者多消费者队列(MPMC)的程序难有很好的多核扩展性,因为这个队列的极限吞吐取决于同步cache的延时,而不是核心的个数。最好是用多个SPMC或多个MPSC队列,甚至多个SPSC队列代替,在源头就规避掉竞争。
- 另一个例子是全局计数器,如果所有线程都频繁修改一个全局变量,性能就会很差,原因同样在于不同的核心在不停地同步同一个cacheline。如果这个计数器只是用作打打日志之类的,那我们完全可以让每个线程修改thread-local变量,在需要时再合并所有线程中的值,性能可能有几十倍的差别。

做不到完全不共享,那就尽量少共享。在一些读很多的场景下,也许可以降低写的频率以减少同步cacheline的次数,以加快读的平均性能。一个相关的编程陷阱是避免false sharing:这指的是那些不怎么被修改的变量,由于同一个cacheline中的另一个变量被频繁修改,而不得不经常等待cacheline同步而显著变慢了。多线程中的变量尽量按访问规律排列,频繁被其他线程的修改要放在独立的cacheline中。要让一个变量或结构体按cacheline对齐,可以include <base/macros.h>然后使用BAIDU_CACHELINE_ALIGNMENT宏,用法请自行grep一下brpc的代码了解。
做不到完全不共享,那就尽量少共享。在一些读很多的场景下,也许可以降低写的频率以减少同步cacheline的次数,以加快读的平均性能。一个相关的编程陷阱是避免false sharing:这指的是那些不怎么被修改的变量,由于同一个cacheline中的另一个变量被频繁修改,而不得不经常等待cacheline同步而显著变慢了。多线程中的变量尽量按访问规律排列,频繁被其他线程的修改要放在独立的cacheline中。要让一个变量或结构体按cacheline对齐,可以include <butil/macros.h>然后使用BAIDU_CACHELINE_ALIGNMENT宏,用法请自行grep一下brpc的代码了解。

# Memory fence

Expand Down
4 changes: 2 additions & 2 deletions docs/cn/backup_request.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ Channel开启backup request。这个Channel会先向其中一个server发送请

```c++
#include <bvar/bvar.h>
#include <base/time.h>
#include <butil/time.h>
...
bvar::LatencyRecorder my_func_latency("my_func");
...
base::Timer tm;
butil::Timer tm;
tm.start();
my_func();
tm.stop();
Expand Down
10 changes: 5 additions & 5 deletions docs/cn/bvar.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,18 +123,18 @@ extern bvar::Adder<int> g_task_pushed;

不同编译单元中全局变量的初始化顺序是[未定义的](https://isocpp.org/wiki/faq/ctors#static-init-order)。在foo.cpp中定义`Adder<int> foo_count`,在foo_qps.cpp中定义`PerSecond<Adder<int> > foo_qps(&foo_count);`**错误**的做法。

计时可以使用base::Timer,接口如下:
计时可以使用butil::Timer,接口如下:

```c++
#include <base/time.h>
namespace base {
#include <butil/time.h>
namespace butil {
class Timer {
public:
enum TimerType { STARTED };

Timer();

// base::Timer tm(base::Timer::STARTED); // tm is already started after creation.
// butil::Timer tm(butil::Timer::STARTED); // tm is already started after creation.
explicit Timer(TimerType);

// Start this timer
Expand All @@ -149,7 +149,7 @@ public:
int64_t m_elapsed() const; // in milliseconds
int64_t s_elapsed() const; // in seconds
};
} // base
} // namespace butil
```
## 2.打开bvar的dump功能
Expand Down
9 changes: 4 additions & 5 deletions docs/cn/bvar_c++.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
# Introduction
COMAKE中增加bvar依赖:`CONFIGS('public/bvar@ci-base')`
源文件中`#include <bvar/bvar.h>`
bvar分为多个具体的类,常用的有:
- bvar::Adder<T> : 计数器,默认0,varname << N相当于varname += N。
Expand Down Expand Up @@ -63,8 +62,8 @@ Variable是所有bvar的基类,主要提供全局注册,列举,查询等
// describe_exposed
// find_exposed
// Return 0 on success, -1 otherwise.
int expose(const base::StringPiece& name);
int expose(const base::StringPiece& prefix, const base::StringPiece& name);
int expose(const butil::StringPiece& name);
int expose(const butil::StringPiece& prefix, const butil::StringPiece& name);
```
全局曝光后的bvar名字便为name或prefix + name,可通过以_exposed为后缀的static函数查询。比如Variable::describe_exposed(name)会返回名为name的bvar的描述。

Expand Down Expand Up @@ -104,7 +103,7 @@ bvar::Status<std::string> status1("count2", "hello"); // the name conflicts. if
// };
// } // foo
// } // bar
int expose_as(const base::StringPiece& prefix, const base::StringPiece& name);
int expose_as(const butil::StringPiece& prefix, const butil::StringPiece& name);
```

# Export all variables
Expand All @@ -115,7 +114,7 @@ int expose_as(const base::StringPiece& prefix, const base::StringPiece& name);
// If dump() returns false, Variable::dump_exposed() stops and returns -1.
class Dumper {
public:
virtual bool dump(const std::string& name, const base::StringPiece& description) = 0;
virtual bool dump(const std::string& name, const butil::StringPiece& description) = 0;
};

// Options for Variable::dump_exposed().
Expand Down
12 changes: 6 additions & 6 deletions docs/cn/client.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ public:
// naming_service.h
struct ServerNode {
base::EndPoint addr;
butil::EndPoint addr;
std::string tag;
};
```
Expand Down Expand Up @@ -365,12 +365,12 @@ 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,返回值类型是[butil::EndPoint](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/butil/endpoint.h),包含一个ip4地址和端口。在RPC结束前调用这个方法都是没有意义的。

打印方式:
```c++
LOG(INFO) << "remote_side=" << cntl->remote_side();
printf("remote_side=%s\n", base::endpoint2str(cntl->remote_side()).c_str());
printf("remote_side=%s\n", butil::endpoint2str(cntl->remote_side()).c_str());
```
## 获取Client的地址和端口
Expand All @@ -379,7 +379,7 @@ r31384后通过local_side()方法可**在RPC结束后**获得发起RPC的地址
打印方式:
```c++
LOG(INFO) << "local_side=" << cntl->local_side();
printf("local_side=%s\n", base::endpoint2str(cntl->local_side()).c_str());
printf("local_side=%s\n", butil::endpoint2str(cntl->local_side()).c_str());
```
## 新建brpc::Controller的代价大吗

Expand Down Expand Up @@ -732,12 +732,12 @@ FATAL 04-07 20:00:03 7778 public/brpc/src/brpc/channel.cpp:123] Invalid address=
2. 根据Channel的创建方式,从进程级的[SocketMap](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/brpc/socket_map.h)中或从[LoadBalancer](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/brpc/load_balancer.h)中选择一台下游server作为本次RPC发送的目的地。
3. 根据连接方式(单连接、连接池、短连接),选择一个[Socket](https://svn.baidu.com/public/trunk/baidu-rpc/src/baidu/rpc/socket.h)
4. 如果开启验证且当前Socket没有被验证过时,第一个请求进入验证分支,其余请求会阻塞直到第一个包含认证信息的请求写入Socket。这是因为server端只对第一个请求进行验证。
5. 根据Channel的协议,选择对应的序列化函数把request序列化至[IOBuf](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/base/iobuf.h)
5. 根据Channel的协议,选择对应的序列化函数把request序列化至[IOBuf](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/butil/iobuf.h)
6. 如果配置了超时,设置定时器。从这个点开始要避免使用Controller对象,因为在设定定时器后->有可能触发超时机制->调用到用户的异步回调->用户在回调中析构Controller。
7. 发送准备阶段结束,若上述任何步骤出错,会调用Channel::HandleSendFailed。
8. 将之前序列化好的IOBuf写出到Socket上,同时传入回调Channel::HandleSocketFailed,当连接断开、写失败等错误发生时会调用此回调。
9. 如果是同步发送,Join correlation_id;如果是异步则至此client端返回。
10. 网络上发消息+收消息。
11. 收到response后,提取出其中的correlation_id,在O(1)时间内找到对应的Controller。这个过程中不需要查找全局哈希表,有良好的多核扩展性。
12. 根据协议格式反序列化response。
13. 调用Controller::OnRPCReturned,其中会根据错误码判断是否需要重试。如果是异步发送,调用用户回调。最后摧毁correlation_id唤醒Join着的线程。
13. 调用Controller::OnRPCReturned,其中会根据错误码判断是否需要重试。如果是异步发送,调用用户回调。最后摧毁correlation_id唤醒Join着的线程。
2 changes: 1 addition & 1 deletion docs/cn/combo_channel.md
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ public:
char* endptr = NULL;
out->index = strtol(tag.c_str(), &endptr, 10);
if (endptr != tag.data() + pos) {
LOG(ERROR) << "Invalid index=" << base::StringPiece(tag.data(), pos);
LOG(ERROR) << "Invalid index=" << butil::StringPiece(tag.data(), pos);
return false;
}
out->num_partition_kinds = strtol(tag.c_str() + pos + 1, &endptr, 10);
Expand Down
6 changes: 3 additions & 3 deletions docs/cn/cpu_profiler.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ brpc可以分析程序中的热点函数。
1. 链接`libtcmalloc_and_profiler.a`
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')`
2. 定义宏BRPC_ENABLE_CPU_PROFILER, 一般加入编译参数-DBRPC_ENABLE_CPU_PROFILER
3. 如果只是brpc client或没有使用brpc,看[这里](dummy_server.md)

注意要关闭Server端的认证,否则可能会看到这个:
Expand Down Expand Up @@ -63,7 +63,7 @@ Total: 2946 samples
33 1.1% 68.8% 33 1.1% brpc::Socket::Write
33 1.1% 69.9% 33 1.1% epoll_ctl
28 1.0% 70.9% 42 1.4% brpc::policy::ProcessRpcRequest
27 0.9% 71.8% 27 0.9% base::IOBuf::_push_back_ref
27 0.9% 71.8% 27 0.9% butil::IOBuf::_push_back_ref
27 0.9% 72.7% 27 0.9% bthread::TaskGroup::ending_sched
```

Expand All @@ -84,7 +84,7 @@ Total: 2954 samples
240 8.1% 53.9% 240 8.1% writev
90 3.0% 56.9% 90 3.0% ::cpp_alloc
67 2.3% 59.2% 67 2.3% __read_nocancel
47 1.6% 60.8% 47 1.6% base::IOBuf::_push_back_ref
47 1.6% 60.8% 47 1.6% butil::IOBuf::_push_back_ref
42 1.4% 62.2% 56 1.9% brpc::policy::ProcessRpcRequest
41 1.4% 63.6% 41 1.4% epoll_wait
38 1.3% 64.9% 38 1.3% epoll_ctl
Expand Down
2 changes: 1 addition & 1 deletion docs/cn/error_code.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ server端Controller的SetFailed()常由用户在服务回调中调用。当处

brpc使用的所有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中是为了跨语言。其余的是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()会包含更具体的错误信息。brpc默认包含berror,你可以直接使用。
[berror(error_code)](http://icode.baidu.com/repo/baidu/opensource/baidu-rpc/files/master/blob/src/butil/errno.h)可获得error_code的描述,berror()可获得[system errno](http://www.cplusplus.com/reference/cerrno/errno/)的描述。**ErrorText() != berror(****ErrorCode())**,ErrorText()会包含更具体的错误信息。brpc默认包含berror,你可以直接使用。

brpc中常见错误的打印内容列表如下:

Expand Down
6 changes: 3 additions & 3 deletions docs/cn/execution_queue.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ const static TaskOptions TASK_OPTIONS_INPLACE = TaskOptions(false, true);
// Execute a task with defaut TaskOptions (normal task);
template <typename T>
int execution_queue_execute(ExecutionQueueId<T> id,
typename base::add_const_reference<T>::type task);
typename butil::add_const_reference<T>::type task);
// Thread-safe and Wait-free.
// Execute a task with options. e.g
Expand All @@ -160,11 +160,11 @@ int execution_queue_execute(ExecutionQueueId<T> id,
// If |handle| is not NULL, we will assign it with the hanlder of this task.
template <typename T>
int execution_queue_execute(ExecutionQueueId<T> id,
typename base::add_const_reference<T>::type task,
typename butil::add_const_reference<T>::type task,
const TaskOptions* options);
template <typename T>
int execution_queue_execute(ExecutionQueueId<T> id,
typename base::add_const_reference<T>::type task,
typename butil::add_const_reference<T>::type task,
const TaskOptions* options,
TaskHandle* handle);
```
Expand Down
2 changes: 0 additions & 2 deletions docs/cn/flags.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ brpc使用gflags管理配置。如果你的程序也使用gflags,那么你应
- 你可以在浏览器中查看brpc服务器中所有gflags,并对其动态修改(如果允许的话)。configure不可能做到这点。
- gflags分散在和其作用紧密关联的文件中,更好管理。而使用configure需要聚集到一个庞大的读取函数中。

如果你依赖了brpc,那么你已经依赖了third-64/gflags,如果你需要依赖某个特定版本的话,在COMAKE中加入CONFIGS('third-64/gflags@<specific-version>')。

# Usage of gflags

gflags一般定义在需要它的源文件中。#include <gflags/gflags.h>后在全局scope加入DEFINE_*<type>*(*<name>*, *<default-value>*, *<description>*); 比如:
Expand Down
14 changes: 7 additions & 7 deletions docs/cn/heap_profiler.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ brpc可以分析内存是被哪些函数占据的。heap profiler的原理是每

1. 如果tcmalloc使用frame pointer而不是libunwind回溯栈,请确保在CXXFLAGS或CFLAGS中加上`-fno-omit-frame-pointer`,否则函数间的调用关系会丢失,最后产生的图片中都是彼此独立的函数方框。

2. 在COMAKE的CPPFLAGS中增加`-DBRPC_ENABLE_HEAP_PROFILER`
2. 定义宏BRPC_ENABLE_HEAP_PROFILER, 一般加入编译参数-DBRPC_ENABLE_HEAP_PROFILER

3. 在shell中`export TCMALLOC_SAMPLE_PARAMETER=524288`。该变量指每分配这么多字节内存时做一次统计,默认为0,代表不开启内存统计。[官方文档](http://goog-perftools.sourceforge.net/doc/tcmalloc.html)建议设置为524288。这个变量也可在运行前临时设置,如`TCMALLOC_SAMPLE_PARAMETER=524288 ./server`。如果没有这个环境变量,可能会看到这样的结果:

Expand Down Expand Up @@ -65,9 +65,9 @@ Adjusting heap profiles for 1-in-524288 sampling rate
Heap version 2
Total: 38.9 MB
35.8 92.0% 92.0% 35.8 92.0% ::cpp_alloc
2.1 5.4% 97.4% 2.1 5.4% base::FlatMap
0.5 1.3% 98.7% 0.5 1.3% base::IOBuf::append
0.5 1.3% 100.0% 0.5 1.3% base::IOBufAsZeroCopyOutputStream::Next
2.1 5.4% 97.4% 2.1 5.4% butil::FlatMap
0.5 1.3% 98.7% 0.5 1.3% butil::IOBuf::append
0.5 1.3% 100.0% 0.5 1.3% butil::IOBufAsZeroCopyOutputStream::Next
0.0 0.0% 100.0% 0.6 1.5% MallocExtension::GetHeapSample
0.0 0.0% 100.0% 0.5 1.3% ProfileHandler::Init
0.0 0.0% 100.0% 0.5 1.3% ProfileHandlerRegisterCallback
Expand All @@ -81,9 +81,9 @@ Total: 38.9 MB
0.0 0.0% 100.0% 2.9 7.4% brpc::Socket::Write
0.0 0.0% 100.0% 3.8 9.7% brpc::Span::CreateServerSpan
0.0 0.0% 100.0% 1.4 3.5% brpc::SpanQueue::Push
0.0 0.0% 100.0% 1.9 4.8% base::ObjectPool
0.0 0.0% 100.0% 0.8 2.0% base::ResourcePool
0.0 0.0% 100.0% 1.0 2.6% base::iobuf::tls_block
0.0 0.0% 100.0% 1.9 4.8% butil::ObjectPool
0.0 0.0% 100.0% 0.8 2.0% butil::ResourcePool
0.0 0.0% 100.0% 1.0 2.6% butil::iobuf::tls_block
0.0 0.0% 100.0% 1.0 2.6% bthread::TimerThread::Bucket::schedule
0.0 0.0% 100.0% 1.6 4.1% bthread::get_stack
0.0 0.0% 100.0% 4.2 10.8% bthread_id_create
Expand Down
Loading

0 comments on commit 8dfaf1a

Please sign in to comment.