Commit f8571933 authored by gongweibao's avatar gongweibao

Merge branch 'master' of https://github.com/brpc/brpc

parents cd6d163c 33604cea
......@@ -25,4 +25,5 @@ install:
- sudo apt-get install -y gdb # install gdb
script:
- if [[ "$PURPOSE" == "compile-with-bazel" ]]; then bazel build -j 12 -c opt --copt -DHAVE_ZLIB=1 //... ; fi
- sh build_in_travis_ci.sh
......@@ -10,11 +10,29 @@ config_setting(
visibility = ["//visibility:public"],
)
config_setting(
name = "with_thrift",
define_values = {"with_thrift": "true"},
visibility = ["//visibility:public"],
)
config_setting(
name = "unittest",
define_values = {"unittest": "true"},
)
config_setting(
name = "darwin",
values = {"cpu": "darwin"},
visibility = ["//visibility:public"],
)
config_setting(
name = "linux",
values = {"cpu": "linux"},
visibility = ["//visibility:public"],
)
COPTS = [
"-DBTHREAD_USE_FAST_PTHREAD_MUTEX",
"-D__const__=",
......@@ -28,16 +46,40 @@ COPTS = [
] + select({
":with_glog": ["-DBRPC_WITH_GLOG=1"],
"//conditions:default": ["-DBRPC_WITH_GLOG=0"],
}) + select({
":with_thrift": ["-DENABLE_THRIFT_FRAMED_PROTOCOL=1"],
"//conditions:default": [""],
})
LINKOPTS = [
"-lpthread",
"-lrt",
"-lssl",
"-lcrypto",
"-ldl",
"-lz",
]
"-lssl",
"-lcrypto",
] + select({
":darwin": [
"-framework CoreFoundation",
"-framework CoreGraphics",
"-framework CoreData",
"-framework CoreText",
"-framework Security",
"-framework Foundation",
"-Wl,-U,_MallocExtension_ReleaseFreeMemory",
"-Wl,-U,_ProfilerStart",
"-Wl,-U,_ProfilerStop",
"-Wl,-U,_RegisterThriftProtocol",
],
"//conditions:default": [
"-lrt",
],
}) + select({
":with_thrift": [
"-lthriftnb",
"-levent",
"-lthrift"],
"//conditions:default": [],
})
genrule(
name = "config_h",
......@@ -103,7 +145,6 @@ BUTIL_SRCS = [
"src/butil/files/scoped_file.cc",
"src/butil/files/scoped_temp_dir.cc",
"src/butil/file_util.cc",
"src/butil/file_util_linux.cc",
"src/butil/file_util_posix.cc",
"src/butil/guid.cc",
"src/butil/guid_posix.cc",
......@@ -118,6 +159,7 @@ BUTIL_SRCS = [
"src/butil/memory/weak_ptr.cc",
"src/butil/posix/file_descriptor_shuffle.cc",
"src/butil/posix/global_descriptors.cc",
"src/butil/process_util.cc",
"src/butil/rand_util.cc",
"src/butil/rand_util_posix.cc",
"src/butil/fast_rand.cpp",
......@@ -133,7 +175,6 @@ BUTIL_SRCS = [
"src/butil/strings/string_util.cc",
"src/butil/strings/string_util_constants.cc",
"src/butil/strings/stringprintf.cc",
"src/butil/strings/sys_string_conversions_posix.cc",
"src/butil/strings/utf_offset_string_conversions.cc",
"src/butil/strings/utf_string_conversion_utils.cc",
"src/butil/strings/utf_string_conversions.cc",
......@@ -141,7 +182,6 @@ BUTIL_SRCS = [
"src/butil/synchronization/condition_variable_posix.cc",
"src/butil/synchronization/waitable_event_posix.cc",
"src/butil/threading/non_thread_safe_impl.cc",
"src/butil/threading/platform_thread_linux.cc",
"src/butil/threading/platform_thread_posix.cc",
"src/butil/threading/simple_thread.cc",
"src/butil/threading/thread_checker_impl.cc",
......@@ -177,8 +217,82 @@ BUTIL_SRCS = [
"src/butil/containers/case_ignored_flat_map.cpp",
"src/butil/iobuf.cpp",
"src/butil/popen.cpp",
]
] + select({
":darwin": [
"src/butil/time/time_mac.cc",
"src/butil/mac/scoped_mach_port.cc",
],
"//conditions:default": [
"src/butil/file_util_linux.cc",
"src/butil/threading/platform_thread_linux.cc",
"src/butil/strings/sys_string_conversions_posix.cc",
],
})
objc_library(
name = "macos_lib",
hdrs = [":config_h",
"src/butil/atomicops.h",
"src/butil/atomicops_internals_atomicword_compat.h",
"src/butil/atomicops_internals_mac.h",
"src/butil/base_export.h",
"src/butil/basictypes.h",
"src/butil/build_config.h",
"src/butil/compat.h",
"src/butil/compiler_specific.h",
"src/butil/containers/hash_tables.h",
"src/butil/debug/debugger.h",
"src/butil/debug/leak_annotations.h",
"src/butil/file_util.h",
"src/butil/file_descriptor_posix.h",
"src/butil/files/file_path.h",
"src/butil/files/file.h",
"src/butil/files/scoped_file.h",
"src/butil/lazy_instance.h",
"src/butil/logging.h",
"src/butil/mac/bundle_locations.h",
"src/butil/mac/foundation_util.h",
"src/butil/mac/scoped_cftyperef.h",
"src/butil/mac/scoped_typeref.h",
"src/butil/macros.h",
"src/butil/memory/aligned_memory.h",
"src/butil/memory/scoped_policy.h",
"src/butil/memory/scoped_ptr.h",
"src/butil/move.h",
"src/butil/port.h",
"src/butil/posix/eintr_wrapper.h",
"src/butil/scoped_generic.h",
"src/butil/strings/string16.h",
"src/butil/strings/string_piece.h",
"src/butil/strings/string_util.h",
"src/butil/strings/string_util_posix.h",
"src/butil/strings/sys_string_conversions.h",
"src/butil/synchronization/lock.h",
"src/butil/time/time.h",
"src/butil/time.h",
"src/butil/third_party/dynamic_annotations/dynamic_annotations.h",
"src/butil/threading/platform_thread.h",
"src/butil/threading/thread_restrictions.h",
"src/butil/threading/thread_id_name_manager.h",
"src/butil/type_traits.h",
],
non_arc_srcs = [
"src/butil/mac/bundle_locations.mm",
"src/butil/mac/foundation_util.mm",
"src/butil/file_util_mac.mm",
"src/butil/threading/platform_thread_mac.mm",
"src/butil/strings/sys_string_conversions_mac.mm",
],
deps = [
"@com_github_gflags_gflags//:gflags",
] + select({
":with_glog": ["@com_github_google_glog//:glog"],
"//conditions:default": [],
}),
includes = ["src/"],
enable_modules = True,
tags = ["manual"],
)
cc_library(
name = "butil",
......@@ -199,6 +313,7 @@ cc_library(
"@com_github_gflags_gflags//:gflags",
] + select({
":with_glog": ["@com_github_google_glog//:glog"],
":darwin": [":macos_lib"],
"//conditions:default": [],
}),
includes = [
......@@ -343,7 +458,17 @@ cc_library(
srcs = glob([
"src/brpc/*.cpp",
"src/brpc/**/*.cpp",
]),
],
exclude = [
"src/brpc/thrift_service.cpp",
"src/brpc/thrift_message.cpp",
"src/brpc/policy/thrift_protocol.cpp",
]) + select({
":with_thrift" : glob([
"src/brpc/thrift*.cpp",
"src/brpc/**/thrift*.cpp"]),
"//conditions:default" : [],
}),
hdrs = glob([
"src/brpc/*.h",
"src/brpc/**/*.h"
......
......@@ -2,7 +2,9 @@ cmake_minimum_required(VERSION 2.8.10)
project(brpc C CXX)
# Enable MACOSX_RPATH. Run "cmake --help-policy CMP0042" for policy details.
cmake_policy(SET CMP0042 NEW)
if(POLICY CMP0042)
cmake_policy(SET CMP0042 NEW)
endif()
set(BRPC_VERSION 0.9.0)
......@@ -20,14 +22,14 @@ else()
message(WARNING "You are using an unsupported compiler! Compilation has only been tested with Clang and GCC.")
endif()
option(BRPC_WITH_GLOG "With glog" OFF)
option(WITH_GLOG "With glog" OFF)
option(DEBUG "Print debug logs" OFF)
option(WITH_DEBUG_SYMBOLS "With debug symbols" ON)
option(BRPC_WITH_THRIFT "With thrift framed protocol supported" OFF)
option(WITH_THRIFT "With thrift framed protocol supported" OFF)
option(BUILD_UNIT_TESTS "Whether to build unit tests" OFF)
set(WITH_GLOG_VAL "0")
if(BRPC_WITH_GLOG)
if(WITH_GLOG)
set(WITH_GLOG_VAL "1")
endif()
......@@ -35,10 +37,10 @@ if(WITH_DEBUG_SYMBOLS)
set(DEBUG_SYMBOL "-g")
endif()
if(BRPC_WITH_THRIFT)
if(WITH_THRIFT)
set(THRIFT_CPP_FLAG "-DENABLE_THRIFT_FRAMED_PROTOCOL")
set(THRIFT_LIB "thriftnb")
message("Enable thrift framed procotol")
set(THRIFTNB_LIB "thriftnb")
set(THRIFT_LIB "thrift")
endif()
include(GNUInstallDirs)
......@@ -119,7 +121,7 @@ if ((NOT LEVELDB_INCLUDE_PATH) OR (NOT LEVELDB_LIB))
message(FATAL_ERROR "Fail to find leveldb")
endif()
if(BRPC_WITH_GLOG)
if(WITH_GLOG)
find_path(GLOG_INCLUDE_PATH NAMES glog/logging.h)
find_library(GLOG_LIB NAMES glog)
if((NOT GLOG_INCLUDE_PATH) OR (NOT GLOG_LIB))
......@@ -155,6 +157,7 @@ set(DYNAMIC_LIB
${PROTOC_LIB}
${CMAKE_THREAD_LIBS_INIT}
${THRIFT_LIB}
${THRIFTNB_LIB}
${OPENSSL_LIBRARIES}
${OPENSSL_CRYPTO_LIBRARY}
dl
......@@ -162,7 +165,7 @@ set(DYNAMIC_LIB
)
set(BRPC_PRIVATE_LIBS "-lgflags -lprotobuf -lleveldb -lprotoc -lssl -lcrypto -ldl -lz")
if(BRPC_WITH_GLOG)
if(WITH_GLOG)
set(DYNAMIC_LIB ${DYNAMIC_LIB} ${GLOG_LIB})
set(BRPC_PRIVATE_LIBS "${BRPC_PRIVATE_LIBS} -lglog")
endif()
......@@ -181,8 +184,7 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
"-framework Foundation"
"-Wl,-U,_MallocExtension_ReleaseFreeMemory"
"-Wl,-U,_ProfilerStart"
"-Wl,-U,_ProfilerStop"
"-Wl,-U,_RegisterThriftProtocol")
"-Wl,-U,_ProfilerStop")
endif()
# for *.so
......@@ -326,6 +328,17 @@ file(GLOB_RECURSE BVAR_SOURCES "${CMAKE_SOURCE_DIR}/src/bvar/*.cpp")
file(GLOB_RECURSE BTHREAD_SOURCES "${CMAKE_SOURCE_DIR}/src/bthread/*.cpp")
file(GLOB_RECURSE JSON2PB_SOURCES "${CMAKE_SOURCE_DIR}/src/json2pb/*.cpp")
file(GLOB_RECURSE BRPC_SOURCES "${CMAKE_SOURCE_DIR}/src/brpc/*.cpp")
file(GLOB_RECURSE THRIFT_SOURCES "thrift*.cpp")
if(WITH_THRIFT)
message("brpc compile with thrift proctol")
else()
# Remove thrift sources
foreach(v ${THRIFT_SOURCES})
list(REMOVE_ITEM BRPC_SOURCES ${v})
endforeach()
set(THRIFT_SOURCES "")
endif()
set(MCPACK2PB_SOURCES
${CMAKE_SOURCE_DIR}/src/mcpack2pb/field_type.cpp
......@@ -366,6 +379,7 @@ set(SOURCES
${JSON2PB_SOURCES}
${MCPACK2PB_SOURCES}
${BRPC_SOURCES}
${THRIFT_SOURCES}
)
add_subdirectory(src)
......
......@@ -4,7 +4,7 @@
# ![brpc](docs/images/logo.png)
A industrial-grade RPC framework used throughout [Baidu](http://ir.baidu.com/phoenix.zhtml?c=188488&p=irol-irhome), with 1,000,000+ instances(not counting clients) and thousands kinds of services, called "**baidu-rpc**" inside Baidu. Only C++ implementation is opensourced right now.
An industrial-grade RPC framework used throughout [Baidu](http://ir.baidu.com/phoenix.zhtml?c=188488&p=irol-irhome), with 1,000,000+ instances(not counting clients) and thousands kinds of services, called "**baidu-rpc**" inside Baidu. Only C++ implementation is opensourced right now.
You can use it to:
* Build a server that can talk in multiple protocols (**on same port**), or access all sorts of services
......@@ -21,12 +21,12 @@ You can use it to:
* Clients can access servers [synchronously](docs/en/client.md#synchronus-call), [asynchronously](docs/en/client.md#asynchronous-call), [semi-synchronously](docs/en/client.md#semi-synchronous-call), or use [combo channels](docs/en/combo_channel.md) to simplify sharded or parallel accesses declaratively.
* Debug services [via http](docs/en/builtin_service.md), and run [cpu](docs/cn/cpu_profiler.md), [heap](docs/cn/heap_profiler.md) and [contention](docs/cn/contention_profiler.md) profilers.
* Get [better latency and throughput](docs/en/overview.md#better-latency-and-throughput).
* [Extend brpc](docs/en/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/en/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)
# Try it!
* Read [overview](docs/en/overview.md) to know where brpc can be used and its advantages.
* Read [building steps](docs/cn/getting_started.md) to get started and play with [examples](https://github.com/brpc/brpc/tree/master/example/).
* Read [getting started](docs/cn/getting_started.md) for building steps and play with [examples](https://github.com/brpc/brpc/tree/master/example/).
* Docs:
* [Performance benchmark](docs/cn/benchmark.md)
* [bvar](docs/en/bvar.md)
......
......@@ -22,7 +22,7 @@
* Client支持[同步](docs/cn/client.md#同步访问)[异步](docs/cn/client.md#异步访问)[半同步](docs/cn/client.md#半同步),或使用[组合channels](docs/cn/combo_channel.md)简化复杂的分库或并发访问。
* [通过http界面](docs/cn/builtin_service.md)调试服务, 使用[cpu](docs/cn/cpu_profiler.md), [heap](docs/cn/heap_profiler.md), [contention](docs/cn/contention_profiler.md) profilers.
* 获得[更好的延时和吞吐](docs/cn/overview.md#更好的延时和吞吐).
* 把你组织中使用的协议快速地[加入brpc](docs/cn/new_protocol.md),或定制各类组件, 包括[名字服务](docs/cn/load_balancing.md#名字服务) (dns, zk, etcd), [负载均衡](docs/cn/load_balancing.md#负载均衡) (rr, random, consistent hashing)
* 把你组织中使用的协议快速地[加入brpc](docs/cn/new_protocol.md),或定制各类组件, 包括[命名服务](docs/cn/load_balancing.md#命名服务) (dns, zk, etcd), [负载均衡](docs/cn/load_balancing.md#负载均衡) (rr, random, consistent hashing)
# 试一下!
......
......@@ -3,8 +3,8 @@
def brpc_workspace():
native.http_archive(
name = "com_google_protobuf",
strip_prefix = "protobuf-b04e5cba356212e4e8c66c61bbe0c3a20537c5b9",
url = "https://github.com/google/protobuf/archive/b04e5cba356212e4e8c66c61bbe0c3a20537c5b9.tar.gz",
strip_prefix = "protobuf-ab8edf1dbe2237b4717869eaab11a2998541ad8d",
url = "https://github.com/google/protobuf/archive/ab8edf1dbe2237b4717869eaab11a2998541ad8d.tar.gz",
)
......
......@@ -21,11 +21,6 @@ runcmd(){
echo "build combination: PURPOSE=$PURPOSE CXX=$CXX CC=$CC"
if [ "$PURPOSE" = "compile-with-bazel" ]; then
runcmd "bazel build -j 12 -c opt --copt -DHAVE_ZLIB=1 //..."
exit 0
fi
# The default env in travis-ci is Ubuntu.
if ! sh config_brpc.sh --headers=/usr/include --libs=/usr/lib --nodebugsymbols --cxx=$CXX --cc=$CC; then
echo "Fail to configure brpc"
......
......@@ -4,7 +4,7 @@ includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@
libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@
Name: brpc
Description: A industrial-grade RPC framework used throughout Baidu, with 1,000,000+ instances(not counting clients) and thousands kinds of services, called "baidu-rpc" inside Baidu.
Description: An industrial-grade RPC framework used throughout Baidu, with 1,000,000+ instances(not counting clients) and thousands kinds of services, called "baidu-rpc" inside Baidu.
Version: @BRPC_VERSION@
Cflags: -I${includedir}
Libs: -L${libdir}/ -lbrpc
......
......@@ -31,11 +31,17 @@ if [ $? != 0 ] ; then >&2 $ECHO "Terminating..."; exit 1 ; fi
# Note the quotes around `$TEMP': they are essential!
eval set -- "$TEMP"
if [ "$SYSTEM" = "Darwin" ]; then
REALPATH=realpath
else
REALPATH="readlink -f"
fi
# Convert to abspath always so that generated mk is include-able from everywhere
while true; do
case "$1" in
--headers ) HDRS_IN="$(realpath $2)"; shift 2 ;;
--libs ) LIBS_IN="$(realpath $2)"; shift 2 ;;
--headers ) HDRS_IN="$(${REALPATH} $2)"; shift 2 ;;
--libs ) LIBS_IN="$(${REALPATH} $2)"; shift 2 ;;
--cc ) CC=$2; shift 2 ;;
--cxx ) CXX=$2; shift 2 ;;
--with-glog ) WITH_GLOG=1; shift 1 ;;
......
有时为了保证可用性,需要同时访问两路服务,哪个先返回就取哪个。在brpc中,这有多种做法:
# 当后端server可以挂在一个名字服务内时
# 当后端server可以挂在一个命名服务内时
Channel开启backup request。这个Channel会先向其中一个server发送请求,如果在ChannelOptions.backup_request_ms后还没回来,再向另一个server发送。之后哪个先回来就取哪个。在设置了合理的backup_request_ms后,大部分时候只会发一个请求,对后端服务只有一倍压力。
......@@ -39,7 +39,7 @@ my_func_latency << tm.u_elapsed(); // u代表微秒,还有s_elapsed(), m_elap
// 好了,在/vars中会显示my_func_qps, my_func_latency, my_func_latency_cdf等很多计数器。
```
# 当后端server不能挂在一个名字服务内时
# 当后端server不能挂在一个命名服务内时
【推荐】建立一个开启backup request的SelectiveChannel,其中包含两个sub channel。访问这个SelectiveChannel和上面的情况类似,会先访问一个sub channel,如果在ChannelOptions.backup_request_ms后没返回,再访问另一个sub channel。如果一个sub channel对应一个集群,这个方法就是在两个集群间做互备。SelectiveChannel的例子见[example/selective_echo_c++](https://github.com/brpc/brpc/tree/master/example/selective_echo_c++),具体做法请参考上面的过程。
......
This diff is collapsed.
......@@ -169,7 +169,7 @@ SelectiveChannel的重试独立于其中的sub channel,当SelectiveChannel访
## 使用SelectiveChannel
SelectiveChannel的初始化和普通Channel基本一样,但Init不需要指定名字服务,因为SelectiveChannel通过AddChannel动态添加sub channel,而普通Channel通过名字服务动态管理server。
SelectiveChannel的初始化和普通Channel基本一样,但Init不需要指定命名服务,因为SelectiveChannel通过AddChannel动态添加sub channel,而普通Channel通过命名服务动态管理server。
```c++
#include <brpc/selective_channel.h>
......@@ -203,11 +203,11 @@ if (schan.AddChannel(sub_channel, NULL/*ChannelHandle*/) != 0) { // 第二个
访问SelectiveChannel的方式和普通Channel是一样的。
## 例子: 往多个名字服务分流
## 例子: 往多个命名服务分流
一些场景中我们需要向多个名字服务下的机器分流,原因可能有:
一些场景中我们需要向多个命名服务下的机器分流,原因可能有:
- 完成同一个检索功能的机器被挂载到了不同的名字服务下。
- 完成同一个检索功能的机器被挂载到了不同的命名服务下。
- 机器被拆成了多个组,流量先分流给一个组,再分流到组内机器。组间的分流方式和组内有所不同。
这都可以通过SelectiveChannel完成。
......@@ -243,11 +243,11 @@ stub.FooMethod(&cntl, &request, &response, NULL);
# PartitionChannel
[PartitionChannel](https://github.com/brpc/brpc/blob/master/src/brpc/partition_channel.h)是特殊的ParallelChannel,它会根据名字服务中的tag自动建立对应分库的sub channel。这样用户就可以把所有的分库机器挂在一个名字服务内,通过tag来指定哪台机器对应哪个分库。示例代码见[example/partition_echo_c++](https://github.com/brpc/brpc/tree/master/example/partition_echo_c++/)
[PartitionChannel](https://github.com/brpc/brpc/blob/master/src/brpc/partition_channel.h)是特殊的ParallelChannel,它会根据命名服务中的tag自动建立对应分库的sub channel。这样用户就可以把所有的分库机器挂在一个命名服务内,通过tag来指定哪台机器对应哪个分库。示例代码见[example/partition_echo_c++](https://github.com/brpc/brpc/tree/master/example/partition_echo_c++/)
ParititonChannel只能处理一种分库方法,当用户需要多种分库方法共存,或从一个分库方法平滑地切换为另一种分库方法时,可以使用DynamicPartitionChannel,它会根据不同的分库方式动态地建立对应的sub PartitionChannel,并根据容量把请求分配给不同的分库。示例代码见[example/dynamic_partition_echo_c++](https://github.com/brpc/brpc/tree/master/example/dynamic_partition_echo_c++/)
如果分库在不同的名字服务内,那么用户得自行用ParallelChannel组装,即每个sub channel对应一个分库(使用不同的名字服务)。ParellelChannel的使用方法见[上面](#ParallelChannel)
如果分库在不同的命名服务内,那么用户得自行用ParallelChannel组装,即每个sub channel对应一个分库(使用不同的命名服务)。ParellelChannel的使用方法见[上面](#ParallelChannel)
## 使用PartitionChannel
......@@ -336,7 +336,7 @@ TRACE: 09-06 10:40:42: * 0 server.cpp:192] S[0]=0 S[1]=0 S[2]=0 [total=0]
...
```
名字服务"file://server_list"的内容是:
命名服务"file://server_list"的内容是:
```
0.0.0.0:8004 0/3 # 表示3分库中的第一个分库,其他依次类推
0.0.0.0:8004 1/3
......@@ -401,7 +401,7 @@ TRACE: 09-06 10:57:15: * 0 server.cpp:192] S[0]=208453 S[1]=276803 S[2]=0 [tot
一次RPC要访问三次8004或四次8005,8004和8005流量比是3:4,说明Client以1:1的比例访问了3分库和4分库。这个比例关系取决于其容量。容量的计算是递归的:
- 普通Channel的容量等于它其中所有server的容量之和。如果名字服务没有配置权值,单个server的容量为1。
- 普通Channel的容量等于它其中所有server的容量之和。如果命名服务没有配置权值,单个server的容量为1。
- ParallelChannel或PartitionChannel的容量等于它其中Sub Channel容量的最小值。
- SelectiveChannel的容量等于它其中Sub Channel的容量之和。
- DynamicPartitionChannel的容量等于它其中Sub PartitionChannel的容量之和。
......
......@@ -25,7 +25,7 @@ $ sudo apt-get install git g++ make libssl-dev
Install [gflags](https://github.com/gflags/gflags), [protobuf](https://github.com/google/protobuf), [leveldb](https://github.com/google/leveldb):
```
$ sudo apt-get install realpath libgflags-dev libprotobuf-dev libprotoc-dev protobuf-compiler libleveldb-dev
$ sudo apt-get install libgflags-dev libprotobuf-dev libprotoc-dev protobuf-compiler libleveldb-dev
```
If you need to statically link leveldb:
......@@ -345,7 +345,7 @@ When you remove tcmalloc, not only remove the linkage with tcmalloc but also the
## glog: 3.3+
brpc implements a default [logging utility](../../src/butil/logging.h) which conflicts with glog. To replace this with glog, add *--with-glog* to config_brpc.sh or add `-DBRPC_WITH_GLOG=ON` to cmake.
brpc implements a default [logging utility](../../src/butil/logging.h) which conflicts with glog. To replace this with glog, add *--with-glog* to config_brpc.sh or add `-DWITH_GLOG=ON` to cmake.
## valgrind: 3.8+
......
......@@ -87,7 +87,7 @@ URL的一般形式如下图:
确实,在简单使用场景下,这两者有所重复,但在复杂场景中,两者差别很大,比如:
- 访问名字服务(如BNS)下的多个http server。此时Channel.Init传入的是对该名字服务有意义的名称(如BNS中的节点名称),对uri()的赋值则是包含Host的完整URL(比如"www.foo.com/index.html?name=value")。
- 访问命名服务(如BNS)下的多个http server。此时Channel.Init传入的是对该命名服务有意义的名称(如BNS中的节点名称),对uri()的赋值则是包含Host的完整URL(比如"www.foo.com/index.html?name=value")。
- 通过http proxy访问目标server。此时Channel.Init传入的是proxy server的地址,但uri()填入的是目标server的URL。
## Host字段
......
上游一般通过名字服务发现所有的下游节点,并通过多种负载均衡方法把流量分配给下游节点。当下游节点出现问题时,它可能会被隔离以提高负载均衡的效率。被隔离的节点定期被健康检查,成功后重新加入正常节点。
上游一般通过命名服务发现所有的下游节点,并通过多种负载均衡方法把流量分配给下游节点。当下游节点出现问题时,它可能会被隔离以提高负载均衡的效率。被隔离的节点定期被健康检查,成功后重新加入正常节点。
# 名字服务
# 命名服务
在brpc中,[NamingService](https://github.com/brpc/brpc/blob/master/src/brpc/naming_service.h)用于获得服务名对应的所有节点。一个直观的做法是定期调用一个函数以获取最新的节点列表。但这会带来一定的延时(定期调用的周期一般在若干秒左右),作为通用接口不太合适。特别当名字服务提供事件通知时(比如zk),这个特性没有被利用。所以我们反转了控制权:不是我们调用用户函数,而是用户在获得列表后调用我们的接口,对应[NamingServiceActions](https://github.com/brpc/brpc/blob/master/src/brpc/naming_service.h)。当然我们还是得启动进行这一过程的函数,对应NamingService::RunNamingService。下面以三个实现解释这套方式:
在brpc中,[NamingService](https://github.com/brpc/brpc/blob/master/src/brpc/naming_service.h)用于获得服务名对应的所有节点。一个直观的做法是定期调用一个函数以获取最新的节点列表。但这会带来一定的延时(定期调用的周期一般在若干秒左右),作为通用接口不太合适。特别当命名服务提供事件通知时(比如zk),这个特性没有被利用。所以我们反转了控制权:不是我们调用用户函数,而是用户在获得列表后调用我们的接口,对应[NamingServiceActions](https://github.com/brpc/brpc/blob/master/src/brpc/naming_service.h)。当然我们还是得启动进行这一过程的函数,对应NamingService::RunNamingService。下面以三个实现解释这套方式:
- bns:没有事件通知,所以我们只能定期去获得最新列表,默认间隔是[5秒](http://brpc.baidu.com:8765/flags/ns_access_interval)。为了简化这类定期获取的逻辑,brpc提供了[PeriodicNamingService](https://github.com/brpc/brpc/blob/master/src/brpc/periodic_naming_service.h) 供用户继承,用户只需要实现单次如何获取(GetServers)。获取后调用NamingServiceActions::ResetServers告诉框架。框架会对列表去重,和之前的列表比较,通知对列表有兴趣的观察者(NamingServiceWatcher)。这套逻辑会运行在独立的bthread中,即NamingServiceThread。一个NamingServiceThread可能被多个Channel共享,通过intrusive_ptr管理ownership。
- file:列表即文件。合理的方式是在文件更新后重新读取。[该实现](https://github.com/brpc/brpc/blob/master/src/brpc/policy/file_naming_service.cpp)使用[FileWatcher](https://github.com/brpc/brpc/blob/master/src/butil/files/file_watcher.h)关注文件的修改时间,当文件修改后,读取并调用NamingServiceActions::ResetServers告诉框架。
......
......@@ -97,6 +97,6 @@ bool PopVersion(std::string* version);
# 访问memcached集群
建立一个使用c_md5负载均衡算法的channel就能访问挂载在对应名字服务下的memcached集群了。注意每个MemcacheRequest应只包含一个操作或确保所有的操作是同一个key。如果request包含了多个操作,在当前实现下这些操作总会送向同一个server,假如对应的key分布在多个server上,那么结果就不对了,这个情况下你必须把一个request分开为多个,每个包含一个操作。
建立一个使用c_md5负载均衡算法的channel就能访问挂载在对应命名服务下的memcached集群了。注意每个MemcacheRequest应只包含一个操作或确保所有的操作是同一个key。如果request包含了多个操作,在当前实现下这些操作总会送向同一个server,假如对应的key分布在多个server上,那么结果就不对了,这个情况下你必须把一个request分开为多个,每个包含一个操作。
或者你可以沿用常见的[twemproxy](https://github.com/twitter/twemproxy)方案。这个方案虽然需要额外部署proxy,还增加了延时,但client端仍可以像访问单点一样的访问它。
......@@ -19,7 +19,7 @@
- 数据需要序列化,[protobuf](https://github.com/google/protobuf)在这方面做的不错。用户填写protobuf::Message类型的request,RPC结束后,从同为protobuf::Message类型的response中取出结果。protobuf有较好的前后兼容性,方便业务调整字段。http广泛使用[json](http://www.json.org/)作为序列化方法。
- 用户无需关心连接如何建立,但可以选择不同的[连接方式](client.md#连接方式):短连接,连接池,单连接。
- 大量机器一般通过名字服务被发现,可基于[DNS](https://en.wikipedia.org/wiki/Domain_Name_System), [ZooKeeper](https://zookeeper.apache.org/), [etcd](https://github.com/coreos/etcd)等实现。在百度内,我们使用BNS (Baidu Naming Service)。brpc也提供["list://"和"file://"](client.md#名字服务)。用户可以指定负载均衡算法,让RPC每次选出一台机器发送请求,包括: round-robin, randomized, [consistent-hashing](consistent_hashing.md)(murmurhash3 or md5)和 [locality-aware](lalb.md).
- 大量机器一般通过命名服务被发现,可基于[DNS](https://en.wikipedia.org/wiki/Domain_Name_System), [ZooKeeper](https://zookeeper.apache.org/), [etcd](https://github.com/coreos/etcd)等实现。在百度内,我们使用BNS (Baidu Naming Service)。brpc也提供["list://"和"file://"](client.md#命名服务)。用户可以指定负载均衡算法,让RPC每次选出一台机器发送请求,包括: round-robin, randomized, [consistent-hashing](consistent_hashing.md)(murmurhash3 or md5)和 [locality-aware](lalb.md).
- 连接断开时可以重试。
- 如果server没有在给定时间内回复,client会返回超时错误。
......@@ -54,7 +54,7 @@ RPC不是万能的抽象,否则我们也不需要TCP/IP这一层了。但是
* Client支持[同步](docs/cn/client.md#同步访问)[异步](docs/cn/client.md#异步访问)[半同步](docs/cn/client.md#半同步),或使用[组合channels](docs/cn/combo_channel.md)简化复杂的分库或并发访问。
* [通过http界面](docs/cn/builtin_service.md)调试服务, 使用[cpu](docs/cn/cpu_profiler.md), [heap](docs/cn/heap_profiler.md), [contention](docs/cn/contention_profiler.md) profilers.
* 获得[更好的延时和吞吐](#更好的延时和吞吐).
* 把你组织中使用的协议快速地[加入brpc](new_protocol.md),或定制各类组件, 包括[名字服务](load_balancing.md#名字服务) (dns, zk, etcd), [负载均衡](load_balancing.md#负载均衡) (rr, random, consistent hashing)
* 把你组织中使用的协议快速地[加入brpc](new_protocol.md),或定制各类组件, 包括[命名服务](load_balancing.md#命名服务) (dns, zk, etcd), [负载均衡](load_balancing.md#负载均衡) (rr, random, consistent hashing)
# brpc的优势
......@@ -66,7 +66,7 @@ RPC不是万能的抽象,否则我们也不需要TCP/IP这一层了。但是
* 访问服务? 包含[brpc/channel.h](https://github.com/brpc/brpc/blob/master/src/brpc/channel.h)并参考注释或[示例](https://github.com/brpc/brpc/blob/master/example/echo_c++/client.cpp).
* 调整参数? 看看[brpc/controller.h](https://github.com/brpc/brpc/blob/master/src/brpc/controller.h). 注意这个类是Server和Channel共用的,分成了三段,分别标记为Client-side, Server-side和Both-side methods。
我们尝试让事情变得更加简单,以名字服务为例,在其他RPC实现中,你也许需要复制一长段晦涩的代码才可使用,而在brpc中访问BNS可以这么写"bns://node-name",DNS是`Init("http://domain-name", ...)`,本地文件列表是"file:///home/work/server.list",相信不用解释,你也能明白这些代表什么。
我们尝试让事情变得更加简单,以命名服务为例,在其他RPC实现中,你也许需要复制一长段晦涩的代码才可使用,而在brpc中访问BNS可以这么写"bns://node-name",DNS是`Init("http://domain-name", ...)`,本地文件列表是"file:///home/work/server.list",相信不用解释,你也能明白这些代表什么。
### 使服务更加可靠
......
......@@ -145,7 +145,7 @@ response中的所有reply的ownership属于response。当response析构时,rep
# 访问redis集群
建立一个使用一致性哈希负载均衡算法(c_md5或c_murmurhash)的channel就能访问挂载在对应名字服务下的redis集群了。注意每个RedisRequest应只包含一个操作或确保所有的操作是同一个key。如果request包含了多个操作,在当前实现下这些操作总会送向同一个server,假如对应的key分布在多个server上,那么结果就不对了,这个情况下你必须把一个request分开为多个,每个包含一个操作。
建立一个使用一致性哈希负载均衡算法(c_md5或c_murmurhash)的channel就能访问挂载在对应命名服务下的redis集群了。注意每个RedisRequest应只包含一个操作或确保所有的操作是同一个key。如果request包含了多个操作,在当前实现下这些操作总会送向同一个server,假如对应的key分布在多个server上,那么结果就不对了,这个情况下你必须把一个request分开为多个,每个包含一个操作。
或者你可以沿用常见的[twemproxy](https://github.com/twitter/twemproxy)方案。这个方案虽然需要额外部署proxy,还增加了延时,但client端仍可以像访问单点一样的访问它。
......
......@@ -26,7 +26,7 @@ json也可以写在文件中,假如./input.json包含了上述两个请求,-
- -proto:指定相关的proto文件名。
- -method:指定方法名,形式必须是package.service.method。
- -server:当-lb_policy为空时,是服务器的ip:port;当-lb_policy不为空时,是集群地址,比如bns://node-name, file://server_list等等。具体见[名字服务](client.md#名字服务)
- -server:当-lb_policy为空时,是服务器的ip:port;当-lb_policy不为空时,是集群地址,比如bns://node-name, file://server_list等等。具体见[命名服务](client.md#命名服务)
- -input: 指定json请求或包含json请求的文件。r32157后json间不需要分隔符,r32157前json间用分号分隔。
可选参数:
......
......@@ -28,6 +28,8 @@ sudo make install
配置brpc支持thrift协议后make。编译完成后会生成libbrpc.a, 其中包含了支持thrift协议的扩展代码, 像正常使用brpc的代码一样链接即可。
```bash
sh config_brpc.sh --headers=/usr/include --libs=/usr/lib --with-thrift
#或者使用cmake
mkdir build && cd build && cmake ../ -DWITH_THRIFT=1
```
# Client端访问thrift server
......
......@@ -34,7 +34,7 @@ Note that Channel neither modifies `options` nor accesses `options` after comple
Init() can connect one server or a cluster(multiple servers).
# Connect a server
# Connect to a server
```c++
// Take default values when options is NULL.
......@@ -53,7 +53,7 @@ Invalid "server_addr_and_port":
- 127.0.0.1:90000 # too large port
- 10.39.2.300:8000 # invalid IP
# Connect a cluster
# Connect to a cluster
```c++
int Init(const char* naming_service_url,
......@@ -86,15 +86,42 @@ If the list in BNS is non-empty, but Channel says "no servers", the status bit o
### file://\<path\>
Servers are put in the file specified by `path`. In "file://conf/local_machine_list", "conf/local_machine_list" is the file and each line in the file is address of a server. brpc reloads the file when it's updated.
Servers are put in the file specified by `path`. For example, in "file://conf/machine_list", "conf/machine_list" is the file:
* in which each line is address of a server.
* contents after \# are comments and ignored.
* non-comment contents after addresses are tags, which are separated from addresses by one or more spaces, same address + different tags are treated as different instances.
* brpc reloads the file when it's updated.
```
# This line is ignored
10.24.234.17 tag1 # a comment
10.24.234.17 tag2 # an instance different from the instance on last line
10.24.234.18
10.24.234.19
```
Pros: easy to modify, convenient for unittests.
Cons: need to update every client when the list changes, not suitable for online deployment.
### list://\<addr1\>,\<addr2\>...
Servers are directly written after list://, separated by comma. For example: "list://db-bce-81-3-186.db01:7000,m1-bce-44-67-72.m1:7000,cp01-rd-cos-006.cp01:7000" has 3 addresses.
Tags can be appended to addresses, separated with one or more spaces. Same address + different tags are treated as different instances.
Pros: directly configurable in CLI, convenient for unittests.
Cons: cannot be updated at runtime, not suitable for online deployment at all.
### http://\<url\>
Connect all servers under the domain, for example: http://www.baidu.com:80. Note: although Init() for connecting single server(2 parameters) accepts hostname as well, it only connects one server under the domain.
Connect all servers under the domain, for example: http://www.baidu.com:80.
Note: although Init() for connecting single server(2 parameters) accepts hostname as well, it only connects one server under the domain.
Pros: Versatility of DNS, useable both in private or public network.
Cons: limited by transmission formats of DNS, unable to implement notification mechanisms.
### consul://\<service-name\>
......@@ -108,6 +135,21 @@ If the server list returned by the consul does not follow [response format](http
If consul is not accessible, the naming service can be automatically downgraded to file naming service. This feature is turned off by default and can be turned on by setting -consul\_enable\_degrade\_to\_file\_naming\_service. After downgrading, in the directory specified by -consul\_file\_naming\_service\_dir, the file whose name is the service-name will be used. This file can be generated by the consul-template, which holds the latest server list before the consul is unavailable. The consul naming service is automatically restored when consul is restored.
### More naming services
User can extend to more naming services by implementing brpc::NamingService, check [this link](https://github.com/brpc/brpc/blob/master/docs/cn/load_balancing.md#%E5%91%BD%E5%90%8D%E6%9C%8D%E5%8A%A1) for details.
### The tag in naming service
tag was used for implementing "coarse-grained wrr": different tags are appended to a same address to make different instances, such that the address gets traffic proportional to the number of different tags. However, you should consider using [wrr algorithm](#wrr) first which distributes traffic proportional to assigned weights and is more fine-grained.
### VIP related issues
VIP is often the public IP of layer-4 load balancer, which proxies traffic to RS behide. When a client connects to the VIP, a connection is established to a chosen RS. When the client connection is broken, the connection to the RS is reset as well.
If one client establishes only one connection to the VIP("single" connection type in brpc), all traffic from the client lands on one RS. If number of clients are large enough, each RS should gets many connections and roughly balanced, at least from the cluster perspective. However, if clients are not large enough or workload from clients are very different, some RS may be overloaded. Another issue is that when multiple VIP are listed together, the traffic to them may not be proportional to the number of RS behide them.
One solution to these issues is to use "pooled" connection type, so that one client may create multiple connections to one VIP (roughly the max concurrency recently) to make traffic land on different RS. If more than one VIP are present, consider using [wrr load balancing](#wrr) to assign weights to different VIP, or add different tags to VIP to form more instances.
Note: When the client uses "single" connection type, even if one VIP appended with different tags can get more traffic, the connection is still one. This is decided by current implementation in brpc.
### Naming Service Filter
Users can filter servers got from the NamingService before pushing to LoadBalancer.
......
......@@ -34,7 +34,7 @@ Common doubts on RPC:
# What is ![brpc](../images/logo.png)?
A industrial-grade RPC framework used throughout [Baidu](http://ir.baidu.com/phoenix.zhtml?c=188488&p=irol-irhome), with 1,000,000+ instances(not counting clients) and thousands kinds of services, called "**baidu-rpc**" inside Baidu. Only C++ implementation is opensourced right now.
An industrial-grade RPC framework used throughout [Baidu](http://ir.baidu.com/phoenix.zhtml?c=188488&p=irol-irhome), with 1,000,000+ instances(not counting clients) and thousands kinds of services, called "**baidu-rpc**" inside Baidu. Only C++ implementation is opensourced right now.
You can use it to:
* Build a server that can talk in multiple protocols (**on same port**), or access all sorts of services
......@@ -50,7 +50,7 @@ You can use it to:
* Clients can access servers [synchronously](client.md#synchronus-call), [asynchronously](client.md#asynchronous-call), [semi-synchronously](client.md#semi-synchronous-call), or use [combo channels](combo_channel.md) to simplify sharded or parallel accesses declaratively.
* Debug services [via http](builtin_service.md), and run [cpu](../cn/cpu_profiler.md), [heap](../cn/heap_profiler.md) and [contention](../cn/contention_profiler.md) profilers.
* Get [better latency and throughput](#better-latency-and-throughput).
* [Extend brpc](new_protocol.md) with the protocols used in your organization quickly, or customize components, including [naming services](../cn/load_balancing.md#名字服务) (dns, zk, etcd), [load balancers](../cn/load_balancing.md#负载均衡) (rr, random, consistent hashing)
* [Extend brpc](new_protocol.md) with the protocols used in your organization quickly, or customize components, including [naming services](../cn/load_balancing.md#命名服务) (dns, zk, etcd), [load balancers](../cn/load_balancing.md#负载均衡) (rr, random, consistent hashing)
# Advantages of brpc
......
......@@ -28,6 +28,8 @@ sudo make install
Config brpc with thrift support, then make. The compiled libbrpc.a includes extended code for thrift support and can be linked normally as in other brpc projects.
```bash
sh config_brpc.sh --headers=/usr/include --libs=/usr/lib --with-thrift
#or use cmake
mkdir build && cd build && cmake ../ -DWITH_THRIFT=1
```
# Client accesses thrift server
......@@ -95,7 +97,7 @@ public:
example::EchoRequest* req = request->Cast<example::EchoRequest>();
example::EchoResponse* res = response->Cast<example::EchoResponse>();
       // Get method-name for thrift via cntl->thrift_method_name()
       // Get method-name for thrift by cntl->thrift_method_name();
       if (_native_handler) {
_native_handler->Echo(*res, *req);
} else {
......
......@@ -16,6 +16,17 @@ protobuf_generate_cpp(PROTO_SRC PROTO_HEADER echo.proto)
# include PROTO_HEADER
include_directories(${CMAKE_CURRENT_BINARY_DIR})
# Search for libthrift* by best effort. If it is not found and brpc is
# compiled with thrift protocol enabled, a link error would be reported.
find_library(THRIFT_LIB NAMES thrift)
if (NOT THRIFT_LIB)
set(THRIFT_LIB "")
endif()
find_library(THRIFTNB_LIB NAMES thriftnb)
if (NOT THRIFTNB_LIB)
set(THRIFTNB_LIB "")
endif()
find_path(BRPC_INCLUDE_PATH NAMES brpc/server.h)
if(EXAMPLE_LINK_SO)
find_library(BRPC_LIB NAMES brpc)
......@@ -91,6 +102,8 @@ set(DYNAMIC_LIB
${LEVELDB_LIB}
${SSL_LIB}
${CRYPTO_LIB}
${THRIFT_LIB}
${THRIFTNB_LIB}
dl
)
......@@ -105,8 +118,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
"-framework Foundation"
"-Wl,-U,_MallocExtension_ReleaseFreeMemory"
"-Wl,-U,_ProfilerStart"
"-Wl,-U,_ProfilerStop"
"-Wl,-U,_RegisterThriftProtocol")
"-Wl,-U,_ProfilerStop")
endif()
add_executable(asynchronous_echo_client client.cpp ${PROTO_SRC})
......
......@@ -16,6 +16,17 @@ protobuf_generate_cpp(PROTO_SRC PROTO_HEADER echo.proto)
# include PROTO_HEADER
include_directories(${CMAKE_CURRENT_BINARY_DIR})
# Search for libthrift* by best effort. If it is not found and brpc is
# compiled with thrift protocol enabled, a link error would be reported.
find_library(THRIFT_LIB NAMES thrift)
if (NOT THRIFT_LIB)
set(THRIFT_LIB "")
endif()
find_library(THRIFTNB_LIB NAMES thriftnb)
if (NOT THRIFTNB_LIB)
set(THRIFTNB_LIB "")
endif()
find_path(BRPC_INCLUDE_PATH NAMES brpc/server.h)
if(EXAMPLE_LINK_SO)
find_library(BRPC_LIB NAMES brpc)
......@@ -91,6 +102,8 @@ set(DYNAMIC_LIB
${LEVELDB_LIB}
${SSL_LIB}
${CRYPTO_LIB}
${THRIFT_LIB}
${THRIFTNB_LIB}
dl
)
......@@ -105,8 +118,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
"-framework Foundation"
"-Wl,-U,_MallocExtension_ReleaseFreeMemory"
"-Wl,-U,_ProfilerStart"
"-Wl,-U,_ProfilerStop"
"-Wl,-U,_RegisterThriftProtocol")
"-Wl,-U,_ProfilerStop")
endif()
add_executable(backup_request_client client.cpp ${PROTO_SRC} ${PROTO_HEADER})
......
......@@ -16,6 +16,17 @@ protobuf_generate_cpp(PROTO_SRC PROTO_HEADER echo.proto)
# include PROTO_HEADER
include_directories(${CMAKE_CURRENT_BINARY_DIR})
# Search for libthrift* by best effort. If it is not found and brpc is
# compiled with thrift protocol enabled, a link error would be reported.
find_library(THRIFT_LIB NAMES thrift)
if (NOT THRIFT_LIB)
set(THRIFT_LIB "")
endif()
find_library(THRIFTNB_LIB NAMES thriftnb)
if (NOT THRIFTNB_LIB)
set(THRIFTNB_LIB "")
endif()
find_path(BRPC_INCLUDE_PATH NAMES brpc/server.h)
if(EXAMPLE_LINK_SO)
find_library(BRPC_LIB NAMES brpc)
......@@ -91,6 +102,8 @@ set(DYNAMIC_LIB
${LEVELDB_LIB}
${SSL_LIB}
${CRYPTO_LIB}
${THRIFT_LIB}
${THRIFTNB_LIB}
dl
)
......@@ -105,8 +118,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
"-framework Foundation"
"-Wl,-U,_MallocExtension_ReleaseFreeMemory"
"-Wl,-U,_ProfilerStart"
"-Wl,-U,_ProfilerStop"
"-Wl,-U,_RegisterThriftProtocol")
"-Wl,-U,_ProfilerStop")
endif()
add_executable(cancel_client client.cpp ${PROTO_SRC} ${PROTO_HEADER})
......
......@@ -15,6 +15,17 @@ protobuf_generate_cpp(PROTO_SRC PROTO_HEADER echo.proto)
# include PROTO_HEADER
include_directories(${CMAKE_CURRENT_BINARY_DIR})
# Search for libthrift* by best effort. If it is not found and brpc is
# compiled with thrift protocol enabled, a link error would be reported.
find_library(THRIFT_LIB NAMES thrift)
if (NOT THRIFT_LIB)
set(THRIFT_LIB "")
endif()
find_library(THRIFTNB_LIB NAMES thriftnb)
if (NOT THRIFTNB_LIB)
set(THRIFTNB_LIB "")
endif()
find_path(BRPC_INCLUDE_PATH NAMES brpc/server.h)
if(EXAMPLE_LINK_SO)
find_library(BRPC_LIB NAMES brpc)
......@@ -90,6 +101,8 @@ set(DYNAMIC_LIB
${LEVELDB_LIB}
${SSL_LIB}
${CRYPTO_LIB}
${THRIFT_LIB}
${THRIFTNB_LIB}
dl
)
......@@ -104,8 +117,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
"-framework Foundation"
"-Wl,-U,_MallocExtension_ReleaseFreeMemory"
"-Wl,-U,_ProfilerStart"
"-Wl,-U,_ProfilerStop"
"-Wl,-U,_RegisterThriftProtocol")
"-Wl,-U,_ProfilerStop")
endif()
add_executable(cascade_echo_client client.cpp ${PROTO_SRC} ${PROTO_HEADER})
......
......@@ -20,6 +20,17 @@ find_path(GPERFTOOLS_INCLUDE_DIR NAMES gperftools/heap-profiler.h)
find_library(GPERFTOOLS_LIBRARIES NAMES tcmalloc_and_profiler)
include_directories(${GPERFTOOLS_INCLUDE_DIR})
# Search for libthrift* by best effort. If it is not found and brpc is
# compiled with thrift protocol enabled, a link error would be reported.
find_library(THRIFT_LIB NAMES thrift)
if (NOT THRIFT_LIB)
set(THRIFT_LIB "")
endif()
find_library(THRIFTNB_LIB NAMES thriftnb)
if (NOT THRIFTNB_LIB)
set(THRIFTNB_LIB "")
endif()
find_path(BRPC_INCLUDE_PATH NAMES brpc/server.h)
if(EXAMPLE_LINK_SO)
find_library(BRPC_LIB NAMES brpc)
......@@ -96,6 +107,8 @@ set(DYNAMIC_LIB
${LEVELDB_LIB}
${SSL_LIB}
${CRYPTO_LIB}
${THRIFT_LIB}
${THRIFTNB_LIB}
dl
)
......@@ -110,8 +123,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
"-framework Foundation"
"-Wl,-U,_MallocExtension_ReleaseFreeMemory"
"-Wl,-U,_ProfilerStart"
"-Wl,-U,_ProfilerStop"
"-Wl,-U,_RegisterThriftProtocol")
"-Wl,-U,_ProfilerStop")
endif()
add_executable(dynamic_partition_echo_client client.cpp ${PROTO_SRC} ${PROTO_HEADER})
......
......@@ -16,6 +16,17 @@ protobuf_generate_cpp(PROTO_SRC PROTO_HEADER echo.proto)
# include PROTO_HEADER
include_directories(${CMAKE_CURRENT_BINARY_DIR})
# Search for libthrift* by best effort. If it is not found and brpc is
# compiled with thrift protocol enabled, a link error would be reported.
find_library(THRIFT_LIB NAMES thrift)
if (NOT THRIFT_LIB)
set(THRIFT_LIB "")
endif()
find_library(THRIFTNB_LIB NAMES thriftnb)
if (NOT THRIFTNB_LIB)
set(THRIFTNB_LIB "")
endif()
find_path(BRPC_INCLUDE_PATH NAMES brpc/server.h)
if(EXAMPLE_LINK_SO)
find_library(BRPC_LIB NAMES brpc)
......@@ -94,6 +105,8 @@ set(DYNAMIC_LIB
${LEVELDB_LIB}
${SSL_LIB}
${CRYPTO_LIB}
${THRIFT_LIB}
${THRIFTNB_LIB}
dl
)
......@@ -108,8 +121,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
"-framework Foundation"
"-Wl,-U,_MallocExtension_ReleaseFreeMemory"
"-Wl,-U,_ProfilerStart"
"-Wl,-U,_ProfilerStop"
"-Wl,-U,_RegisterThriftProtocol")
"-Wl,-U,_ProfilerStop")
endif()
target_link_libraries(echo_client ${BRPC_LIB} ${DYNAMIC_LIB})
......
......@@ -16,6 +16,17 @@ protobuf_generate_cpp(PROTO_SRC PROTO_HEADER echo.proto)
# include PROTO_HEADER
include_directories(${CMAKE_CURRENT_BINARY_DIR})
# Search for libthrift* by best effort. If it is not found and brpc is
# compiled with thrift protocol enabled, a link error would be reported.
find_library(THRIFT_LIB NAMES thrift)
if (NOT THRIFT_LIB)
set(THRIFT_LIB "")
endif()
find_library(THRIFTNB_LIB NAMES thriftnb)
if (NOT THRIFTNB_LIB)
set(THRIFTNB_LIB "")
endif()
find_path(BRPC_INCLUDE_PATH NAMES brpc/server.h)
if(EXAMPLE_LINK_SO)
find_library(BRPC_LIB NAMES brpc)
......@@ -91,6 +102,8 @@ set(DYNAMIC_LIB
${LEVELDB_LIB}
${SSL_LIB}
${CRYPTO_LIB}
${THRIFT_LIB}
${THRIFTNB_LIB}
dl
)
......@@ -105,8 +118,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
"-framework Foundation"
"-Wl,-U,_MallocExtension_ReleaseFreeMemory"
"-Wl,-U,_ProfilerStart"
"-Wl,-U,_ProfilerStop"
"-Wl,-U,_RegisterThriftProtocol")
"-Wl,-U,_ProfilerStop")
endif()
add_executable(echo_hulu_pbrpc_client client.cpp ${PROTO_SRC} ${PROTO_HEADER})
......
......@@ -16,6 +16,17 @@ protobuf_generate_cpp(PROTO_SRC PROTO_HEADER echo.proto)
# include PROTO_HEADER
include_directories(${CMAKE_CURRENT_BINARY_DIR})
# Search for libthrift* by best effort. If it is not found and brpc is
# compiled with thrift protocol enabled, a link error would be reported.
find_library(THRIFT_LIB NAMES thrift)
if (NOT THRIFT_LIB)
set(THRIFT_LIB "")
endif()
find_library(THRIFTNB_LIB NAMES thriftnb)
if (NOT THRIFTNB_LIB)
set(THRIFTNB_LIB "")
endif()
find_path(BRPC_INCLUDE_PATH NAMES brpc/server.h)
if(EXAMPLE_LINK_SO)
find_library(BRPC_LIB NAMES brpc)
......@@ -91,6 +102,8 @@ set(DYNAMIC_LIB
${LEVELDB_LIB}
${SSL_LIB}
${CRYPTO_LIB}
${THRIFT_LIB}
${THRIFTNB_LIB}
dl
)
......@@ -105,8 +118,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
"-framework Foundation"
"-Wl,-U,_MallocExtension_ReleaseFreeMemory"
"-Wl,-U,_ProfilerStart"
"-Wl,-U,_ProfilerStop"
"-Wl,-U,_RegisterThriftProtocol")
"-Wl,-U,_ProfilerStop")
endif()
add_executable(echo_sofa_pbrpc_client client.cpp ${PROTO_SRC} ${PROTO_HEADER})
......
......@@ -16,6 +16,17 @@ protobuf_generate_cpp(PROTO_SRC PROTO_HEADER echo.proto)
# include PROTO_HEADER
include_directories(${CMAKE_CURRENT_BINARY_DIR})
# Search for libthrift* by best effort. If it is not found and brpc is
# compiled with thrift protocol enabled, a link error would be reported.
find_library(THRIFT_LIB NAMES thrift)
if (NOT THRIFT_LIB)
set(THRIFT_LIB "")
endif()
find_library(THRIFTNB_LIB NAMES thriftnb)
if (NOT THRIFTNB_LIB)
set(THRIFTNB_LIB "")
endif()
find_path(BRPC_INCLUDE_PATH NAMES brpc/server.h)
if(EXAMPLE_LINK_SO)
find_library(BRPC_LIB NAMES brpc)
......@@ -91,6 +102,8 @@ set(DYNAMIC_LIB
${LEVELDB_LIB}
${SSL_LIB}
${CRYPTO_LIB}
${THRIFT_LIB}
${THRIFTNB_LIB}
dl
)
......@@ -105,8 +118,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
"-framework Foundation"
"-Wl,-U,_MallocExtension_ReleaseFreeMemory"
"-Wl,-U,_ProfilerStart"
"-Wl,-U,_ProfilerStop"
"-Wl,-U,_RegisterThriftProtocol")
"-Wl,-U,_ProfilerStop")
endif()
execute_process(
......
......@@ -16,6 +16,17 @@ protobuf_generate_cpp(PROTO_SRC PROTO_HEADER http.proto)
# include PROTO_HEADER
include_directories(${CMAKE_CURRENT_BINARY_DIR})
# Search for libthrift* by best effort. If it is not found and brpc is
# compiled with thrift protocol enabled, a link error would be reported.
find_library(THRIFT_LIB NAMES thrift)
if (NOT THRIFT_LIB)
set(THRIFT_LIB "")
endif()
find_library(THRIFTNB_LIB NAMES thriftnb)
if (NOT THRIFTNB_LIB)
set(THRIFTNB_LIB "")
endif()
find_path(GPERFTOOLS_INCLUDE_DIR NAMES gperftools/heap-profiler.h)
find_library(GPERFTOOLS_LIBRARIES NAMES tcmalloc_and_profiler)
include_directories(${GPERFTOOLS_INCLUDE_DIR})
......@@ -97,6 +108,8 @@ set(DYNAMIC_LIB
${LEVELDB_LIB}
${SSL_LIB}
${CRYPTO_LIB}
${THRIFT_LIB}
${THRIFTNB_LIB}
dl
)
......@@ -111,8 +124,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
"-framework Foundation"
"-Wl,-U,_MallocExtension_ReleaseFreeMemory"
"-Wl,-U,_ProfilerStart"
"-Wl,-U,_ProfilerStop"
"-Wl,-U,_RegisterThriftProtocol")
"-Wl,-U,_ProfilerStop")
endif()
add_executable(http_client http_client.cpp)
......
......@@ -16,6 +16,17 @@ protobuf_generate_cpp(PROTO_SRC PROTO_HEADER echo.proto)
# include PROTO_HEADER
include_directories(${CMAKE_CURRENT_BINARY_DIR})
# Search for libthrift* by best effort. If it is not found and brpc is
# compiled with thrift protocol enabled, a link error would be reported.
find_library(THRIFT_LIB NAMES thrift)
if (NOT THRIFT_LIB)
set(THRIFT_LIB "")
endif()
find_library(THRIFTNB_LIB NAMES thriftnb)
if (NOT THRIFTNB_LIB)
set(THRIFTNB_LIB "")
endif()
find_path(BRPC_INCLUDE_PATH NAMES brpc/server.h)
if(EXAMPLE_LINK_SO)
find_library(BRPC_LIB NAMES brpc)
......@@ -91,6 +102,8 @@ set(DYNAMIC_LIB
${LEVELDB_LIB}
${SSL_LIB}
${CRYPTO_LIB}
${THRIFT_LIB}
${THRIFTNB_LIB}
dl
)
......@@ -105,8 +118,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
"-framework Foundation"
"-Wl,-U,_MallocExtension_ReleaseFreeMemory"
"-Wl,-U,_ProfilerStart"
"-Wl,-U,_ProfilerStop"
"-Wl,-U,_RegisterThriftProtocol")
"-Wl,-U,_ProfilerStop")
endif()
add_executable(memcache_client client.cpp)
......
......@@ -16,6 +16,17 @@ protobuf_generate_cpp(PROTO_SRC PROTO_HEADER echo.proto)
# include PROTO_HEADER
include_directories(${CMAKE_CURRENT_BINARY_DIR})
# Search for libthrift* by best effort. If it is not found and brpc is
# compiled with thrift protocol enabled, a link error would be reported.
find_library(THRIFT_LIB NAMES thrift)
if (NOT THRIFT_LIB)
set(THRIFT_LIB "")
endif()
find_library(THRIFTNB_LIB NAMES thriftnb)
if (NOT THRIFTNB_LIB)
set(THRIFTNB_LIB "")
endif()
find_path(GPERFTOOLS_INCLUDE_DIR NAMES gperftools/heap-profiler.h)
find_library(GPERFTOOLS_LIBRARIES NAMES tcmalloc_and_profiler)
include_directories(${GPERFTOOLS_INCLUDE_DIR})
......@@ -96,6 +107,8 @@ set(DYNAMIC_LIB
${LEVELDB_LIB}
${SSL_LIB}
${CRYPTO_LIB}
${THRIFT_LIB}
${THRIFTNB_LIB}
dl
)
......@@ -110,8 +123,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
"-framework Foundation"
"-Wl,-U,_MallocExtension_ReleaseFreeMemory"
"-Wl,-U,_ProfilerStart"
"-Wl,-U,_ProfilerStop"
"-Wl,-U,_RegisterThriftProtocol")
"-Wl,-U,_ProfilerStop")
endif()
add_executable(multi_threaded_echo_client client.cpp ${PROTO_SRC} ${PROTO_HEADER})
......
......@@ -16,6 +16,17 @@ protobuf_generate_cpp(PROTO_SRC PROTO_HEADER echo.proto)
# include PROTO_HEADER
include_directories(${CMAKE_CURRENT_BINARY_DIR})
# Search for libthrift* by best effort. If it is not found and brpc is
# compiled with thrift protocol enabled, a link error would be reported.
find_library(THRIFT_LIB NAMES thrift)
if (NOT THRIFT_LIB)
set(THRIFT_LIB "")
endif()
find_library(THRIFTNB_LIB NAMES thriftnb)
if (NOT THRIFTNB_LIB)
set(THRIFTNB_LIB "")
endif()
find_path(GPERFTOOLS_INCLUDE_DIR NAMES gperftools/heap-profiler.h)
find_library(GPERFTOOLS_LIBRARIES NAMES tcmalloc_and_profiler)
include_directories(${GPERFTOOLS_INCLUDE_DIR})
......@@ -96,6 +107,8 @@ set(DYNAMIC_LIB
${LEVELDB_LIB}
${SSL_LIB}
${CRYPTO_LIB}
${THRIFT_LIB}
${THRIFTNB_LIB}
dl
)
......@@ -110,8 +123,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
"-framework Foundation"
"-Wl,-U,_MallocExtension_ReleaseFreeMemory"
"-Wl,-U,_ProfilerStart"
"-Wl,-U,_ProfilerStop"
"-Wl,-U,_RegisterThriftProtocol")
"-Wl,-U,_ProfilerStop")
endif()
add_executable(multi_threaded_echo_fns_client client.cpp ${PROTO_SRC} ${PROTO_HEADER})
......
......@@ -16,6 +16,17 @@ protobuf_generate_cpp(PROTO_SRC PROTO_HEADER echo.proto)
# include PROTO_HEADER
include_directories(${CMAKE_CURRENT_BINARY_DIR})
# Search for libthrift* by best effort. If it is not found and brpc is
# compiled with thrift protocol enabled, a link error would be reported.
find_library(THRIFT_LIB NAMES thrift)
if (NOT THRIFT_LIB)
set(THRIFT_LIB "")
endif()
find_library(THRIFTNB_LIB NAMES thriftnb)
if (NOT THRIFTNB_LIB)
set(THRIFTNB_LIB "")
endif()
find_path(GPERFTOOLS_INCLUDE_DIR NAMES gperftools/heap-profiler.h)
find_library(GPERFTOOLS_LIBRARIES NAMES tcmalloc_and_profiler)
include_directories(${GPERFTOOLS_INCLUDE_DIR})
......@@ -96,6 +107,8 @@ set(DYNAMIC_LIB
${LEVELDB_LIB}
${SSL_LIB}
${CRYPTO_LIB}
${THRIFT_LIB}
${THRIFTNB_LIB}
dl
)
......@@ -110,8 +123,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
"-framework Foundation"
"-Wl,-U,_MallocExtension_ReleaseFreeMemory"
"-Wl,-U,_ProfilerStart"
"-Wl,-U,_ProfilerStop"
"-Wl,-U,_RegisterThriftProtocol")
"-Wl,-U,_ProfilerStop")
endif()
execute_process(
......
......@@ -16,6 +16,17 @@ protobuf_generate_cpp(PROTO_SRC PROTO_HEADER echo.proto)
# include PROTO_HEADER
include_directories(${CMAKE_CURRENT_BINARY_DIR})
# Search for libthrift* by best effort. If it is not found and brpc is
# compiled with thrift protocol enabled, a link error would be reported.
find_library(THRIFT_LIB NAMES thrift)
if (NOT THRIFT_LIB)
set(THRIFT_LIB "")
endif()
find_library(THRIFTNB_LIB NAMES thriftnb)
if (NOT THRIFTNB_LIB)
set(THRIFTNB_LIB "")
endif()
find_path(BRPC_INCLUDE_PATH NAMES brpc/server.h)
if(EXAMPLE_LINK_SO)
find_library(BRPC_LIB NAMES brpc)
......@@ -91,6 +102,8 @@ set(DYNAMIC_LIB
${LEVELDB_LIB}
${SSL_LIB}
${CRYPTO_LIB}
${THRIFT_LIB}
${THRIFTNB_LIB}
dl
)
......@@ -105,8 +118,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
"-framework Foundation"
"-Wl,-U,_MallocExtension_ReleaseFreeMemory"
"-Wl,-U,_ProfilerStart"
"-Wl,-U,_ProfilerStop"
"-Wl,-U,_RegisterThriftProtocol")
"-Wl,-U,_ProfilerStop")
endif()
add_executable(nshead_extension_client client.cpp)
......
......@@ -16,6 +16,17 @@ protobuf_generate_cpp(PROTO_SRC PROTO_HEADER echo.proto)
# include PROTO_HEADER
include_directories(${CMAKE_CURRENT_BINARY_DIR})
# Search for libthrift* by best effort. If it is not found and brpc is
# compiled with thrift protocol enabled, a link error would be reported.
find_library(THRIFT_LIB NAMES thrift)
if (NOT THRIFT_LIB)
set(THRIFT_LIB "")
endif()
find_library(THRIFTNB_LIB NAMES thriftnb)
if (NOT THRIFTNB_LIB)
set(THRIFTNB_LIB "")
endif()
find_path(BRPC_INCLUDE_PATH NAMES brpc/server.h)
if(EXAMPLE_LINK_SO)
find_library(BRPC_LIB NAMES brpc)
......@@ -91,6 +102,8 @@ set(DYNAMIC_LIB
${LEVELDB_LIB}
${SSL_LIB}
${CRYPTO_LIB}
${THRIFT_LIB}
${THRIFTNB_LIB}
dl
)
......@@ -105,8 +118,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
"-framework Foundation"
"-Wl,-U,_MallocExtension_ReleaseFreeMemory"
"-Wl,-U,_ProfilerStart"
"-Wl,-U,_ProfilerStop"
"-Wl,-U,_RegisterThriftProtocol")
"-Wl,-U,_ProfilerStop")
endif()
add_executable(nshead_pb_extension_client client.cpp ${PROTO_SRC} ${PROTO_HEADER})
......
......@@ -16,6 +16,17 @@ protobuf_generate_cpp(PROTO_SRC PROTO_HEADER echo.proto)
# include PROTO_HEADER
include_directories(${CMAKE_CURRENT_BINARY_DIR})
# Search for libthrift* by best effort. If it is not found and brpc is
# compiled with thrift protocol enabled, a link error would be reported.
find_library(THRIFT_LIB NAMES thrift)
if (NOT THRIFT_LIB)
set(THRIFT_LIB "")
endif()
find_library(THRIFTNB_LIB NAMES thriftnb)
if (NOT THRIFTNB_LIB)
set(THRIFTNB_LIB "")
endif()
find_path(GPERFTOOLS_INCLUDE_DIR NAMES gperftools/heap-profiler.h)
find_library(GPERFTOOLS_LIBRARIES NAMES tcmalloc_and_profiler)
include_directories(${GPERFTOOLS_INCLUDE_DIR})
......@@ -96,6 +107,8 @@ set(DYNAMIC_LIB
${LEVELDB_LIB}
${SSL_LIB}
${CRYPTO_LIB}
${THRIFT_LIB}
${THRIFTNB_LIB}
dl
)
......@@ -110,8 +123,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
"-framework Foundation"
"-Wl,-U,_MallocExtension_ReleaseFreeMemory"
"-Wl,-U,_ProfilerStart"
"-Wl,-U,_ProfilerStop"
"-Wl,-U,_RegisterThriftProtocol")
"-Wl,-U,_ProfilerStop")
endif()
add_executable(parallel_echo_client client.cpp ${PROTO_SRC} ${PROTO_HEADER})
......
......@@ -16,6 +16,17 @@ protobuf_generate_cpp(PROTO_SRC PROTO_HEADER echo.proto)
# include PROTO_HEADER
include_directories(${CMAKE_CURRENT_BINARY_DIR})
# Search for libthrift* by best effort. If it is not found and brpc is
# compiled with thrift protocol enabled, a link error would be reported.
find_library(THRIFT_LIB NAMES thrift)
if (NOT THRIFT_LIB)
set(THRIFT_LIB "")
endif()
find_library(THRIFTNB_LIB NAMES thriftnb)
if (NOT THRIFTNB_LIB)
set(THRIFTNB_LIB "")
endif()
find_path(GPERFTOOLS_INCLUDE_DIR NAMES gperftools/heap-profiler.h)
find_library(GPERFTOOLS_LIBRARIES NAMES tcmalloc_and_profiler)
include_directories(${GPERFTOOLS_INCLUDE_DIR})
......@@ -96,6 +107,8 @@ set(DYNAMIC_LIB
${LEVELDB_LIB}
${SSL_LIB}
${CRYPTO_LIB}
${THRIFT_LIB}
${THRIFTNB_LIB}
dl
)
......@@ -110,8 +123,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
"-framework Foundation"
"-Wl,-U,_MallocExtension_ReleaseFreeMemory"
"-Wl,-U,_ProfilerStart"
"-Wl,-U,_ProfilerStop"
"-Wl,-U,_RegisterThriftProtocol")
"-Wl,-U,_ProfilerStop")
endif()
add_executable(client client.cpp ${PROTO_SRC} ${PROTO_HEADER})
......
......@@ -21,6 +21,17 @@ set(CMAKE_PREFIX_PATH ${OUTPUT_PATH})
include(FindThreads)
include(FindProtobuf)
# Search for libthrift* by best effort. If it is not found and brpc is
# compiled with thrift protocol enabled, a link error would be reported.
find_library(THRIFT_LIB NAMES thrift)
if (NOT THRIFT_LIB)
set(THRIFT_LIB "")
endif()
find_library(THRIFTNB_LIB NAMES thriftnb)
if (NOT THRIFTNB_LIB)
set(THRIFTNB_LIB "")
endif()
find_path(BRPC_INCLUDE_PATH NAMES brpc/server.h)
if(EXAMPLE_LINK_SO)
find_library(BRPC_LIB NAMES brpc)
......@@ -96,6 +107,8 @@ set(DYNAMIC_LIB
${LEVELDB_LIB}
${SSL_LIB}
${CRYPTO_LIB}
${THRIFT_LIB}
${THRIFTNB_LIB}
dl
)
......@@ -110,8 +123,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
"-framework Foundation"
"-Wl,-U,_MallocExtension_ReleaseFreeMemory"
"-Wl,-U,_ProfilerStart"
"-Wl,-U,_ProfilerStop"
"-Wl,-U,_RegisterThriftProtocol")
"-Wl,-U,_ProfilerStop")
endif()
add_executable(redis_cli redis_cli.cpp)
......
......@@ -16,6 +16,17 @@ protobuf_generate_cpp(PROTO_SRC PROTO_HEADER echo.proto)
# include PROTO_HEADER
include_directories(${CMAKE_CURRENT_BINARY_DIR})
# Search for libthrift* by best effort. If it is not found and brpc is
# compiled with thrift protocol enabled, a link error would be reported.
find_library(THRIFT_LIB NAMES thrift)
if (NOT THRIFT_LIB)
set(THRIFT_LIB "")
endif()
find_library(THRIFTNB_LIB NAMES thriftnb)
if (NOT THRIFTNB_LIB)
set(THRIFTNB_LIB "")
endif()
find_path(GPERFTOOLS_INCLUDE_DIR NAMES gperftools/heap-profiler.h)
find_library(GPERFTOOLS_LIBRARIES NAMES tcmalloc_and_profiler)
include_directories(${GPERFTOOLS_INCLUDE_DIR})
......@@ -96,6 +107,8 @@ set(DYNAMIC_LIB
${LEVELDB_LIB}
${SSL_LIB}
${CRYPTO_LIB}
${THRIFT_LIB}
${THRIFTNB_LIB}
dl
)
......@@ -110,8 +123,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
"-framework Foundation"
"-Wl,-U,_MallocExtension_ReleaseFreeMemory"
"-Wl,-U,_ProfilerStart"
"-Wl,-U,_ProfilerStop"
"-Wl,-U,_RegisterThriftProtocol")
"-Wl,-U,_ProfilerStop")
endif()
add_executable(selective_echo_client client.cpp ${PROTO_SRC} ${PROTO_HEADER})
......
......@@ -16,6 +16,17 @@ protobuf_generate_cpp(PROTO_SRC PROTO_HEADER echo.proto)
# include PROTO_HEADER
include_directories(${CMAKE_CURRENT_BINARY_DIR})
# Search for libthrift* by best effort. If it is not found and brpc is
# compiled with thrift protocol enabled, a link error would be reported.
find_library(THRIFT_LIB NAMES thrift)
if (NOT THRIFT_LIB)
set(THRIFT_LIB "")
endif()
find_library(THRIFTNB_LIB NAMES thriftnb)
if (NOT THRIFTNB_LIB)
set(THRIFTNB_LIB "")
endif()
find_path(GPERFTOOLS_INCLUDE_DIR NAMES gperftools/heap-profiler.h)
find_library(GPERFTOOLS_LIBRARIES NAMES tcmalloc_and_profiler)
include_directories(${GPERFTOOLS_INCLUDE_DIR})
......@@ -103,6 +114,8 @@ set(DYNAMIC_LIB
${LEVELDB_LIB}
${SSL_LIB}
${CRYPTO_LIB}
${THRIFT_LIB}
${THRIFTNB_LIB}
dl
)
......@@ -117,8 +130,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
"-framework Foundation"
"-Wl,-U,_MallocExtension_ReleaseFreeMemory"
"-Wl,-U,_ProfilerStart"
"-Wl,-U,_ProfilerStop"
"-Wl,-U,_RegisterThriftProtocol")
"-Wl,-U,_ProfilerStop")
endif()
add_executable(session_data_and_thread_local_client client.cpp ${PROTO_SRC} ${PROTO_HEADER})
......
......@@ -16,6 +16,17 @@ protobuf_generate_cpp(PROTO_SRC PROTO_HEADER echo.proto)
# include PROTO_HEADER
include_directories(${CMAKE_CURRENT_BINARY_DIR})
# Search for libthrift* by best effort. If it is not found and brpc is
# compiled with thrift protocol enabled, a link error would be reported.
find_library(THRIFT_LIB NAMES thrift)
if (NOT THRIFT_LIB)
set(THRIFT_LIB "")
endif()
find_library(THRIFTNB_LIB NAMES thriftnb)
if (NOT THRIFTNB_LIB)
set(THRIFTNB_LIB "")
endif()
find_path(BRPC_INCLUDE_PATH NAMES brpc/server.h)
if(EXAMPLE_LINK_SO)
find_library(BRPC_LIB NAMES brpc)
......@@ -91,6 +102,8 @@ set(DYNAMIC_LIB
${LEVELDB_LIB}
${SSL_LIB}
${CRYPTO_LIB}
${THRIFT_LIB}
${THRIFTNB_LIB}
dl
)
......@@ -105,8 +118,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
"-framework Foundation"
"-Wl,-U,_MallocExtension_ReleaseFreeMemory"
"-Wl,-U,_ProfilerStart"
"-Wl,-U,_ProfilerStop"
"-Wl,-U,_RegisterThriftProtocol")
"-Wl,-U,_ProfilerStop")
endif()
add_executable(streaming_echo_client client.cpp ${PROTO_SRC} ${PROTO_HEADER})
......
......@@ -3,7 +3,7 @@ include $(BRPC_PATH)/config.mk
# Notes on the flags:
# 1. Added -fno-omit-frame-pointer: perf/tcmalloc-profiler use frame pointers by default
# 2. Added -D__const__= : Avoid over-optimizations of TLS variables by GCC>=4.8
CXXFLAGS = -std=c++0x -g -DENABLE_THRIFT_FRAMED_PROTOCOL -DDEBUG -D__const__= -pipe -W -Wall -Werror -Wno-unused-parameter -fPIC -fno-omit-frame-pointer
CXXFLAGS = -std=c++0x -g -DDEBUG -D__const__= -pipe -W -Wall -Werror -Wno-unused-parameter -fPIC -fno-omit-frame-pointer
HDRS+=$(BRPC_PATH)/output/include
LIBS+=$(BRPC_PATH)/output/lib
HDRPATHS = $(addprefix -I, $(HDRS))
......@@ -11,7 +11,7 @@ LIBPATHS = $(addprefix -L, $(LIBS))
COMMA=,
SOPATHS=$(addprefix -Wl$(COMMA)-rpath=, $(LIBS))
STATIC_LINKINGS += -lbrpc -lthrift -lgflags -Wl,--whole-archive -Wl,--no-whole-archive -levent
STATIC_LINKINGS += -lthrift -lgflags -lbrpc -levent
CLIENT_SOURCES = client.cpp
SERVER_SOURCES = server.cpp
......
......@@ -18,7 +18,7 @@
#include <butil/logging.h>
#include <brpc/server.h>
#include <brpc/thrift_service.h>
#include <brpc/details/thrift_utils.h>
#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/transport/TBufferTransports.h>
......@@ -65,6 +65,7 @@ public:
return;
}
// get method name by cntl->thrift_method_name() if needed
example::EchoRequest* req = request->Cast<example::EchoRequest>();
example::EchoResponse* res = response->Cast<example::EchoResponse>();
......@@ -78,6 +79,8 @@ public:
} else {
res->data = req->data + " (processed directly)";
}
}
private:
......
package(default_visibility = ["//visibility:public"])
config_setting(
name = "darwin",
values = {"cpu": "darwin"},
visibility = ["//visibility:public"],
)
SOURCES = ["db/builder.cc",
"db/c.cc",
"db/dbformat.cc",
......@@ -63,8 +70,13 @@ cc_library(
],
copts = [
"-fno-builtin-memcmp",
"-DOS_LINUX",
"-DLEVELDB_PLATFORM_POSIX=1",
"-DLEVELDB_ATOMIC_PRESENT",
],
defines = [
"LEVELDB_PLATFORM_POSIX",
] + select({
":darwin": ["OS_MACOSX"],
"//conditions:default": [],
}),
)
\ No newline at end of file
......@@ -22,6 +22,9 @@
#include "brpc/details/method_status.h" // MethodStatus
#include "brpc/builtin/status_service.h"
#include "brpc/nshead_service.h" // NsheadService
#ifdef ENABLE_THRIFT_FRAMED_PROTOCOL
#include "brpc/thrift_service.h" // ThriftService
#endif
#include "brpc/rtmp.h" // RtmpService
#include "brpc/builtin/common.h"
......@@ -187,6 +190,19 @@ void StatusService::default_method(::google::protobuf::RpcController* cntl_base,
nshead_svc->_status->Describe(os, desc_options);
os << '\n';
}
#ifdef ENABLE_THRIFT_FRAMED_PROTOCOL
const ThriftService* thrift_svc = server->options().thrift_service;
if (thrift_svc && thrift_svc->_status) {
DescribeOptions options;
options.verbose = false;
options.use_html = use_html;
os << (use_html ? "<h3>" : "[");
thrift_svc->Describe(os, options);
os << (use_html ? "</h3>\n" : "]\n");
thrift_svc->_status->Describe(os, desc_options);
os << '\n';
}
#endif
if (policy::g_server_msg_status) {
DescribeOptions options;
options.verbose = false;
......
......@@ -454,7 +454,7 @@ public:
void set_thrift_method_name(const std::string& method_name) {
_thrift_method_name = method_name;
}
std::string thrift_method_name() { return _thrift_method_name; }
const std::string& thrift_method_name() { return _thrift_method_name; }
private:
struct CompletionInfo {
......
......@@ -14,12 +14,11 @@
// utils for serialize/parse thrift binary message to brpc protobuf obj.
#ifdef ENABLE_THRIFT_FRAMED_PROTOCOL
#ifndef BRPC_THRIFT_UTILS_H
#define BRPC_THRIFT_UTILS_H
#include "butil/iobuf.h"
#include "butil/logging.h"
#include <thrift/TDispatchProcessor.h>
#include <thrift/transport/TBufferTransports.h>
......@@ -51,8 +50,8 @@ uint32_t thrift_framed_message_writer(void* p, void* prot) {
}
template<typename T>
bool serialize_iobuf_to_thrift_message(butil::IOBuf& body,
void* thrift_raw_instance, std::string* method_name, int32_t* thrift_message_seq_id) {
bool serialize_iobuf_to_thrift_message(const butil::IOBuf& body,
void* thrift_raw_instance, int32_t* thrift_message_seq_id) {
auto in_buffer =
THRIFT_STDCXX::make_shared<apache::thrift::transport::TMemoryBuffer>();
......@@ -75,7 +74,7 @@ bool serialize_iobuf_to_thrift_message(butil::IOBuf& body,
std::string fname;
::apache::thrift::protocol::TMessageType mtype;
in_portocol->readMessageBegin(*method_name, mtype, *thrift_message_seq_id);
in_portocol->readMessageBegin(fname, mtype, *thrift_message_seq_id);
apache::thrift::protocol::TInputRecursionTracker tracker(*in_portocol);
uint32_t xfer = 0;
......@@ -120,4 +119,3 @@ bool serialize_iobuf_to_thrift_message(butil::IOBuf& body,
#endif //BRPC_THRIFT_UTILS_H
#endif //ENABLE_THRIFT_FRAMED_PROTOCOL
......@@ -77,7 +77,10 @@
extern "C" {
// defined in gperftools/malloc_extension_c.h
void BAIDU_WEAK MallocExtension_ReleaseFreeMemory(void);
void BAIDU_WEAK RegisterThriftProtocol();
// Register Thrift Protocol if thrift was enabled
#ifdef ENABLE_THRIFT_FRAMED_PROTOCOL
void RegisterThriftProtocol();
#endif
}
namespace brpc {
......@@ -466,10 +469,10 @@ static void GlobalInitializeOrDieImpl() {
exit(1);
}
// Register Thrift framed protocol if linked
if (RegisterThriftProtocol) {
// Use Macro is more straight forward than weak link technology(becasue of static link issue)
#ifdef ENABLE_THRIFT_FRAMED_PROTOCOL
RegisterThriftProtocol();
}
#endif
// Only valid at client side
Protocol ubrpc_compack_protocol = {
......
......@@ -14,8 +14,6 @@
// Authors: wangxuefeng (wangxuefeng@didichuxing.com)
#ifdef ENABLE_THRIFT_FRAMED_PROTOCOL
#include <google/protobuf/descriptor.h> // MethodDescriptor
#include <google/protobuf/message.h> // Message
#include <gflags/gflags.h>
......@@ -54,6 +52,38 @@ void bthread_assign_data(void* data) __THROW;
namespace brpc {
static int32_t parse_thrift_method_name(const butil::IOBuf& body, std::string* method_name) {
// Thrift protocol format:
// Version + Message type + Length + Method + Sequence Id
// | | | | |
// 2 + 2 + 4 + >0 + 4
if (body.size() < 12) {
LOG(ERROR) << "No Enough data to get method name, request body size: " << body.size();
return -1;
}
char version_and_len_buf[8];
size_t k = body.copy_to(version_and_len_buf, sizeof(version_and_len_buf));
if (k != sizeof(version_and_len_buf) ) {
LOG(ERROR) << "copy "<< sizeof(version_and_len_buf) << " bytes from body failed";
return -1;
}
uint32_t method_name_length = ntohl(*(int32_t*)(version_and_len_buf + 4));
char fname[method_name_length];
k = body.copy_to(fname, method_name_length, sizeof(version_and_len_buf));
if ( k != method_name_length) {
LOG(ERROR) << "copy " << method_name_length << " bytes from body failed";
return -1;
}
method_name->assign(fname, method_name_length);
return sizeof(version_and_len_buf) + method_name_length;
}
ThriftClosure::ThriftClosure(void* additional_space)
: _socket_ptr(NULL)
, _server(NULL)
......@@ -114,7 +144,7 @@ void ThriftClosure::Run() {
_response.head = _request.head;
if (_response.thrift_raw_instance) {
std::string method_name = _request.method_name;
const std::string& method_name = _controller.thrift_method_name();
if (method_name == "" ||
method_name.length() < 1 ||
method_name[0] == ' ') {
......@@ -250,6 +280,15 @@ struct CallMethodInBackupThreadArgs {
static void CallMethodInBackupThread(void* void_args) {
CallMethodInBackupThreadArgs* args = (CallMethodInBackupThreadArgs*)void_args;
std::string method_name;
if (parse_thrift_method_name(args->request->body, &method_name) < 0) {
LOG(ERROR) << "Fail to get thrift method name";
delete args;
return;
}
args->controller->set_thrift_method_name(method_name);
args->service->ProcessThriftFramedRequest(*args->server, args->controller,
args->request, args->response,
args->done);
......@@ -382,23 +421,38 @@ void ProcessThriftRequest(InputMessageBase* msg_base) {
span->AsParent();
}
try {
std::string method_name;
if (parse_thrift_method_name(req->body, &method_name) < 0) {
cntl->SetFailed(EREQUEST, "Fail to get thrift method name!");
return;
}
cntl->set_thrift_method_name(method_name);
if (!FLAGS_usercode_in_pthread) {
try {
return service->ProcessThriftFramedRequest(*server, cntl,
req, res, thrift_done);
} catch (::apache::thrift::TException& e) {
cntl->SetFailed(EREQUEST, "Invalid request data, reason: %s", e.what());
} catch (...) {
cntl->SetFailed(EINTERNAL, "Internal server error!");
}
}
if (BeginRunningUserCode()) {
try {
service->ProcessThriftFramedRequest(*server, cntl, req, res, thrift_done);
return EndRunningUserCodeInPlace();
} else {
return EndRunningCallMethodInPool(
service, *server, cntl, req, res, thrift_done);
}
} catch (::apache::thrift::TException& e) {
cntl->SetFailed(EREQUEST, "Invalid request data, reason: %s", e.what());
} catch (...) {
cntl->SetFailed(EINTERNAL, "Internal server error!");
}
return EndRunningUserCodeInPlace();
} else {
return EndRunningCallMethodInPool(
service, *server, cntl, req, res, thrift_done);
}
}
......@@ -648,4 +702,3 @@ void RegisterThriftProtocol() {
}
}
#endif
......@@ -14,8 +14,6 @@
// Authors: wangxuefeng (wangxuefeng@didichuxing.com)
#ifdef ENABLE_THRIFT_FRAMED_PROTOCOL
#ifndef BRPC_POLICY_THRIFT_PROTOCOL_H
#define BRPC_POLICY_THRIFT_PROTOCOL_H
......@@ -51,6 +49,4 @@ bool VerifyThriftRequest(const InputMessageBase *msg);
} // namespace policy
} // namespace brpc
#endif // BRPC_POLICY_THRIFT_PROTOCOL_H
#endif
......@@ -40,7 +40,9 @@
#include "brpc/details/ssl_helper.h" // CreateServerSSLContext
#include "brpc/protocol.h" // ListProtocols
#include "brpc/nshead_service.h" // NsheadService
#ifdef ENABLE_THRIFT_FRAMED_PROTOCOL
#include "brpc/thrift_service.h" // ThriftService
#endif
#include "brpc/builtin/bad_method_service.h" // BadMethodService
#include "brpc/builtin/get_favicon_service.h"
#include "brpc/builtin/get_js_service.h"
......
......@@ -14,8 +14,6 @@
// Authors: wangxuefeng (wangxuefeng@didichuxing.com)
#ifdef ENABLE_THRIFT_FRAMED_PROTOCOL
#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION
#include "brpc/thrift_message.h"
......@@ -127,8 +125,6 @@ void ThriftFramedMessage::SharedCtor() {
thrift_raw_instance_deleter = nullptr;
thrift_raw_instance = nullptr;
thrift_message_seq_id = 0;
method_name = "";
//RegisterThriftProtocolDummy dummy;
}
ThriftFramedMessage::~ThriftFramedMessage() {
......@@ -246,4 +242,3 @@ void ThriftFramedMessage::Swap(ThriftFramedMessage* other) {
} // namespace brpc
#endif
......@@ -14,8 +14,6 @@
// Authors: wangxuefeng (wangxuefeng@didichuxing.com)
#ifdef ENABLE_THRIFT_FRAMED_PROTOCOL
#ifndef BRPC_THRIFT_MESSAGE_H
#define BRPC_THRIFT_MESSAGE_H
......@@ -57,7 +55,6 @@ public:
void* thrift_raw_instance;
int32_t thrift_message_seq_id;
std::string method_name;
public:
ThriftFramedMessage();
......@@ -94,8 +91,8 @@ public:
int GetCachedSize() const { return ByteSize(); }
::google::protobuf::Metadata GetMetadata() const;
virtual uint32_t write(void* oprot) { return 0;}
virtual uint32_t read(void* iprot) { return 0;}
virtual uint32_t write(void* /*oprot*/) { return 0;}
virtual uint32_t read(void* /*iprot*/) { return 0;}
template<typename T>
T* Cast() {
......@@ -105,8 +102,7 @@ public:
// serialize binary thrift message to thrift struct request
// for response, we just return the new instance and deserialize it in Closure
if (body.size() > 0 ) {
if (serialize_iobuf_to_thrift_message<T>(body, thrift_raw_instance,
&method_name, &thrift_message_seq_id)) {
if (serialize_iobuf_to_thrift_message<T>(body, thrift_raw_instance, &thrift_message_seq_id)) {
} else {
delete static_cast<T*>(thrift_raw_instance);
return nullptr;
......@@ -167,4 +163,3 @@ private:
#endif // BRPC_THRIFT_MESSAGE_H
#endif //ENABLE_THRIFT_FRAMED_PROTOCOL
......@@ -13,7 +13,6 @@
// limitations under the License.
// Authors: wangxuefeng (wangxuefeng@didichuxing.com)
#ifdef ENABLE_THRIFT_FRAMED_PROTOCOL
#include "butil/class_name.h"
#include "brpc/thrift_service.h"
......@@ -58,4 +57,3 @@ void ThriftService::Expose(const butil::StringPiece& prefix) {
} // namespace brpc
#endif
......@@ -14,8 +14,6 @@
// Authors: wangxuefeng (wangxuefeng@didichuxing.com)
#ifdef ENABLE_THRIFT_FRAMED_PROTOCOL
#ifndef BRPC_THRIFT_SERVICE_H
#define BRPC_THRIFT_SERVICE_H
......@@ -130,5 +128,3 @@ private:
#endif // BRPC_THRIFT_SERVICE_H
#endif
......@@ -98,7 +98,7 @@ int bthread_id_lock_verbose(bthread_id_t id, void** pdata,
const char *location);
// Lock `id' (for using the data exclusively) and reset the range. If `id' is
// locked by others, wait until `id' is unlocked or destroyed. if `range' if
// locked by others, wait until `id' is unlocked or destroyed. if `range' is
// smaller than the original range of this id, nothing happens about the range
#define bthread_id_lock_and_reset_range(id, pdata, range) \
bthread_id_lock_and_reset_range_verbose(id, pdata, range, \
......
......@@ -23,12 +23,19 @@
#include <string.h> // strcpy
#include <stdio.h> // snprintf
#include <stdlib.h> // strtol
#include <gflags/gflags.h>
#include "butil/fd_guard.h" // fd_guard
#include "butil/endpoint.h" // ip_t
#include "butil/logging.h"
#include "butil/memory/singleton_on_pthread_once.h"
#include "butil/strings/string_piece.h"
#ifndef SO_REUSEPORT
#define SO_REUSEPORT 15
#endif
//This option is supported since Linux 3.9.
DEFINE_bool(reuse_port, false, "turn on support for SO_REUSEPORT socket option.");
__BEGIN_DECLS
int BAIDU_WEAK bthread_connect(
int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen) {
......@@ -313,6 +320,15 @@ int tcp_listen(EndPoint point, bool reuse_addr) {
return -1;
}
}
if (FLAGS_reuse_port) {
const int on = 1;
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEPORT,
&on, sizeof(on)) != 0) {
LOG(WARNING) << "Fail to setsockopt SO_REUSEPORT of sockfd=" << sockfd;
}
}
struct sockaddr_in serv_addr;
bzero((char*)&serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
......
load("//:bazel/brpc.bzl", "brpc_proto_library")
config_setting(
name = "darwin",
values = {"cpu": "darwin"},
visibility = ["//visibility:public"],
)
COPTS = [
"-D__STDC_FORMAT_MACROS",
"-DBTHREAD_USE_FAST_PTHREAD_MUTEX",
......@@ -27,12 +33,17 @@ COPTS = [
LINKOPTS = [
"-lpthread",
"-lrt",
"-lssl",
"-lcrypto",
"-ldl",
"-lz",
]
] + select({
":darwin": [],
"//conditions:default": [
"-lrt",
],
})
TEST_BUTIL_SOURCES = [
"at_exit_unittest.cc",
......@@ -48,7 +59,6 @@ TEST_BUTIL_SOURCES = [
"cpu_unittest.cc",
"crash_logging_unittest.cc",
"leak_tracker_unittest.cc",
"proc_maps_linux_unittest.cc",
"stack_trace_unittest.cc",
"environment_unittest.cc",
"file_util_unittest.cc",
......@@ -129,10 +139,15 @@ TEST_BUTIL_SOURCES = [
"iobuf_unittest.cpp",
"test_switches.cc",
"scoped_locale.cc",
"test_file_util_linux.cc",
#"popen_unittest.cpp",
"butil_unittest_main.cpp",
]
] + select({
"@bazel_tools//tools/osx:darwin": [],
"//conditions:default": [
"test_file_util_linux.cc",
"proc_maps_linux_unittest.cc",
],
})
proto_library(
name = "test_proto",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment