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_SERVER_H |
20 | #define BRPC_SERVER_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 "bthread/errno.h" // Redefine errno |
26 | #include "bthread/bthread.h" // Server may need some bthread functions, |
27 | // e.g. bthread_usleep |
28 | #include <google/protobuf/service.h> // google::protobuf::Service |
29 | #include "butil/macros.h" // DISALLOW_COPY_AND_ASSIGN |
30 | #include "butil/containers/doubly_buffered_data.h" // DoublyBufferedData |
31 | #include "bvar/bvar.h" |
32 | #include "butil/containers/case_ignored_flat_map.h" // [CaseIgnored]FlatMap |
33 | #include "butil/ptr_container.h" |
34 | #include "brpc/controller.h" // brpc::Controller |
35 | #include "brpc/ssl_options.h" // ServerSSLOptions |
36 | #include "brpc/describable.h" // User often needs this |
37 | #include "brpc/data_factory.h" // DataFactory |
38 | #include "brpc/builtin/tabbed.h" |
39 | #include "brpc/details/profiler_linker.h" |
40 | #include "brpc/health_reporter.h" |
41 | #include "brpc/adaptive_max_concurrency.h" |
42 | #include "brpc/http2.h" |
43 | #include "brpc/redis.h" |
44 | |
45 | namespace brpc { |
46 | |
47 | class Acceptor; |
48 | class MethodStatus; |
49 | class NsheadService; |
50 | class ThriftService; |
51 | class SimpleDataPool; |
52 | class MongoServiceAdaptor; |
53 | class RestfulMap; |
54 | class RtmpService; |
55 | class RedisService; |
56 | struct SocketSSLContext; |
57 | |
58 | struct ServerOptions { |
59 | ServerOptions(); // Constructed with default options. |
60 | |
61 | // connections without data transmission for so many seconds will be closed |
62 | // Default: -1 (disabled) |
63 | int idle_timeout_sec; |
64 | |
65 | // If this option is not empty, a file named so containing Process Id |
66 | // of the server will be created when the server is started. |
67 | // Default: "" |
68 | std::string pid_file; |
69 | |
70 | // Process requests in format of nshead_t + blob. |
71 | // Owned by Server and deleted in server's destructor. |
72 | // Default: NULL |
73 | NsheadService* nshead_service; |
74 | |
75 | // Process requests in format of thrift_binary_head_t + blob. |
76 | // Owned by Server and deleted in server's destructor. |
77 | // Default: NULL |
78 | ThriftService* thrift_service; |
79 | |
80 | // Adaptor for Mongo protocol, check src/brpc/mongo_service_adaptor.h for details |
81 | // The adaptor will not be deleted by server |
82 | // and must remain valid when server is running. |
83 | const MongoServiceAdaptor* mongo_service_adaptor; |
84 | |
85 | // Turn on authentication for all services if `auth' is not NULL. |
86 | // Default: NULL |
87 | const Authenticator* auth; |
88 | |
89 | // false: `auth' is not owned by server and must be valid when server is running. |
90 | // true: `auth' is owned by server and will be deleted when server is destructed. |
91 | // Default: false |
92 | bool server_owns_auth; |
93 | |
94 | // Number of pthreads that server runs on. Notice that this is just a hint, |
95 | // you can't assume that the server uses exactly so many pthreads because |
96 | // pthread workers are shared by all servers and channels inside a |
97 | // process. And there're no "io-thread" and "worker-thread" anymore, |
98 | // brpc automatically schedules "io" and "worker" code for better |
99 | // parallelism and less context switches. |
100 | // If this option <= 0, number of pthread workers is not changed. |
101 | // Default: #cpu-cores |
102 | int num_threads; |
103 | |
104 | // Server-level max concurrency. |
105 | // "concurrency" = "number of requests processed in parallel" |
106 | // |
107 | // In a traditional server, number of pthread workers also limits |
108 | // concurrency. However brpc runs requests in bthreads which are |
109 | // mapped to pthread workers, when a bthread context switches, it gives |
110 | // the pthread worker to another bthread, yielding a higher concurrency |
111 | // than number of pthreads. In some situations, higher concurrency may |
112 | // consume more resources, to protect the server from running out of |
113 | // resources, you may set this option. |
114 | // If the server reaches the limitation, it responds client with ELIMIT |
115 | // directly without calling service's callback. The client seeing ELIMIT |
116 | // shall try another server. |
117 | // NOTE: accesses to builtin services are not limited by this option. |
118 | // Default: 0 (unlimited) |
119 | int max_concurrency; |
120 | |
121 | // Default value of method-level max concurrencies, |
122 | // Overridable by Server.MaxConcurrencyOf(). |
123 | AdaptiveMaxConcurrency method_max_concurrency; |
124 | |
125 | // ------------------------------------------------------- |
126 | // Differences between session-local and thread-local data |
127 | // ------------------------------------------------------- |
128 | // * session-local data has to be got from a server-side Controller. |
129 | // thread-local data can be got in any function running inside a server |
130 | // thread without an object. |
131 | // * session-local data is attached to current RPC and invalid after |
132 | // calling `done'. thread-local data is attached to current server |
133 | // thread and invalid after leaving Service::CallMethod(). If you need |
134 | // to hand down data to an asynchronous `done' which is called outside |
135 | // Service::CallMethod(), you must use session-local data. |
136 | // ----------------- |
137 | // General guideline |
138 | // ----------------- |
139 | // * Choose a proper value for reserved_xxx_local_data, small value may |
140 | // not create enough data for all searching threads, while big value |
141 | // wastes memory. |
142 | // * Comparing to reserving data, making them as small as possible and |
143 | // creating them on demand is better. Passing a lot of stuff via |
144 | // session-local data or thread-local data is definitely not a good design. |
145 | |
146 | // The factory to create/destroy data attached to each RPC session. |
147 | // If this option is NULL, Controller::session_local_data() is always NULL. |
148 | // NOT owned by Server and must be valid when Server is running. |
149 | // Default: NULL |
150 | const DataFactory* session_local_data_factory; |
151 | |
152 | // Prepare so many session-local data before server starts, so that calls |
153 | // to Controller::session_local_data() get data directly rather than |
154 | // calling session_local_data_factory->Create() at first time. Useful when |
155 | // Create() is slow, otherwise the RPC session may be blocked by the |
156 | // creation of data and not served within timeout. |
157 | // Default: 0 |
158 | size_t reserved_session_local_data; |
159 | |
160 | // The factory to create/destroy data attached to each searching thread |
161 | // in server. |
162 | // If this option is NULL, brpc::thread_local_data() is always NULL. |
163 | // NOT owned by Server and must be valid when Server is running. |
164 | // Default: NULL |
165 | const DataFactory* thread_local_data_factory; |
166 | |
167 | // Prepare so many thread-local data before server starts, so that calls |
168 | // to brpc::thread_local_data() get data directly rather than calling |
169 | // thread_local_data_factory->Create() at first time. Useful when Create() |
170 | // is slow, otherwise the RPC session may be blocked by the creation |
171 | // of data and not served within timeout. |
172 | // Default: 0 |
173 | size_t reserved_thread_local_data; |
174 | |
175 | // Call bthread_init_fn(bthread_init_args) in at least #bthread_init_count |
176 | // bthreads before server runs, mainly for initializing bthread locals. |
177 | // You have to set both `bthread_init_fn' and `bthread_init_count' to |
178 | // enable the feature. |
179 | bool (*bthread_init_fn)(void* args); // default: NULL (do nothing) |
180 | void* bthread_init_args; // default: NULL |
181 | size_t bthread_init_count; // default: 0 |
182 | |
183 | // Provide builtin services at this port rather than the port to Start(). |
184 | // When your server needs to be accessed from public (including traffic |
185 | // redirected by nginx or other http front-end servers), set this port |
186 | // to a port number that's ONLY accessible from internal network |
187 | // so that you can check out the builtin services from this port while |
188 | // hiding them from public. Setting this option also enables security |
189 | // protection code which we may add constantly. |
190 | // Update: this option affects Tabbed services as well. |
191 | // Default: -1 |
192 | int internal_port; |
193 | |
194 | // Contain a set of builtin services to ease monitoring/debugging. |
195 | // Read docs/cn/builtin_service.md for details. |
196 | // DO NOT set this option to false if you don't even know what builtin |
197 | // services are. They're very helpful for addressing runtime problems. |
198 | // Setting to false makes -internal_port ineffective. |
199 | // Default: true |
200 | bool has_builtin_services; |
201 | |
202 | // Enable more secured code which protects internal information from exposure. |
203 | bool security_mode() const { return internal_port >= 0 || !has_builtin_services; } |
204 | |
205 | // SSL related options. Refer to `ServerSSLOptions' for details |
206 | bool has_ssl_options() const { return _ssl_options != NULL; } |
207 | const ServerSSLOptions& ssl_options() const { return *_ssl_options.get(); } |
208 | ServerSSLOptions* mutable_ssl_options(); |
209 | |
210 | // [CAUTION] This option is for implementing specialized http proxies, |
211 | // most users don't need it. Don't change this option unless you fully |
212 | // understand the description below. |
213 | // If this option is set, all HTTP requests to the server will be delegated |
214 | // to this service which fully decides what to call and what to send back, |
215 | // including accesses to builtin services and pb services. |
216 | // The service must have a method named "default_method" and the request |
217 | // and response must have no fields. |
218 | // |
219 | // Owned by Server and deleted in server's destructor |
220 | google::protobuf::Service* http_master_service; |
221 | |
222 | // If this field is on, contents on /health page is generated by calling |
223 | // health_reporter->GenerateReport(). This object is NOT owned by server |
224 | // and must remain valid when server is running. |
225 | HealthReporter* health_reporter; |
226 | |
227 | // For processing RTMP connections. Read src/brpc/rtmp.h for details. |
228 | // Default: NULL (rtmp support disabled) |
229 | RtmpService* rtmp_service; |
230 | |
231 | // Only enable these protocols, separated by spaces. |
232 | // All names inside must be valid, check protocols name in global.cpp |
233 | // Default: empty (all protocols) |
234 | std::string enabled_protocols; |
235 | |
236 | // Customize parameters of HTTP2, defined in http2.h |
237 | H2Settings h2_settings; |
238 | |
239 | // For processing Redis connections. Read src/brpc/redis.h for details. |
240 | // Owned by Server and deleted in server's destructor. |
241 | // Default: NULL (disabled) |
242 | RedisService* redis_service; |
243 | |
244 | private: |
245 | // SSLOptions is large and not often used, allocate it on heap to |
246 | // prevent ServerOptions from being bloated in most cases. |
247 | butil::PtrContainer<ServerSSLOptions> _ssl_options; |
248 | }; |
249 | |
250 | // This struct is originally designed to contain basic statistics of the |
251 | // server. But bvar contains more stats and is more convenient. |
252 | struct ServerStatistics { |
253 | size_t connection_count; |
254 | int user_service_count; |
255 | int builtin_service_count; |
256 | }; |
257 | |
258 | // Represent server's ownership of services. |
259 | enum ServiceOwnership { |
260 | SERVER_OWNS_SERVICE, |
261 | SERVER_DOESNT_OWN_SERVICE |
262 | }; |
263 | |
264 | struct ServiceOptions { |
265 | ServiceOptions(); // constructed with default options. |
266 | |
267 | // SERVER_OWNS_SERVICE: the service will be deleted by the server. |
268 | // SERVER_DOESNT_OWN_SERVICE: the service shall be deleted by user after |
269 | // stopping the server. |
270 | // Default: SERVER_DOESNT_OWN_SERVICE |
271 | ServiceOwnership ownership; |
272 | |
273 | // If this option is non-empty, methods in the service will be exposed |
274 | // on specified paths instead of default "/SERVICE/METHOD". |
275 | // Mappings are in form of: "PATH1 => NAME1, PATH2 => NAME2 ..." where |
276 | // PATHs are valid http paths, NAMEs are method names in the service. |
277 | // Default: empty |
278 | std::string restful_mappings; |
279 | |
280 | // [ Not recommended to change this option ] |
281 | // If this flag is true, the service will convert http body to protobuf |
282 | // when the pb schema is non-empty in http servings. The body must be |
283 | // valid json or protobuf(wire-format) otherwise the request is rejected. |
284 | // This option does not affect pure-http services (pb schema is empty). |
285 | // Services that use older versions of brpc may need to turn this |
286 | // conversion off and handle http requests by their own to keep compatible |
287 | // with existing clients. |
288 | // Default: true |
289 | bool allow_http_body_to_pb; |
290 | |
291 | // decode json string to protobuf bytes using base64 decoding when this |
292 | // option is turned on. |
293 | // Default: false if BAIDU_INTERNAL is defined, otherwise true |
294 | bool pb_bytes_to_base64; |
295 | }; |
296 | |
297 | // Represent ports inside [min_port, max_port] |
298 | struct PortRange { |
299 | int min_port; |
300 | int max_port; |
301 | |
302 | PortRange(int min_port2, int max_port2) |
303 | : min_port(min_port2), max_port(max_port2) { |
304 | } |
305 | }; |
306 | |
307 | // Server dispatches requests from clients to registered services and |
308 | // and sends responses back to clients. |
309 | class Server { |
310 | public: |
311 | enum Status { |
312 | UNINITIALIZED = 0, |
313 | READY = 1, |
314 | RUNNING = 2, |
315 | STOPPING = 3, |
316 | }; |
317 | struct ServiceProperty { |
318 | bool is_builtin_service; |
319 | ServiceOwnership ownership; |
320 | // `service' and `restful_map' are mutual exclusive, they can't be |
321 | // both non-NULL. If `restful_map' is not NULL, the URL should be |
322 | // further matched by it. |
323 | google::protobuf::Service* service; |
324 | RestfulMap* restful_map; |
325 | |
326 | bool is_user_service() const { |
327 | return !is_builtin_service && !restful_map; |
328 | } |
329 | |
330 | const std::string& service_name() const; |
331 | }; |
332 | typedef butil::FlatMap<std::string, ServiceProperty> ServiceMap; |
333 | |
334 | struct MethodProperty { |
335 | bool is_builtin_service; |
336 | bool own_method_status; |
337 | // Parameters which have nothing to do with management of services, but |
338 | // will be used when the service is queried. |
339 | struct OpaqueParams { |
340 | bool is_tabbed; |
341 | bool allow_http_body_to_pb; |
342 | bool pb_bytes_to_base64; |
343 | OpaqueParams(); |
344 | }; |
345 | OpaqueParams params; |
346 | // NULL if service of the method was never added as restful. |
347 | // "@path1 @path2 ..." if the method was mapped from paths. |
348 | std::string* http_url; |
349 | google::protobuf::Service* service; |
350 | const google::protobuf::MethodDescriptor* method; |
351 | MethodStatus* status; |
352 | AdaptiveMaxConcurrency max_concurrency; |
353 | |
354 | MethodProperty(); |
355 | }; |
356 | typedef butil::FlatMap<std::string, MethodProperty> MethodMap; |
357 | |
358 | struct ThreadLocalOptions { |
359 | bthread_key_t tls_key; |
360 | const DataFactory* thread_local_data_factory; |
361 | |
362 | ThreadLocalOptions() |
363 | : tls_key(INVALID_BTHREAD_KEY) |
364 | , thread_local_data_factory(NULL) {} |
365 | }; |
366 | |
367 | public: |
368 | Server(ProfilerLinker = ProfilerLinker()); |
369 | ~Server(); |
370 | |
371 | // A set of functions to start this server. |
372 | // Returns 0 on success, -1 otherwise and errno is set appropriately. |
373 | // Notes: |
374 | // * Default options are taken if `opt' is NULL. |
375 | // * A server can be started more than once if the server is completely |
376 | // stopped by Stop() and Join(). |
377 | // * port can be 0, which makes kernel to choose a port dynamically. |
378 | |
379 | // Start on an address in form of "0.0.0.0:8000". |
380 | int Start(const char* ip_port_str, const ServerOptions* opt); |
381 | int Start(const butil::EndPoint& ip_port, const ServerOptions* opt); |
382 | // Start on IP_ANY:port. |
383 | int Start(int port, const ServerOptions* opt); |
384 | // Start on `ip_str' + any useable port in `range' |
385 | int Start(const char* ip_str, PortRange range, const ServerOptions *opt); |
386 | |
387 | // NOTE: Stop() is paired with Join() to stop a server without losing |
388 | // requests. The point of separating them is that you can Stop() multiple |
389 | // servers before Join() them, in which case the total time to Join is |
390 | // time of the slowest Join(). Otherwise you have to Join() them one by |
391 | // one, in which case the total time is sum of all Join(). |
392 | |
393 | // Stop accepting new connections and requests from existing connections. |
394 | // Returns 0 on success, -1 otherwise. |
395 | int Stop(int closewait_ms/*not used anymore*/); |
396 | |
397 | // Wait until requests in progress are done. If Stop() is not called, |
398 | // this function NEVER return. If Stop() is called, during the waiting, |
399 | // this server responds new requests with `ELOGOFF' error immediately |
400 | // without calling any service. When clients see the error, they should |
401 | // try other servers. |
402 | int Join(); |
403 | |
404 | // Sleep until Ctrl-C is pressed, then stop and join this server. |
405 | // CAUTION: Don't call signal(SIGINT, ...) in your program! |
406 | // If signal(SIGINT, ..) is called AFTER calling this function, this |
407 | // function may block indefinitely. |
408 | void RunUntilAskedToQuit(); |
409 | |
410 | // Add a service. Arguments are explained in ServiceOptions above. |
411 | // NOTE: Adding a service while server is running is forbidden. |
412 | // Returns 0 on success, -1 otherwise. |
413 | int AddService(google::protobuf::Service* service, |
414 | ServiceOwnership ownership); |
415 | int AddService(google::protobuf::Service* service, |
416 | ServiceOwnership ownership, |
417 | const butil::StringPiece& restful_mappings); |
418 | int AddService(google::protobuf::Service* service, |
419 | const ServiceOptions& options); |
420 | |
421 | // Remove a service from this server. |
422 | // NOTE: removing a service while server is running is forbidden. |
423 | // Returns 0 on success, -1 otherwise. |
424 | int RemoveService(google::protobuf::Service* service); |
425 | |
426 | // Remove all services from this server. |
427 | // NOTE: clearing services when server is running is forbidden. |
428 | void ClearServices(); |
429 | |
430 | // Dynamically add a new certificate into server. It can be called |
431 | // while the server is running, but it's not thread-safe by itself. |
432 | // Returns 0 on success, -1 otherwise. |
433 | int AddCertificate(const CertInfo& cert); |
434 | |
435 | // Dynamically remove a former certificate from server. Can be called |
436 | // while the server is running, but it's not thread-safe by itself. |
437 | // Returns 0 on success, -1 otherwise. |
438 | int RemoveCertificate(const CertInfo& cert); |
439 | |
440 | // Dynamically reset all certificates except the default one. It can be |
441 | // called while the server is running, but it's not thread-safe by itself. |
442 | // Returns 0 on success, -1 otherwise. |
443 | int ResetCertificates(const std::vector<CertInfo>& certs); |
444 | |
445 | // Find a service by its ServiceDescriptor::full_name(). |
446 | // Returns the registered service pointer, NULL on not found. |
447 | // Notice that for performance concerns, this function does not lock service |
448 | // list internally thus races with AddService()/RemoveService(). |
449 | google::protobuf::Service* |
450 | FindServiceByFullName(const butil::StringPiece& full_name) const; |
451 | |
452 | // Find a service by its ServiceDescriptor::name(). |
453 | // Returns the registered service pointer, NULL on not found. |
454 | // Notice that for performance concerns, this function does not lock service |
455 | // list internally thus races with AddService()/RemoveService(). |
456 | google::protobuf::Service* |
457 | FindServiceByName(const butil::StringPiece& name) const; |
458 | |
459 | // Put all services registered by user into `services' |
460 | void ListServices(std::vector<google::protobuf::Service*>* services); |
461 | |
462 | // Get statistics of this server |
463 | void GetStat(ServerStatistics* stat) const; |
464 | |
465 | // Get the options passed to Start(). |
466 | const ServerOptions& options() const { return _options; } |
467 | |
468 | // Status of this server. |
469 | Status status() const { return _status; } |
470 | |
471 | // Return true iff this server is serving requests. |
472 | bool IsRunning() const { return status() == RUNNING; } |
473 | |
474 | // Return the first service added to this server. If a service was once |
475 | // returned by first_service() and then removed, first_service() will |
476 | // always be NULL. |
477 | // This is useful for some production lines whose protocol does not |
478 | // contain a service name, in which case this service works as the |
479 | // default service. |
480 | google::protobuf::Service* first_service() const |
481 | { return _first_service; } |
482 | |
483 | // Set version string for this server, will be shown in /version page |
484 | void set_version(const std::string& version) { _version = version; } |
485 | const std::string& version() const { return _version; } |
486 | |
487 | // Return the address this server is listening |
488 | butil::EndPoint listen_address() const { return _listen_addr; } |
489 | |
490 | // Last time that Start() was successfully called. 0 if Start() was |
491 | // never called |
492 | time_t last_start_time() const { return _last_start_time; } |
493 | |
494 | SimpleDataPool* session_local_data_pool() const { return _session_local_data_pool; } |
495 | |
496 | const ThreadLocalOptions& thread_local_options() const { return _tl_options; } |
497 | |
498 | // Print the html code of tabs into `os'. |
499 | // current_tab_name is the tab highlighted. |
500 | void PrintTabsBody(std::ostream& os, const char* current_tab_name) const; |
501 | |
502 | // This method is already deprecated.You should NOT call it anymore. |
503 | int ResetMaxConcurrency(int max_concurrency); |
504 | |
505 | // Get/set max_concurrency associated with a method. |
506 | // Example: |
507 | // server.MaxConcurrencyOf("example.EchoService.Echo") = 10; |
508 | // or server.MaxConcurrencyOf("example.EchoService", "Echo") = 10; |
509 | // or server.MaxConcurrencyOf(&service, "Echo") = 10; |
510 | // Note: These interfaces can ONLY be called before the server is started. |
511 | // And you should NOT set the max_concurrency when you are going to choose |
512 | // an auto concurrency limiter, eg `options.max_concurrency = "auto"`.If you |
513 | // still called non-const version of the interface, your changes to the |
514 | // maximum concurrency will not take effect. |
515 | AdaptiveMaxConcurrency& MaxConcurrencyOf(const butil::StringPiece& full_method_name); |
516 | int MaxConcurrencyOf(const butil::StringPiece& full_method_name) const; |
517 | |
518 | AdaptiveMaxConcurrency& MaxConcurrencyOf(const butil::StringPiece& full_service_name, |
519 | const butil::StringPiece& method_name); |
520 | int MaxConcurrencyOf(const butil::StringPiece& full_service_name, |
521 | const butil::StringPiece& method_name) const; |
522 | |
523 | AdaptiveMaxConcurrency& MaxConcurrencyOf(google::protobuf::Service* service, |
524 | const butil::StringPiece& method_name); |
525 | int MaxConcurrencyOf(google::protobuf::Service* service, |
526 | const butil::StringPiece& method_name) const; |
527 | |
528 | private: |
529 | friend class StatusService; |
530 | friend class ProtobufsService; |
531 | friend class ConnectionsService; |
532 | friend class BadMethodService; |
533 | friend class ServerPrivateAccessor; |
534 | friend class PrometheusMetricsService; |
535 | friend class Controller; |
536 | |
537 | int AddServiceInternal(google::protobuf::Service* service, |
538 | bool is_builtin_service, |
539 | const ServiceOptions& options); |
540 | |
541 | int AddBuiltinService(google::protobuf::Service* service); |
542 | |
543 | // Remove all methods of `service' from internal structures. |
544 | void RemoveMethodsOf(google::protobuf::Service* service); |
545 | |
546 | int AddBuiltinServices(); |
547 | |
548 | // Initialize internal structure. Initializtion is |
549 | // ensured to be called only once |
550 | int InitializeOnce(); |
551 | |
552 | // Create acceptor with handlers of protocols. |
553 | Acceptor* BuildAcceptor(); |
554 | |
555 | int StartInternal(const butil::ip_t& ip, |
556 | const PortRange& port_range, |
557 | const ServerOptions *opt); |
558 | |
559 | // Number of user added services, not counting builtin services. |
560 | size_t service_count() const { |
561 | return _fullname_service_map.size() - |
562 | _builtin_service_count - |
563 | _virtual_service_count; |
564 | } |
565 | |
566 | // Number of builtin services. |
567 | size_t builtin_service_count() const { return _builtin_service_count; } |
568 | |
569 | static void* UpdateDerivedVars(void*); |
570 | |
571 | void GenerateVersionIfNeeded(); |
572 | void PutPidFileIfNeeded(); |
573 | |
574 | const MethodProperty* |
575 | FindMethodPropertyByFullName(const butil::StringPiece& fullname) const; |
576 | |
577 | const MethodProperty* |
578 | FindMethodPropertyByFullName(const butil::StringPiece& full_service_name, |
579 | const butil::StringPiece& method_name) const; |
580 | |
581 | const MethodProperty* |
582 | FindMethodPropertyByNameAndIndex(const butil::StringPiece& service_name, |
583 | int method_index) const; |
584 | |
585 | const ServiceProperty* |
586 | FindServicePropertyByFullName(const butil::StringPiece& fullname) const; |
587 | |
588 | const ServiceProperty* |
589 | FindServicePropertyByName(const butil::StringPiece& name) const; |
590 | |
591 | std::string ServerPrefix() const; |
592 | |
593 | // Mapping from hostname to corresponding SSL_CTX |
594 | typedef butil::CaseIgnoredFlatMap<std::shared_ptr<SocketSSLContext> > CertMap; |
595 | struct CertMaps { |
596 | CertMap cert_map; |
597 | CertMap wildcard_cert_map; |
598 | }; |
599 | |
600 | struct SSLContext { |
601 | std::shared_ptr<SocketSSLContext> ctx; |
602 | std::vector<std::string> filters; |
603 | }; |
604 | // Mapping from [certficate + private-key] to SSLContext |
605 | typedef butil::FlatMap<std::string, SSLContext> SSLContextMap; |
606 | |
607 | void FreeSSLContexts(); |
608 | |
609 | static int SSLSwitchCTXByHostname(struct ssl_st* ssl, |
610 | int* al, Server* server); |
611 | |
612 | static bool AddCertMapping(CertMaps& bg, const SSLContext& ssl_ctx); |
613 | static bool RemoveCertMapping(CertMaps& bg, const SSLContext& ssl_ctx); |
614 | static bool ResetCertMappings(CertMaps& bg, const SSLContextMap& ctx_map); |
615 | static bool ClearCertMapping(CertMaps& bg); |
616 | |
617 | AdaptiveMaxConcurrency& MaxConcurrencyOf(MethodProperty*); |
618 | int MaxConcurrencyOf(const MethodProperty*) const; |
619 | |
620 | DISALLOW_COPY_AND_ASSIGN(Server); |
621 | |
622 | // Put frequently-accessed data pool at first. |
623 | SimpleDataPool* _session_local_data_pool; |
624 | ThreadLocalOptions _tl_options; |
625 | |
626 | Status _status; |
627 | int _builtin_service_count; |
628 | // number of the virtual services for mapping URL to methods. |
629 | int _virtual_service_count; |
630 | bool _failed_to_set_max_concurrency_of_method; |
631 | Acceptor* _am; |
632 | Acceptor* _internal_am; |
633 | |
634 | // Use method->full_name() as key |
635 | MethodMap _method_map; |
636 | |
637 | // Use service->full_name() as key |
638 | ServiceMap _fullname_service_map; |
639 | |
640 | // In order to be compatible with some RPC framework that |
641 | // uses service->name() to designate an RPC service |
642 | ServiceMap _service_map; |
643 | |
644 | // The only non-builtin service in _service_map, otherwise NULL. |
645 | google::protobuf::Service* _first_service; |
646 | |
647 | // Store TabInfo of services inheriting Tabbed. |
648 | TabInfoList* _tab_info_list; |
649 | |
650 | // Store url patterns for paths without exact service names, examples: |
651 | // *.flv => Method |
652 | // abc* => Method |
653 | RestfulMap* _global_restful_map; |
654 | |
655 | // Default certficate which can't be reloaded |
656 | std::shared_ptr<SocketSSLContext> _default_ssl_ctx; |
657 | |
658 | // Reloadable SSL mappings |
659 | butil::DoublyBufferedData<CertMaps> _reload_cert_maps; |
660 | |
661 | // Holds the memory of all SSL_CTXs |
662 | SSLContextMap _ssl_ctx_map; |
663 | |
664 | ServerOptions _options; |
665 | butil::EndPoint _listen_addr; |
666 | |
667 | std::string _version; |
668 | time_t _last_start_time; |
669 | bthread_t _derivative_thread; |
670 | |
671 | bthread_keytable_pool_t* _keytable_pool; |
672 | |
673 | // mutable is required for `ServerPrivateAccessor' to change this bvar |
674 | mutable bvar::Adder<int64_t> _nerror_bvar; |
675 | mutable int32_t BAIDU_CACHELINE_ALIGNMENT _concurrency; |
676 | |
677 | }; |
678 | |
679 | // Get the data attached to current searching thread. The data is created by |
680 | // ServerOptions.thread_local_data_factory and reused between different threads. |
681 | // If ServerOptions.thread_local_data_factory is NULL, return NULL. |
682 | // If this function is not called inside a server thread, return NULL. |
683 | void* thread_local_data(); |
684 | |
685 | // Test if a dummy server was already started. |
686 | bool IsDummyServerRunning(); |
687 | |
688 | // Start a dummy server listening at `port'. If a dummy server was already |
689 | // running, this function does nothing and fails. |
690 | // NOTE: The second parameter(ProfilerLinker) is for linking of profiling |
691 | // functions when corresponding macros are defined, just ignore it. |
692 | // Returns 0 on success, -1 otherwise. |
693 | int StartDummyServerAt(int port, ProfilerLinker = ProfilerLinker()); |
694 | |
695 | } // namespace brpc |
696 | |
697 | #endif // BRPC_SERVER_H |
698 | |