From b587e96996d24e4f32b3ad755b20c033dfb39b8c Mon Sep 17 00:00:00 2001 From: lianxuechao Date: Thu, 14 Nov 2024 16:32:50 +0800 Subject: [PATCH 1/9] method level option to ignore server eovercrowded --- src/brpc/policy/baidu_rpc_protocol.cpp | 5 ++ src/brpc/policy/http_rpc_protocol.cpp | 2 +- src/brpc/policy/hulu_pbrpc_protocol.cpp | 12 ++--- src/brpc/policy/sofa_pbrpc_protocol.cpp | 11 ++-- src/brpc/server.cpp | 69 +++++++++++++++++++++++++ src/brpc/server.h | 16 ++++++ 6 files changed, 102 insertions(+), 13 deletions(-) diff --git a/src/brpc/policy/baidu_rpc_protocol.cpp b/src/brpc/policy/baidu_rpc_protocol.cpp index 53866262b5..fc24be11de 100644 --- a/src/brpc/policy/baidu_rpc_protocol.cpp +++ b/src/brpc/policy/baidu_rpc_protocol.cpp @@ -586,6 +586,11 @@ void ProcessRpcRequest(InputMessageBase* msg_base) { mp->service->CallMethod(mp->method, cntl.get(), &breq, &bres, NULL); break; } + if (socket->is_overcrowded() && !server->options().ignore_eovercrowded && !mp->ignore_eovercrowded) { + cntl->SetFailed(EOVERCROWDED, "Connection to %s is overcrowded", + butil::endpoint2str(socket->remote_side()).c_str()); + break; + } // Switch to service-specific error. non_service_error.release(); method_status = mp->status; diff --git a/src/brpc/policy/http_rpc_protocol.cpp b/src/brpc/policy/http_rpc_protocol.cpp index 76f43c0524..fe13d59d80 100644 --- a/src/brpc/policy/http_rpc_protocol.cpp +++ b/src/brpc/policy/http_rpc_protocol.cpp @@ -1495,7 +1495,7 @@ void ProcessHttpRequest(InputMessageBase *msg) { // NOTE: accesses to builtin services are not counted as part of // concurrency, therefore are not limited by ServerOptions.max_concurrency. if (!sp->is_builtin_service && !sp->params.is_tabbed) { - if (socket->is_overcrowded() && !server->options().ignore_eovercrowded) { + if (socket->is_overcrowded() && !server->options().ignore_eovercrowded && !sp->ignore_eovercrowded) { cntl->SetFailed(EOVERCROWDED, "Connection to %s is overcrowded", butil::endpoint2str(socket->remote_side()).c_str()); return; diff --git a/src/brpc/policy/hulu_pbrpc_protocol.cpp b/src/brpc/policy/hulu_pbrpc_protocol.cpp index 20e9c827d2..c12212718e 100644 --- a/src/brpc/policy/hulu_pbrpc_protocol.cpp +++ b/src/brpc/policy/hulu_pbrpc_protocol.cpp @@ -422,12 +422,6 @@ void ProcessHuluRequest(InputMessageBase* msg_base) { break; } - if (socket->is_overcrowded() && !server->options().ignore_eovercrowded) { - cntl->SetFailed(EOVERCROWDED, "Connection to %s is overcrowded", - butil::endpoint2str(socket->remote_side()).c_str()); - break; - } - if (!server_accessor.AddConcurrency(cntl.get())) { cntl->SetFailed(ELIMIT, "Reached server's max_concurrency=%d", server->options().max_concurrency); @@ -454,6 +448,12 @@ void ProcessHuluRequest(InputMessageBase* msg_base) { sp->service->CallMethod(sp->method, cntl.get(), &breq, &bres, NULL); break; } + if (socket->is_overcrowded() && !server->options().ignore_eovercrowded && !sp->ignore_eovercrowded) { + cntl->SetFailed(EOVERCROWDED, "Connection to %s is overcrowded", + butil::endpoint2str(socket->remote_side()).c_str()); + break; + } + // Switch to service-specific error. non_service_error.release(); method_status = sp->status; diff --git a/src/brpc/policy/sofa_pbrpc_protocol.cpp b/src/brpc/policy/sofa_pbrpc_protocol.cpp index ad58022ffd..b8f40c8a94 100644 --- a/src/brpc/policy/sofa_pbrpc_protocol.cpp +++ b/src/brpc/policy/sofa_pbrpc_protocol.cpp @@ -381,12 +381,6 @@ void ProcessSofaRequest(InputMessageBase* msg_base) { break; } - if (socket->is_overcrowded() && !server->options().ignore_eovercrowded) { - cntl->SetFailed(EOVERCROWDED, "Connection to %s is overcrowded", - butil::endpoint2str(socket->remote_side()).c_str()); - break; - } - if (!server_accessor.AddConcurrency(cntl.get())) { cntl->SetFailed( ELIMIT, "Reached server's max_concurrency=%d", @@ -406,6 +400,11 @@ void ProcessSofaRequest(InputMessageBase* msg_base) { meta.method().c_str()); break; } + if (socket->is_overcrowded() && !server->options().ignore_eovercrowded && !sp->ignore_eovercrowded) { + cntl->SetFailed(EOVERCROWDED, "Connection to %s is overcrowded", + butil::endpoint2str(socket->remote_side()).c_str()); + break; + } // Switch to service-specific error. non_service_error.release(); method_status = sp->status; diff --git a/src/brpc/server.cpp b/src/brpc/server.cpp index 0110761af7..f576390b13 100644 --- a/src/brpc/server.cpp +++ b/src/brpc/server.cpp @@ -795,6 +795,7 @@ static bool OptionsAvailableOverRdma(const ServerOptions* opt) { #endif static AdaptiveMaxConcurrency g_default_max_concurrency_of_method(0); +static bool g_default_ignore_eovercrowded(false); int Server::StartInternal(const butil::EndPoint& endpoint, const PortRange& port_range, @@ -2302,6 +2303,74 @@ int Server::MaxConcurrencyOf(google::protobuf::Service* service, return MaxConcurrencyOf(service->GetDescriptor()->full_name(), method_name); } +bool& Server::IgnoreEovercrowdedOf(MethodProperty* mp) { + if (IsRunning()) { + LOG(WARNING) << "IgnoreEovercrowdedOf is only allowd before Server started"; + return g_default_ignore_eovercrowded; + } + if (mp->status == NULL) { + LOG(ERROR) << "method=" << mp->method->full_name() + << " does not support max_concurrency"; + _failed_to_set_max_concurrency_of_method = true; + return g_default_ignore_eovercrowded; + } + return mp->ignore_eovercrowded; +} + +bool Server::IgnoreEovercrowdedOf(const MethodProperty* mp) const { + if (IsRunning()) { + LOG(WARNING) << "IgnoreEovercrowdedOf is only allowd before Server started"; + return g_default_ignore_eovercrowded; + } + if (mp == NULL || mp->status == NULL) { + return false; + } + return mp->ignore_eovercrowded; +} + +bool& Server::IgnoreEovercrowdedOf(const butil::StringPiece& full_method_name) { + MethodProperty* mp = _method_map.seek(full_method_name); + if (mp == NULL) { + LOG(ERROR) << "Fail to find method=" << full_method_name; + _failed_to_set_max_concurrency_of_method = true; + return g_default_ignore_eovercrowded; + } + return IgnoreEovercrowdedOf(mp); +} + +bool Server::IgnoreEovercrowdedOf(const butil::StringPiece& full_method_name) const { + return IgnoreEovercrowdedOf(_method_map.seek(full_method_name)); +} + +bool& Server::IgnoreEovercrowdedOf(const butil::StringPiece& full_service_name, + const butil::StringPiece& method_name) { + MethodProperty* mp = const_cast( + FindMethodPropertyByFullName(full_service_name, method_name)); + if (mp == NULL) { + LOG(ERROR) << "Fail to find method=" << full_service_name + << '/' << method_name; + _failed_to_set_max_concurrency_of_method = true; + return g_default_ignore_eovercrowded; + } + return IgnoreEovercrowdedOf(mp); +} + +bool Server::IgnoreEovercrowdedOf(const butil::StringPiece& full_service_name, + const butil::StringPiece& method_name) const { + return IgnoreEovercrowdedOf(FindMethodPropertyByFullName( + full_service_name, method_name)); +} + +bool& Server::IgnoreEovercrowdedOf(google::protobuf::Service* service, + const butil::StringPiece& method_name) { + return IgnoreEovercrowdedOf(service->GetDescriptor()->full_name(), method_name); +} + +bool Server::IgnoreEovercrowdedOf(google::protobuf::Service* service, + const butil::StringPiece& method_name) const { + return IgnoreEovercrowdedOf(service->GetDescriptor()->full_name(), method_name); +} + bool Server::AcceptRequest(Controller* cntl) const { const Interceptor* interceptor = _options.interceptor; if (!interceptor) { diff --git a/src/brpc/server.h b/src/brpc/server.h index ee5a500d1b..7bb5d399bc 100644 --- a/src/brpc/server.h +++ b/src/brpc/server.h @@ -417,6 +417,7 @@ class Server { const google::protobuf::MethodDescriptor* method; MethodStatus* status; AdaptiveMaxConcurrency max_concurrency; + bool ignore_eovercrowded = false; MethodProperty(); }; @@ -595,6 +596,19 @@ class Server { int MaxConcurrencyOf(google::protobuf::Service* service, const butil::StringPiece& method_name) const; + bool& IgnoreEovercrowdedOf(const butil::StringPiece& full_method_name); + bool IgnoreEovercrowdedOf(const butil::StringPiece& full_method_name) const; + + bool& IgnoreEovercrowdedOf(const butil::StringPiece& full_service_name, + const butil::StringPiece& method_name); + bool IgnoreEovercrowdedOf(const butil::StringPiece& full_service_name, + const butil::StringPiece& method_name) const; + + bool& IgnoreEovercrowdedOf(google::protobuf::Service* service, + const butil::StringPiece& method_name); + bool IgnoreEovercrowdedOf(google::protobuf::Service* service, + const butil::StringPiece& method_name) const; + int Concurrency() const { return butil::subtle::NoBarrier_Load(&_concurrency); }; @@ -699,6 +713,8 @@ friend class Controller; AdaptiveMaxConcurrency& MaxConcurrencyOf(MethodProperty*); int MaxConcurrencyOf(const MethodProperty*) const; + bool& IgnoreEovercrowdedOf(MethodProperty*); + bool IgnoreEovercrowdedOf(const MethodProperty*) const; static bool CreateConcurrencyLimiter(const AdaptiveMaxConcurrency& amc, ConcurrencyLimiter** out); From ab95b79493fd13500d793e2ecbab08084adb1dce Mon Sep 17 00:00:00 2001 From: lianxuechao Date: Thu, 14 Nov 2024 17:47:21 +0800 Subject: [PATCH 2/9] explain method-level option --- src/brpc/server.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/brpc/server.h b/src/brpc/server.h index 7bb5d399bc..dd5bd791b1 100644 --- a/src/brpc/server.h +++ b/src/brpc/server.h @@ -417,6 +417,10 @@ class Server { const google::protobuf::MethodDescriptor* method; MethodStatus* status; AdaptiveMaxConcurrency max_concurrency; + // ignore_eovercrowded on method-level, it should be used with carefulness. + // It might introduce inbalance between methods, + // as some methods(ignore_eovercrowded=1) might never return eovercrowded + // while other methods(ignore_eovercrowded=0) keep returning eovercrowded. bool ignore_eovercrowded = false; MethodProperty(); From e40add64a9feafede0de94eb559c90716dd451d7 Mon Sep 17 00:00:00 2001 From: lianxuechao Date: Thu, 14 Nov 2024 17:52:07 +0800 Subject: [PATCH 3/9] [fix] add _failed_to_set_ignore_eovercrowded --- src/brpc/server.cpp | 15 +++++++++++---- src/brpc/server.h | 1 + 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/brpc/server.cpp b/src/brpc/server.cpp index f576390b13..437ca82d08 100644 --- a/src/brpc/server.cpp +++ b/src/brpc/server.cpp @@ -412,6 +412,7 @@ Server::Server(ProfilerLinker) , _builtin_service_count(0) , _virtual_service_count(0) , _failed_to_set_max_concurrency_of_method(false) + , _failed_to_set_ignore_eovercrowded(false) , _am(NULL) , _internal_am(NULL) , _first_service(NULL) @@ -807,6 +808,12 @@ int Server::StartInternal(const butil::EndPoint& endpoint, "fix it before starting server"; return -1; } + if (_failed_to_set_ignore_eovercrowded) { + _failed_to_set_ignore_eovercrowded = false; + LOG(ERROR) << "previous call to IgnoreEovercrowdedOf() was failed, " + "fix it before starting server"; + return -1; + } if (InitializeOnce() != 0) { LOG(ERROR) << "Fail to initialize Server[" << version() << ']'; return -1; @@ -2310,8 +2317,8 @@ bool& Server::IgnoreEovercrowdedOf(MethodProperty* mp) { } if (mp->status == NULL) { LOG(ERROR) << "method=" << mp->method->full_name() - << " does not support max_concurrency"; - _failed_to_set_max_concurrency_of_method = true; + << " does not support ignore_eovercrowded"; + _failed_to_set_ignore_eovercrowded = true; return g_default_ignore_eovercrowded; } return mp->ignore_eovercrowded; @@ -2332,7 +2339,7 @@ bool& Server::IgnoreEovercrowdedOf(const butil::StringPiece& full_method_name) { MethodProperty* mp = _method_map.seek(full_method_name); if (mp == NULL) { LOG(ERROR) << "Fail to find method=" << full_method_name; - _failed_to_set_max_concurrency_of_method = true; + _failed_to_set_ignore_eovercrowded = true; return g_default_ignore_eovercrowded; } return IgnoreEovercrowdedOf(mp); @@ -2349,7 +2356,7 @@ bool& Server::IgnoreEovercrowdedOf(const butil::StringPiece& full_service_name, if (mp == NULL) { LOG(ERROR) << "Fail to find method=" << full_service_name << '/' << method_name; - _failed_to_set_max_concurrency_of_method = true; + _failed_to_set_ignore_eovercrowded = true; return g_default_ignore_eovercrowded; } return IgnoreEovercrowdedOf(mp); diff --git a/src/brpc/server.h b/src/brpc/server.h index dd5bd791b1..135f7b9d5c 100644 --- a/src/brpc/server.h +++ b/src/brpc/server.h @@ -751,6 +751,7 @@ friend class Controller; // number of the virtual services for mapping URL to methods. int _virtual_service_count; bool _failed_to_set_max_concurrency_of_method; + bool _failed_to_set_ignore_eovercrowded; Acceptor* _am; Acceptor* _internal_am; From cf5205055d699644dc37325c4216b6b5f99a8876 Mon Sep 17 00:00:00 2001 From: lianxuechao Date: Thu, 14 Nov 2024 17:53:22 +0800 Subject: [PATCH 4/9] [fix] update docs --- src/brpc/server.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/brpc/server.h b/src/brpc/server.h index 135f7b9d5c..01649ba0b5 100644 --- a/src/brpc/server.h +++ b/src/brpc/server.h @@ -420,7 +420,8 @@ class Server { // ignore_eovercrowded on method-level, it should be used with carefulness. // It might introduce inbalance between methods, // as some methods(ignore_eovercrowded=1) might never return eovercrowded - // while other methods(ignore_eovercrowded=0) keep returning eovercrowded. + // while other methods(ignore_eovercrowded=0) keep returning eovercrowded. + // currently only valid for baidu_rpc, http_rpc, hulu_pbrpc and sofa_pbrpc protocols bool ignore_eovercrowded = false; MethodProperty(); From d8833c5d9e8273b2df55ff5f64f508ffec61c8b1 Mon Sep 17 00:00:00 2001 From: lianxuechao Date: Wed, 20 Nov 2024 19:05:05 +0800 Subject: [PATCH 5/9] fix indent and add service level option in baidu_master_service --- src/brpc/baidu_master_service.h | 5 +++++ src/brpc/policy/baidu_rpc_protocol.cpp | 24 ++++++++++++++---------- src/brpc/policy/http_rpc_protocol.cpp | 4 +++- src/brpc/policy/hulu_pbrpc_protocol.cpp | 4 +++- src/brpc/policy/sofa_pbrpc_protocol.cpp | 4 +++- 5 files changed, 28 insertions(+), 13 deletions(-) diff --git a/src/brpc/baidu_master_service.h b/src/brpc/baidu_master_service.h index 9dc7ebbf90..5d8dbc3fbc 100644 --- a/src/brpc/baidu_master_service.h +++ b/src/brpc/baidu_master_service.h @@ -45,6 +45,10 @@ class BaiduMasterService : public ::google::protobuf::Service return _max_concurrency; } + bool& IgnoreEOverCrowded() { + return ignore_eovercrowded; + } + virtual void ProcessRpcRequest(Controller* cntl, const SerializedRequest* request, SerializedResponse* response, @@ -92,6 +96,7 @@ friend class Server; MethodStatus* _status; AdaptiveMaxConcurrency _max_concurrency; + bool ignore_eovercrowded = false; }; } diff --git a/src/brpc/policy/baidu_rpc_protocol.cpp b/src/brpc/policy/baidu_rpc_protocol.cpp index fc24be11de..9a4601e7f6 100644 --- a/src/brpc/policy/baidu_rpc_protocol.cpp +++ b/src/brpc/policy/baidu_rpc_protocol.cpp @@ -491,12 +491,6 @@ void ProcessRpcRequest(InputMessageBase* msg_base) { cntl->SetFailed(ELOGOFF, "Server is stopping"); break; } - - if (socket->is_overcrowded() && !server->options().ignore_eovercrowded) { - cntl->SetFailed(EOVERCROWDED, "Connection to %s is overcrowded", - butil::endpoint2str(socket->remote_side()).c_str()); - break; - } if (!server_accessor.AddConcurrency(cntl.get())) { cntl->SetFailed( @@ -524,6 +518,13 @@ void ProcessRpcRequest(InputMessageBase* msg_base) { google::protobuf::Service* svc = NULL; google::protobuf::MethodDescriptor* method = NULL; if (NULL != server->options().baidu_master_service) { + if (socket->is_overcrowded() && + !server->options().ignore_eovercrowded && + !server->options().baidu_master_service->IgnoreEOverCrowded()) { + cntl->SetFailed(EOVERCROWDED, "Connection to %s is overcrowded", + butil::endpoint2str(socket->remote_side()).c_str()); + break; + } svc = server->options().baidu_master_service; auto sampled_request = new (std::nothrow) SampledRequest; if (NULL == sampled_request) { @@ -586,10 +587,13 @@ void ProcessRpcRequest(InputMessageBase* msg_base) { mp->service->CallMethod(mp->method, cntl.get(), &breq, &bres, NULL); break; } - if (socket->is_overcrowded() && !server->options().ignore_eovercrowded && !mp->ignore_eovercrowded) { - cntl->SetFailed(EOVERCROWDED, "Connection to %s is overcrowded", - butil::endpoint2str(socket->remote_side()).c_str()); - break; + if (socket->is_overcrowded() && + !server->options().ignore_eovercrowded && + !mp->ignore_eovercrowded) { + cntl->SetFailed( + EOVERCROWDED, "Connection to %s is overcrowded", + butil::endpoint2str(socket->remote_side()).c_str()); + break; } // Switch to service-specific error. non_service_error.release(); diff --git a/src/brpc/policy/http_rpc_protocol.cpp b/src/brpc/policy/http_rpc_protocol.cpp index fe13d59d80..2dd18076fb 100644 --- a/src/brpc/policy/http_rpc_protocol.cpp +++ b/src/brpc/policy/http_rpc_protocol.cpp @@ -1495,7 +1495,9 @@ void ProcessHttpRequest(InputMessageBase *msg) { // NOTE: accesses to builtin services are not counted as part of // concurrency, therefore are not limited by ServerOptions.max_concurrency. if (!sp->is_builtin_service && !sp->params.is_tabbed) { - if (socket->is_overcrowded() && !server->options().ignore_eovercrowded && !sp->ignore_eovercrowded) { + if (socket->is_overcrowded() && + !server->options().ignore_eovercrowded && + !sp->ignore_eovercrowded) { cntl->SetFailed(EOVERCROWDED, "Connection to %s is overcrowded", butil::endpoint2str(socket->remote_side()).c_str()); return; diff --git a/src/brpc/policy/hulu_pbrpc_protocol.cpp b/src/brpc/policy/hulu_pbrpc_protocol.cpp index c12212718e..bf4bd86f5c 100644 --- a/src/brpc/policy/hulu_pbrpc_protocol.cpp +++ b/src/brpc/policy/hulu_pbrpc_protocol.cpp @@ -448,7 +448,9 @@ void ProcessHuluRequest(InputMessageBase* msg_base) { sp->service->CallMethod(sp->method, cntl.get(), &breq, &bres, NULL); break; } - if (socket->is_overcrowded() && !server->options().ignore_eovercrowded && !sp->ignore_eovercrowded) { + if (socket->is_overcrowded() && + !server->options().ignore_eovercrowded && + !sp->ignore_eovercrowded) { cntl->SetFailed(EOVERCROWDED, "Connection to %s is overcrowded", butil::endpoint2str(socket->remote_side()).c_str()); break; diff --git a/src/brpc/policy/sofa_pbrpc_protocol.cpp b/src/brpc/policy/sofa_pbrpc_protocol.cpp index b8f40c8a94..ae128b4051 100644 --- a/src/brpc/policy/sofa_pbrpc_protocol.cpp +++ b/src/brpc/policy/sofa_pbrpc_protocol.cpp @@ -400,7 +400,9 @@ void ProcessSofaRequest(InputMessageBase* msg_base) { meta.method().c_str()); break; } - if (socket->is_overcrowded() && !server->options().ignore_eovercrowded && !sp->ignore_eovercrowded) { + if (socket->is_overcrowded() && + !server->options().ignore_eovercrowded && + !sp->ignore_eovercrowded) { cntl->SetFailed(EOVERCROWDED, "Connection to %s is overcrowded", butil::endpoint2str(socket->remote_side()).c_str()); break; From 768c9b902ba771257ed378daa7c1c8a685c4059e Mon Sep 17 00:00:00 2001 From: lianxuechao Date: Thu, 21 Nov 2024 16:37:34 +0800 Subject: [PATCH 6/9] refactor constructor and update docs --- src/brpc/baidu_master_service.cpp | 2 +- src/brpc/baidu_master_service.h | 2 +- src/brpc/server.cpp | 3 ++- src/brpc/server.h | 8 ++++---- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/brpc/baidu_master_service.cpp b/src/brpc/baidu_master_service.cpp index 0b98373292..11083c2482 100644 --- a/src/brpc/baidu_master_service.cpp +++ b/src/brpc/baidu_master_service.cpp @@ -22,7 +22,7 @@ namespace brpc { BaiduMasterService::BaiduMasterService() - :_status(new(std::nothrow) MethodStatus) { + : _status(new (std::nothrow) MethodStatus), ignore_eovercrowded(false) { LOG_IF(FATAL, NULL == _status) << "Fail to new MethodStatus"; } diff --git a/src/brpc/baidu_master_service.h b/src/brpc/baidu_master_service.h index 5d8dbc3fbc..1747f06153 100644 --- a/src/brpc/baidu_master_service.h +++ b/src/brpc/baidu_master_service.h @@ -96,7 +96,7 @@ friend class Server; MethodStatus* _status; AdaptiveMaxConcurrency _max_concurrency; - bool ignore_eovercrowded = false; + bool ignore_eovercrowded; }; } diff --git a/src/brpc/server.cpp b/src/brpc/server.cpp index 437ca82d08..f557d1870c 100644 --- a/src/brpc/server.cpp +++ b/src/brpc/server.cpp @@ -180,7 +180,8 @@ Server::MethodProperty::MethodProperty() , http_url(NULL) , service(NULL) , method(NULL) - , status(NULL) { + , status(NULL) + , ignore_eovercrowded(false) { } static timeval GetUptime(void* arg/*start_time*/) { diff --git a/src/brpc/server.h b/src/brpc/server.h index 01649ba0b5..d609b4d85a 100644 --- a/src/brpc/server.h +++ b/src/brpc/server.h @@ -419,10 +419,10 @@ class Server { AdaptiveMaxConcurrency max_concurrency; // ignore_eovercrowded on method-level, it should be used with carefulness. // It might introduce inbalance between methods, - // as some methods(ignore_eovercrowded=1) might never return eovercrowded - // while other methods(ignore_eovercrowded=0) keep returning eovercrowded. - // currently only valid for baidu_rpc, http_rpc, hulu_pbrpc and sofa_pbrpc protocols - bool ignore_eovercrowded = false; + // as some methods(ignore_eovercrowded=true) might never return eovercrowded + // while other methods(ignore_eovercrowded=false) keep returning eovercrowded. + // currently only valid for baidu_master_service, baidu_rpc, http_rpc, hulu_pbrpc and sofa_pbrpc protocols + bool ignore_eovercrowded; MethodProperty(); }; From a4c4ba1b6ef96c5ab61dc3e894cf575d7f866769 Mon Sep 17 00:00:00 2001 From: lianxuechao Date: Tue, 26 Nov 2024 17:44:00 +0800 Subject: [PATCH 7/9] update server.md --- docs/cn/server.md | 20 ++++++++++++++++++++ docs/en/server.md | 22 ++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/docs/cn/server.md b/docs/cn/server.md index 9606ab1d40..9343a24832 100644 --- a/docs/cn/server.md +++ b/docs/cn/server.md @@ -1057,6 +1057,26 @@ Protobuf arena是一种Protobuf message内存管理机制,有着提高内存 注意:从Protobuf v3.14.0开始,[默认开启arena](https://github.com/protocolbuffers/protobuf/releases/tag/v3.14.0https://github.com/protocolbuffers/protobuf/releases/tag/v3.14.0)。但是Protobuf v3.14.0之前的版本,用户需要再proto文件中加上选项:`option cc_enable_arenas = true;`,所以为了兼容性,可以统一都加上该选项。 +## server端忽略eovercrowded +### server级别忽略eovercrowded +设置ServerOptions.ignore_eovercrowded,默认值0代表不忽略 + +### method级别忽略eovercrowded +server.IgnoreEovercrowdedOf("...") = ...可设置method级别的ignore_eovercrowded。也可以通过设置ServerOptions.ignore_eovercrowded一次性为所有的method设置忽略eovercrowded。 + +```c++ +ServerOptions.ignore_eovercrowded = true; // Set the default ignore_eovercrowded for all methods +server.IgnoreEovercrowdedOf("example.EchoService.Echo") = true; +server.IgnoreEovercrowdedOf("example.EchoService", "Echo") = true; +server.IgnoreEovercrowdedOf(&service, "Echo") = true; +``` + +此设置一般**发生在AddService后,server启动前**。当设置失败时(比如对应的method不存在),server会启动失败同时提示用户修正IgnoreEovercrowdedOf设置错误。 + +当ServerOptions.ignore_eovercrowded和server.IgnoreEovercrowdedOf("...")=...同时被设置时,任何一个设置为true,就表示会忽略eovercrowded。 + +注意:没有service级别的ignore_eovercrowded。 + # FAQ ### Q: Fail to write into fd=1865 SocketId=8905@10.208.245.43:54742@8230: Got EOF是什么意思 diff --git a/docs/en/server.md b/docs/en/server.md index 1c2923a6b3..3e26b58266 100644 --- a/docs/en/server.md +++ b/docs/en/server.md @@ -1051,6 +1051,28 @@ Users can set `ServerOptions.rpc_pb_message_factory = brpc::GetArenaRpcPBMessage Note: Since Protocol Buffers v3.14.0, Arenas are now unconditionally enabled. However, for versions prior to Protobuf v3.14.0, users need to add the option `option cc_enable_arenas = true;` to the proto file. so for compatibility, this option can be added uniformly. +## Ignoring eovercrowded on server-side +### Ignore eovercrowded on server-level + +Set ServerOptions.ignore_eovercrowded. Default value is 0 which means not ignored. + +### Ignore eovercrowded on method-level + +server.IgnoreEovercrowdedOf("...") = … sets ignore_eovercrowded of the method. Possible settings: + +```c++ +ServerOptions.ignore_eovercrowded = true; // Set the default ignore_eovercrowded for all methods +server.IgnoreEovercrowdedOf("example.EchoService.Echo") = true; +server.IgnoreEovercrowdedOf("example.EchoService", "Echo") = true; +server.IgnoreEovercrowdedOf(&service, "Echo") = true; +``` + +The code is generally put **after AddService, before Start() of the server**. When a setting fails(namely the method does not exist), server will fail to start and notify user to fix settings on IgnoreEovercrowdedOf. + +When method-level and server-level ignore_eovercrowded are both set, if any one of them is set to true, eovercrowded will be ignored. + +NOTE: No service-level ignore_eovercrowded. + # FAQ ### Q: Fail to write into fd=1865 SocketId=8905@10.208.245.43:54742@8230: Got EOF From 57bd3d6fef0047850acc7a1b963324405bd57a30 Mon Sep 17 00:00:00 2001 From: lianxuechao Date: Mon, 2 Dec 2024 11:38:59 +0800 Subject: [PATCH 8/9] rm useless methods and refactor getter/setter --- docs/cn/server.md | 2 -- docs/en/server.md | 2 -- src/brpc/baidu_master_service.cpp | 2 +- src/brpc/baidu_master_service.h | 10 ++++-- src/brpc/server.cpp | 54 ++++++------------------------- src/brpc/server.h | 12 ------- 6 files changed, 17 insertions(+), 65 deletions(-) diff --git a/docs/cn/server.md b/docs/cn/server.md index 9343a24832..0e68c51d40 100644 --- a/docs/cn/server.md +++ b/docs/cn/server.md @@ -1067,8 +1067,6 @@ server.IgnoreEovercrowdedOf("...") = ...可设置method级别的ignore_eovercrow ```c++ ServerOptions.ignore_eovercrowded = true; // Set the default ignore_eovercrowded for all methods server.IgnoreEovercrowdedOf("example.EchoService.Echo") = true; -server.IgnoreEovercrowdedOf("example.EchoService", "Echo") = true; -server.IgnoreEovercrowdedOf(&service, "Echo") = true; ``` 此设置一般**发生在AddService后,server启动前**。当设置失败时(比如对应的method不存在),server会启动失败同时提示用户修正IgnoreEovercrowdedOf设置错误。 diff --git a/docs/en/server.md b/docs/en/server.md index 3e26b58266..e49f8512ae 100644 --- a/docs/en/server.md +++ b/docs/en/server.md @@ -1063,8 +1063,6 @@ server.IgnoreEovercrowdedOf("...") = … sets ignore_eovercrowded of the method. ```c++ ServerOptions.ignore_eovercrowded = true; // Set the default ignore_eovercrowded for all methods server.IgnoreEovercrowdedOf("example.EchoService.Echo") = true; -server.IgnoreEovercrowdedOf("example.EchoService", "Echo") = true; -server.IgnoreEovercrowdedOf(&service, "Echo") = true; ``` The code is generally put **after AddService, before Start() of the server**. When a setting fails(namely the method does not exist), server will fail to start and notify user to fix settings on IgnoreEovercrowdedOf. diff --git a/src/brpc/baidu_master_service.cpp b/src/brpc/baidu_master_service.cpp index 11083c2482..b1b0fa0dbf 100644 --- a/src/brpc/baidu_master_service.cpp +++ b/src/brpc/baidu_master_service.cpp @@ -22,7 +22,7 @@ namespace brpc { BaiduMasterService::BaiduMasterService() - : _status(new (std::nothrow) MethodStatus), ignore_eovercrowded(false) { + : _status(new (std::nothrow) MethodStatus), _ignore_eovercrowded(false) { LOG_IF(FATAL, NULL == _status) << "Fail to new MethodStatus"; } diff --git a/src/brpc/baidu_master_service.h b/src/brpc/baidu_master_service.h index 1747f06153..11846fd9b4 100644 --- a/src/brpc/baidu_master_service.h +++ b/src/brpc/baidu_master_service.h @@ -45,8 +45,12 @@ class BaiduMasterService : public ::google::protobuf::Service return _max_concurrency; } - bool& IgnoreEOverCrowded() { - return ignore_eovercrowded; + bool ignore_eovercrowded() { + return _ignore_eovercrowded; + } + + void set_ignore_eovercrowded(bool ignore_eovercrowded) { + _ignore_eovercrowded = ignore_eovercrowded; } virtual void ProcessRpcRequest(Controller* cntl, @@ -96,7 +100,7 @@ friend class Server; MethodStatus* _status; AdaptiveMaxConcurrency _max_concurrency; - bool ignore_eovercrowded; + bool _ignore_eovercrowded; }; } diff --git a/src/brpc/server.cpp b/src/brpc/server.cpp index f557d1870c..e904e6c8af 100644 --- a/src/brpc/server.cpp +++ b/src/brpc/server.cpp @@ -2311,7 +2311,13 @@ int Server::MaxConcurrencyOf(google::protobuf::Service* service, return MaxConcurrencyOf(service->GetDescriptor()->full_name(), method_name); } -bool& Server::IgnoreEovercrowdedOf(MethodProperty* mp) { +bool& Server::IgnoreEovercrowdedOf(const butil::StringPiece& full_method_name) { + MethodProperty* mp = _method_map.seek(full_method_name); + if (mp == NULL) { + LOG(ERROR) << "Fail to find method=" << full_method_name; + _failed_to_set_ignore_eovercrowded = true; + return g_default_ignore_eovercrowded; + } if (IsRunning()) { LOG(WARNING) << "IgnoreEovercrowdedOf is only allowd before Server started"; return g_default_ignore_eovercrowded; @@ -2325,7 +2331,8 @@ bool& Server::IgnoreEovercrowdedOf(MethodProperty* mp) { return mp->ignore_eovercrowded; } -bool Server::IgnoreEovercrowdedOf(const MethodProperty* mp) const { +bool Server::IgnoreEovercrowdedOf(const butil::StringPiece& full_method_name) const { + MethodProperty* mp = _method_map.seek(full_method_name); if (IsRunning()) { LOG(WARNING) << "IgnoreEovercrowdedOf is only allowd before Server started"; return g_default_ignore_eovercrowded; @@ -2336,49 +2343,6 @@ bool Server::IgnoreEovercrowdedOf(const MethodProperty* mp) const { return mp->ignore_eovercrowded; } -bool& Server::IgnoreEovercrowdedOf(const butil::StringPiece& full_method_name) { - MethodProperty* mp = _method_map.seek(full_method_name); - if (mp == NULL) { - LOG(ERROR) << "Fail to find method=" << full_method_name; - _failed_to_set_ignore_eovercrowded = true; - return g_default_ignore_eovercrowded; - } - return IgnoreEovercrowdedOf(mp); -} - -bool Server::IgnoreEovercrowdedOf(const butil::StringPiece& full_method_name) const { - return IgnoreEovercrowdedOf(_method_map.seek(full_method_name)); -} - -bool& Server::IgnoreEovercrowdedOf(const butil::StringPiece& full_service_name, - const butil::StringPiece& method_name) { - MethodProperty* mp = const_cast( - FindMethodPropertyByFullName(full_service_name, method_name)); - if (mp == NULL) { - LOG(ERROR) << "Fail to find method=" << full_service_name - << '/' << method_name; - _failed_to_set_ignore_eovercrowded = true; - return g_default_ignore_eovercrowded; - } - return IgnoreEovercrowdedOf(mp); -} - -bool Server::IgnoreEovercrowdedOf(const butil::StringPiece& full_service_name, - const butil::StringPiece& method_name) const { - return IgnoreEovercrowdedOf(FindMethodPropertyByFullName( - full_service_name, method_name)); -} - -bool& Server::IgnoreEovercrowdedOf(google::protobuf::Service* service, - const butil::StringPiece& method_name) { - return IgnoreEovercrowdedOf(service->GetDescriptor()->full_name(), method_name); -} - -bool Server::IgnoreEovercrowdedOf(google::protobuf::Service* service, - const butil::StringPiece& method_name) const { - return IgnoreEovercrowdedOf(service->GetDescriptor()->full_name(), method_name); -} - bool Server::AcceptRequest(Controller* cntl) const { const Interceptor* interceptor = _options.interceptor; if (!interceptor) { diff --git a/src/brpc/server.h b/src/brpc/server.h index d609b4d85a..8d1b093cc7 100644 --- a/src/brpc/server.h +++ b/src/brpc/server.h @@ -604,16 +604,6 @@ class Server { bool& IgnoreEovercrowdedOf(const butil::StringPiece& full_method_name); bool IgnoreEovercrowdedOf(const butil::StringPiece& full_method_name) const; - bool& IgnoreEovercrowdedOf(const butil::StringPiece& full_service_name, - const butil::StringPiece& method_name); - bool IgnoreEovercrowdedOf(const butil::StringPiece& full_service_name, - const butil::StringPiece& method_name) const; - - bool& IgnoreEovercrowdedOf(google::protobuf::Service* service, - const butil::StringPiece& method_name); - bool IgnoreEovercrowdedOf(google::protobuf::Service* service, - const butil::StringPiece& method_name) const; - int Concurrency() const { return butil::subtle::NoBarrier_Load(&_concurrency); }; @@ -718,8 +708,6 @@ friend class Controller; AdaptiveMaxConcurrency& MaxConcurrencyOf(MethodProperty*); int MaxConcurrencyOf(const MethodProperty*) const; - bool& IgnoreEovercrowdedOf(MethodProperty*); - bool IgnoreEovercrowdedOf(const MethodProperty*) const; static bool CreateConcurrencyLimiter(const AdaptiveMaxConcurrency& amc, ConcurrencyLimiter** out); From d39a3541f89dbdeda25db071e5fdcf124296e2bf Mon Sep 17 00:00:00 2001 From: lianxuechao Date: Mon, 2 Dec 2024 18:39:52 +0800 Subject: [PATCH 9/9] fix build --- src/brpc/policy/baidu_rpc_protocol.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/brpc/policy/baidu_rpc_protocol.cpp b/src/brpc/policy/baidu_rpc_protocol.cpp index 9a4601e7f6..f8ea1f6361 100644 --- a/src/brpc/policy/baidu_rpc_protocol.cpp +++ b/src/brpc/policy/baidu_rpc_protocol.cpp @@ -520,7 +520,7 @@ void ProcessRpcRequest(InputMessageBase* msg_base) { if (NULL != server->options().baidu_master_service) { if (socket->is_overcrowded() && !server->options().ignore_eovercrowded && - !server->options().baidu_master_service->IgnoreEOverCrowded()) { + !server->options().baidu_master_service->ignore_eovercrowded()) { cntl->SetFailed(EOVERCROWDED, "Connection to %s is overcrowded", butil::endpoint2str(socket->remote_side()).c_str()); break;