brpc源码

This commit is contained in:
yangzuhao
2022-12-14 20:13:26 +08:00
parent fd6441d247
commit 0cf6c335b8
1989 changed files with 225300 additions and 140559 deletions
+23
View File
@@ -0,0 +1,23 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
include(FindProtobuf)
protobuf_generate_cpp(PROTO_SRC PROTO_HEADER view.proto)
include_directories(${CMAKE_CURRENT_BINARY_DIR})
add_executable(rpc_view rpc_view.cpp ${PROTO_SRC})
target_link_libraries(rpc_view brpc-static ${DYNAMIC_LIB})
+60
View File
@@ -0,0 +1,60 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
BRPC_PATH = ../../
include $(BRPC_PATH)/config.mk
# Notes on the flags:
# 1. Added -fno-omit-frame-pointer: perf/tcmalloc-profiler use frame pointers by default
CXXFLAGS = $(CPPFLAGS) -std=c++0x -DNDEBUG -O2 -pipe -W -Wall -Wno-unused-parameter -fPIC -fno-omit-frame-pointer
HDRPATHS = -I$(BRPC_PATH)/output/include $(addprefix -I, $(HDRS))
LIBPATHS = -L$(BRPC_PATH)/output/lib $(addprefix -L, $(LIBS))
STATIC_LINKINGS += $(BRPC_PATH)/output/lib/libbrpc.a
CLIENT_SOURCES = rpc_view.cpp
PROTOS = $(wildcard *.proto)
PROTO_OBJS = $(PROTOS:.proto=.pb.o)
PROTO_GENS = $(PROTOS:.proto=.pb.h) $(PROTOS:.proto=.pb.cc)
CLIENT_OBJS = $(addsuffix .o, $(basename $(CLIENT_SOURCES)))
.PHONY:all
all: rpc_view
.PHONY:clean
clean:
@echo "> Cleaning"
rm -rf rpc_view $(PROTO_GENS) $(PROTO_OBJS) $(CLIENT_OBJS)
rpc_view:$(PROTO_OBJS) $(CLIENT_OBJS)
@echo "> Linking $@"
ifeq ($(SYSTEM),Linux)
$(CXX) $(LIBPATHS) -Xlinker "-(" $^ -Wl,-Bstatic $(STATIC_LINKINGS) -Wl,-Bdynamic -Xlinker "-)" $(DYNAMIC_LINKINGS) -o $@
else ifeq ($(SYSTEM),Darwin)
$(CXX) $(LIBPATHS) $^ $(STATIC_LINKINGS) $(DYNAMIC_LINKINGS) -o $@
endif
%.pb.cc %.pb.h:%.proto
@echo "> Generating $@"
$(PROTOC) --cpp_out=. --proto_path=. $(PROTOC_EXTRA_ARGS) $<
%.o:%.cpp
@echo "> Compiling $@"
$(CXX) -c $(HDRPATHS) $(CXXFLAGS) $< -o $@
%.o:%.cc
@echo "> Compiling $@"
$(CXX) -c $(HDRPATHS) $(CXXFLAGS) $< -o $@
+176
View File
@@ -0,0 +1,176 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#include <gflags/gflags.h>
#include <butil/logging.h>
#include <brpc/server.h>
#include <brpc/channel.h>
#include "view.pb.h"
DEFINE_int32(port, 8888, "TCP Port of this server");
DEFINE_string(target, "", "The server to view");
DEFINE_int32(timeout_ms, 5000, "Timeout for calling the server to view");
// handle HTTP response of accessing builtin services of the target server.
static void handle_response(brpc::Controller* client_cntl,
std::string target,
brpc::Controller* server_cntl,
google::protobuf::Closure* server_done) {
// Copy all headers. The "Content-Length" will be overwriteen.
server_cntl->http_response() = client_cntl->http_response();
// Copy content.
server_cntl->response_attachment() = client_cntl->response_attachment();
// Insert "rpc_view: <target>" before </body> so that users are always
// visually notified with target server w/o confusions.
butil::IOBuf& content = server_cntl->response_attachment();
butil::IOBuf before_body;
if (content.cut_until(&before_body, "</body>") == 0) {
before_body.append(
"<style type=\"text/css\">\n"
".rpcviewlogo {position: fixed; bottom: 0px; right: 0px;"
" color: #ffffff; background-color: #000000; }\n"
" </style>\n"
"<span class='rpcviewlogo'>&nbsp;rpc_view: ");
before_body.append(target);
before_body.append("&nbsp;</span></body>");
before_body.append(content);
content = before_body;
}
// Notice that we don't set RPC to failed on http errors because we
// want to pass unchanged content to the users otherwise RPC replaces
// the content with ErrorText.
if (client_cntl->Failed() &&
client_cntl->ErrorCode() != brpc::EHTTP) {
server_cntl->SetFailed(client_cntl->ErrorCode(),
"%s", client_cntl->ErrorText().c_str());
}
delete client_cntl;
server_done->Run();
}
// A http_master_service.
class ViewServiceImpl : public ViewService {
public:
ViewServiceImpl() {}
virtual ~ViewServiceImpl() {}
virtual void default_method(google::protobuf::RpcController* cntl_base,
const HttpRequest*,
HttpResponse*,
google::protobuf::Closure* done) {
brpc::ClosureGuard done_guard(done);
brpc::Controller* server_cntl =
static_cast<brpc::Controller*>(cntl_base);
// Get or set target. Notice that we don't access FLAGS_target directly
// which is thread-unsafe (for string flags).
std::string target;
const std::string* newtarget =
server_cntl->http_request().uri().GetQuery("changetarget");
if (newtarget) {
if (GFLAGS_NS::SetCommandLineOption("target", newtarget->c_str()).empty()) {
server_cntl->SetFailed("Fail to change value of -target");
return;
}
target = *newtarget;
} else {
if (!GFLAGS_NS::GetCommandLineOption("target", &target)) {
server_cntl->SetFailed("Fail to get value of -target");
return;
}
}
// Create the http channel on-the-fly. Notice that we've set
// `defer_close_second' in main() so that dtor of channels do not
// close connections immediately and ad-hoc creation of channels
// often reuses the not-yet-closed connections.
brpc::Channel http_chan;
brpc::ChannelOptions http_chan_opt;
http_chan_opt.protocol = brpc::PROTOCOL_HTTP;
if (http_chan.Init(target.c_str(), &http_chan_opt) != 0) {
server_cntl->SetFailed(brpc::EINTERNAL,
"Fail to connect to %s", target.c_str());
return;
}
// Remove "Accept-Encoding". We need to insert additional texts
// before </body>, preventing the server from compressing the content
// simplifies our code. The additional bandwidth consumption shouldn't
// be an issue for infrequent checking out of builtin services pages.
server_cntl->http_request().RemoveHeader("Accept-Encoding");
brpc::Controller* client_cntl = new brpc::Controller;
client_cntl->http_request() = server_cntl->http_request();
// Remove "Host" so that RPC will laterly serialize the (correct)
// target server in.
client_cntl->http_request().RemoveHeader("host");
// Setup the URI.
const brpc::URI& server_uri = server_cntl->http_request().uri();
std::string uri = server_uri.path();
if (!server_uri.query().empty()) {
uri.push_back('?');
uri.append(server_uri.query());
}
if (!server_uri.fragment().empty()) {
uri.push_back('#');
uri.append(server_uri.fragment());
}
client_cntl->http_request().uri() = uri;
// /hotspots pages may take a long time to finish, since they all have
// query "seconds", we set the timeout to be longer than "seconds".
const std::string* seconds =
server_cntl->http_request().uri().GetQuery("seconds");
int64_t timeout_ms = FLAGS_timeout_ms;
if (seconds) {
timeout_ms += atoll(seconds->c_str()) * 1000;
}
client_cntl->set_timeout_ms(timeout_ms);
// Keep content as it is.
client_cntl->request_attachment() = server_cntl->request_attachment();
http_chan.CallMethod(NULL, client_cntl, NULL, NULL,
brpc::NewCallback(
handle_response, client_cntl, target,
server_cntl, done_guard.release()));
}
};
int main(int argc, char* argv[]) {
GFLAGS_NS::ParseCommandLineFlags(&argc, &argv, true);
if (FLAGS_target.empty() &&
(argc != 2 ||
GFLAGS_NS::SetCommandLineOption("target", argv[1]).empty())) {
LOG(ERROR) << "Usage: ./rpc_view <ip>:<port>";
return -1;
}
// This keeps ad-hoc creation of channels reuse previous connections.
GFLAGS_NS::SetCommandLineOption("defer_close_second", "10");
brpc::Server server;
server.set_version("rpc_view_server");
brpc::ServerOptions server_opt;
server_opt.http_master_service = new ViewServiceImpl;
if (server.Start(FLAGS_port, &server_opt) != 0) {
LOG(ERROR) << "Fail to start ViewServer";
return -1;
}
server.RunUntilAskedToQuit();
return 0;
}
+26
View File
@@ -0,0 +1,26 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
syntax="proto2";
option cc_generic_services = true;
message HttpRequest {};
message HttpResponse {};
service ViewService {
rpc default_method(HttpRequest) returns (HttpResponse);
};