1 | // Licensed to the Apache Software Foundation (ASF) under one |
2 | // or more contributor license agreements. See the NOTICE file |
3 | // distributed with this work for additional information |
4 | // regarding copyright ownership. The ASF licenses this file |
5 | // to you under the Apache License, Version 2.0 (the |
6 | // "License"); you may not use this file except in compliance |
7 | // with the License. You may obtain a copy of the License at |
8 | // |
9 | // http://www.apache.org/licenses/LICENSE-2.0 |
10 | // |
11 | // Unless required by applicable law or agreed to in writing, |
12 | // software distributed under the License is distributed on an |
13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
14 | // KIND, either express or implied. See the License for the |
15 | // specific language governing permissions and limitations |
16 | // under the License. |
17 | |
18 | |
19 | #ifndef BRPC_CHANNEL_H |
20 | #define BRPC_CHANNEL_H |
21 | |
22 | // To brpc developers: This is a header included by user, don't depend |
23 | // on internal structures, use opaque pointers instead. |
24 | |
25 | #include <ostream> // std::ostream |
26 | #include "bthread/errno.h" // Redefine errno |
27 | #include "butil/intrusive_ptr.hpp" // butil::intrusive_ptr |
28 | #include "butil/ptr_container.h" |
29 | #include "brpc/ssl_options.h" // ChannelSSLOptions |
30 | #include "brpc/channel_base.h" // ChannelBase |
31 | #include "brpc/adaptive_protocol_type.h" // AdaptiveProtocolType |
32 | #include "brpc/adaptive_connection_type.h" // AdaptiveConnectionType |
33 | #include "brpc/socket_id.h" // SocketId |
34 | #include "brpc/controller.h" // brpc::Controller |
35 | #include "brpc/details/profiler_linker.h" |
36 | #include "brpc/retry_policy.h" |
37 | #include "brpc/naming_service_filter.h" |
38 | |
39 | namespace brpc { |
40 | |
41 | struct ChannelOptions { |
42 | // Constructed with default options. |
43 | ChannelOptions(); |
44 | |
45 | // Issue error when a connection is not established after so many |
46 | // milliseconds. -1 means wait indefinitely. |
47 | // Default: 200 (milliseconds) |
48 | // Maximum: 0x7fffffff (roughly 30 days) |
49 | int32_t connect_timeout_ms; |
50 | |
51 | // Max duration of RPC over this Channel. -1 means wait indefinitely. |
52 | // Overridable by Controller.set_timeout_ms(). |
53 | // Default: 500 (milliseconds) |
54 | // Maximum: 0x7fffffff (roughly 30 days) |
55 | int32_t timeout_ms; |
56 | |
57 | // Send another request if RPC does not finish after so many milliseconds. |
58 | // Overridable by Controller.set_backup_request_ms(). |
59 | // The request will be sent to a different server by best effort. |
60 | // If timeout_ms is set and backup_request_ms >= timeout_ms, backup request |
61 | // will never be sent. |
62 | // backup request does NOT imply server-side cancelation. |
63 | // Default: -1 (disabled) |
64 | // Maximum: 0x7fffffff (roughly 30 days) |
65 | int32_t backup_request_ms; |
66 | |
67 | // Retry limit for RPC over this Channel. <=0 means no retry. |
68 | // Overridable by Controller.set_max_retry(). |
69 | // Default: 3 |
70 | // Maximum: INT_MAX |
71 | int max_retry; |
72 | |
73 | // When the error rate of a server node is too high, isolate the node. |
74 | // Note that this isolation is GLOBAL, the node will become unavailable |
75 | // for all channels running in this process during the isolation. |
76 | // Default: false |
77 | bool enable_circuit_breaker; |
78 | |
79 | // Serialization protocol, defined in src/brpc/options.proto |
80 | // NOTE: You can assign name of the protocol to this field as well, for |
81 | // Example: options.protocol = "baidu_std"; |
82 | AdaptiveProtocolType protocol; |
83 | |
84 | // Type of connection to server. If unset, use the default connection type |
85 | // of the protocol. |
86 | // NOTE: You can assign name of the type to this field as well, for |
87 | // Example: options.connection_type = "single"; |
88 | // Possible values: "single", "pooled", "short". |
89 | AdaptiveConnectionType connection_type; |
90 | |
91 | // Channel.Init() succeeds even if there's no server in the NamingService. |
92 | // E.g. the BNS directory is empty. All RPC over the channel will fail before |
93 | // new nodes being added to the NamingService. |
94 | // Default: true (false before r32470) |
95 | bool succeed_without_server; |
96 | // Print a log when above situation happens. |
97 | // Default: true. |
98 | bool log_succeed_without_server; |
99 | |
100 | // SSL related options. Refer to `ChannelSSLOptions' for details |
101 | bool has_ssl_options() const { return _ssl_options != NULL; } |
102 | const ChannelSSLOptions& ssl_options() const { return *_ssl_options.get(); } |
103 | ChannelSSLOptions* mutable_ssl_options(); |
104 | |
105 | // Turn on authentication for this channel if `auth' is not NULL. |
106 | // Note `auth' will not be deleted by channel and must remain valid when |
107 | // the channel is being used. |
108 | // Default: NULL |
109 | const Authenticator* auth; |
110 | |
111 | // Customize the error code that should be retried. The interface is |
112 | // defined in src/brpc/retry_policy.h |
113 | // This object is NOT owned by channel and should remain valid when |
114 | // channel is used. |
115 | // Default: NULL |
116 | const RetryPolicy* retry_policy; |
117 | |
118 | // Filter ServerNodes (i.e. based on `tag' field of `ServerNode') |
119 | // which are generated by NamingService. The interface is defined |
120 | // in src/brpc/naming_service_filter.h |
121 | // This object is NOT owned by channel and should remain valid when |
122 | // channel is used. |
123 | // Default: NULL |
124 | const NamingServiceFilter* ns_filter; |
125 | |
126 | // Channels with same connection_group share connections. |
127 | // In other words, set to a different value to stop sharing connections. |
128 | // Case-sensitive, leading and trailing spaces are ignored. |
129 | // Default: "" |
130 | std::string connection_group; |
131 | |
132 | private: |
133 | // SSLOptions is large and not often used, allocate it on heap to |
134 | // prevent ChannelOptions from being bloated in most cases. |
135 | butil::PtrContainer<ChannelSSLOptions> _ssl_options; |
136 | }; |
137 | |
138 | // A Channel represents a communication line to one server or multiple servers |
139 | // which can be used to call that Server's services. Servers may be running |
140 | // on another machines. Normally, you should not call a Channel directly, but |
141 | // instead construct a stub Service wrapping it. |
142 | // Example: |
143 | // brpc::Channel channel; |
144 | // channel.Init("bns://rdev.matrix.all", "rr", NULL/*default options*/); |
145 | // MyService_Stub stub(&channel); |
146 | // stub.MyMethod(&controller, &request, &response, NULL); |
147 | class Channel : public ChannelBase { |
148 | friend class Controller; |
149 | friend class SelectiveChannel; |
150 | public: |
151 | Channel(ProfilerLinker = ProfilerLinker()); |
152 | ~Channel(); |
153 | |
154 | // Connect this channel to a single server whose address is given by the |
155 | // first parameter. Use default options if `options' is NULL. |
156 | int Init(butil::EndPoint server_addr_and_port, const ChannelOptions* options); |
157 | int Init(const char* server_addr_and_port, const ChannelOptions* options); |
158 | int Init(const char* server_addr, int port, const ChannelOptions* options); |
159 | |
160 | // Connect this channel to a group of servers whose addresses can be |
161 | // accessed via `naming_service_url' according to its protocol. Use the |
162 | // method specified by `load_balancer_name' to distribute traffic to |
163 | // servers. Use default options if `options' is NULL. |
164 | // Supported naming service("protocol://service_name"): |
165 | // bns://<node-name> # Baidu Naming Service |
166 | // file://<file-path> # load addresses from the file |
167 | // list://addr1,addr2,... # use the addresses separated by comma |
168 | // http://<url> # Domain Naming Service, aka DNS. |
169 | // Supported load balancer: |
170 | // rr # round robin, choose next server |
171 | // random # randomly choose a server |
172 | // la # locality aware |
173 | // c_murmurhash/c_md5 # consistent hashing with murmurhash3/md5 |
174 | // "" or NULL # treat `naming_service_url' as `server_addr_and_port' |
175 | // # Init(xxx, "", options) and Init(xxx, NULL, options) |
176 | // # are exactly same with Init(xxx, options) |
177 | int Init(const char* naming_service_url, |
178 | const char* load_balancer_name, |
179 | const ChannelOptions* options); |
180 | |
181 | // Call `method' of the remote service with `request' as input, and |
182 | // `response' as output. `controller' contains options and extra data. |
183 | // If `done' is not NULL, this method returns after request was sent |
184 | // and `done->Run()' will be called when the call finishes, otherwise |
185 | // caller blocks until the call finishes. |
186 | void CallMethod(const google::protobuf::MethodDescriptor* method, |
187 | google::protobuf::RpcController* controller, |
188 | const google::protobuf::Message* request, |
189 | google::protobuf::Message* response, |
190 | google::protobuf::Closure* done); |
191 | |
192 | // Get current options. |
193 | const ChannelOptions& options() const { return _options; } |
194 | |
195 | void Describe(std::ostream&, const DescribeOptions&) const; |
196 | |
197 | // Sum of weights of servers that this channel connects to. |
198 | int Weight(); |
199 | |
200 | protected: |
201 | int CheckHealth(); |
202 | |
203 | bool SingleServer() const { return _lb.get() == NULL; } |
204 | |
205 | // Pick a server using `lb' and then send RPC. Wait for response when |
206 | // sending synchronous RPC. |
207 | // NOTE: DO NOT directly use `controller' after this call when |
208 | // sending asynchronous RPC (controller->_done != NULL) since |
209 | // user callback `done' could be called when it returns and |
210 | // therefore destroy the `controller' inside `done' |
211 | static void CallMethodImpl(Controller* controller, SharedLoadBalancer* lb); |
212 | |
213 | int InitChannelOptions(const ChannelOptions* options); |
214 | int InitSingle(const butil::EndPoint& server_addr_and_port, |
215 | const char* raw_server_address, |
216 | const ChannelOptions* options); |
217 | |
218 | butil::EndPoint _server_address; |
219 | SocketId _server_id; |
220 | Protocol::SerializeRequest _serialize_request; |
221 | Protocol::PackRequest _pack_request; |
222 | Protocol::GetMethodName _get_method_name; |
223 | // This will be shared between channel and controllers that |
224 | // are in the middle of RPC procedure using this channel. |
225 | // It will be destroyed after channel's destruction and all |
226 | // the RPC above has finished |
227 | butil::intrusive_ptr<SharedLoadBalancer> _lb; |
228 | ChannelOptions _options; |
229 | int _preferred_index; |
230 | }; |
231 | |
232 | enum ChannelOwnership { |
233 | OWNS_CHANNEL, |
234 | DOESNT_OWN_CHANNEL |
235 | }; |
236 | |
237 | } // namespace brpc |
238 | |
239 | #endif // BRPC_CHANNEL_H |
240 | |