diff --git a/core-tests/src/server/server.cpp b/core-tests/src/server/server.cpp index 7f4ce668a57..e3446c953b3 100644 --- a/core-tests/src/server/server.cpp +++ b/core-tests/src/server/server.cpp @@ -193,3 +193,36 @@ TEST(server, task_worker) { t1.join(); serv.gs->task_workers.destroy(); } + +TEST(server, max_connection) { + Server serv; + + serv.set_max_connection(0); + ASSERT_EQ(serv.get_max_connection(), SW_MIN(SW_MAX_CONNECTION, SwooleG.max_sockets)); + + serv.set_max_connection(SwooleG.max_sockets + 13); + ASSERT_EQ(serv.get_max_connection(), SwooleG.max_sockets); + + serv.set_max_connection(SwooleG.max_sockets - 13); + ASSERT_EQ(serv.get_max_connection(), SwooleG.max_sockets - 13); + + uint32_t last_value = serv.get_max_connection(); + + serv.create(); + + serv.set_max_connection(100); + ASSERT_EQ(serv.get_max_connection(), last_value); +} + +TEST(server, min_connection) { + Server serv; + + serv.task_worker_num = 14; + serv.worker_num = 5; + + serv.add_port(SW_SOCK_TCP, TEST_HOST, 0); + + serv.set_max_connection(15); + serv.create(); + ASSERT_EQ(serv.get_max_connection(), SwooleG.max_sockets); +} diff --git a/examples/cpp/test_server.cc b/examples/cpp/test_server.cc index 4603e9050eb..4967fe82786 100644 --- a/examples/cpp/test_server.cc +++ b/examples/cpp/test_server.cc @@ -31,7 +31,7 @@ int main(int argc, char **argv) { serv.worker_num = 1; serv.factory_mode = SW_MODE_BASE; - serv.max_connection = 10000; + serv.set_max_connection(10000); // serv.open_cpu_affinity = 1; // serv.open_tcp_nodelay = 1; // serv.daemonize = 1; diff --git a/include/server.h b/include/server.h index f2337b64124..c0e86879e94 100644 --- a/include/server.h +++ b/include/server.h @@ -522,11 +522,6 @@ class Server { int worker_groupid = 0; void **worker_input_buffers = nullptr; - /** - * max connection num - */ - uint32_t max_connection = 0; - /** * worker process max request */ @@ -1102,6 +1097,12 @@ class Server { void init_signal_handler(); void set_ipc_max_size(); + void set_max_connection(uint32_t _max_connection); + + inline uint32_t get_max_connection() { + return max_connection; + } + int create_pipe_buffers(); int create_worker(swWorker *worker); void disable_accept(); @@ -1226,6 +1227,7 @@ class Server { */ std::string document_root; std::mutex lock_; + uint32_t max_connection = 0; int start_check(); void check_port_type(ListenPort *ls); diff --git a/src/server/master.cc b/src/server/master.cc index 1c8fc54c67a..c9b36068191 100644 --- a/src/server/master.cc +++ b/src/server/master.cc @@ -243,6 +243,24 @@ dtls::Session *Server::accept_dtls_connection(swListenPort *port, swSocketAddres } #endif +void Server::set_max_connection(uint32_t _max_connection) { + if (connection_list != nullptr) { + swWarn("max_connection must be set before server create"); + return; + } + max_connection = _max_connection; + if (max_connection == 0) { + max_connection = SW_MIN(SW_MAX_CONNECTION, SwooleG.max_sockets); + } else if (max_connection > SW_SESSION_LIST_SIZE) { + max_connection = SW_SESSION_LIST_SIZE; + swWarn("max_connection is exceed the SW_SESSION_LIST_SIZE, it's reset to %u", SW_SESSION_LIST_SIZE); + } + if (SwooleG.max_sockets > 0 && max_connection > SwooleG.max_sockets) { + max_connection = SwooleG.max_sockets; + swWarn("max_connection is exceed the maximum value, it's reset to %u", SwooleG.max_sockets); + } +} + int Server::start_check() { // disable notice when use SW_DISPATCH_ROUND and SW_DISPATCH_QUEUE if (factory_mode == SW_MODE_PROCESS) { @@ -305,18 +323,6 @@ int Server::start_check() { if (worker_num < reactor_num) { reactor_num = worker_num; } - // max connections - uint32_t minimum_connection = (worker_num + task_worker_num) * 2 + 32; - if (max_connection < minimum_connection) { - max_connection = SwooleG.max_sockets; - swWarn("max_connection must be bigger than %u, it's reset to %u", minimum_connection, SwooleG.max_sockets); - } else if (SwooleG.max_sockets > 0 && max_connection > SwooleG.max_sockets) { - max_connection = SwooleG.max_sockets; - swWarn("max_connection is exceed the maximum value, it's reset to %u", SwooleG.max_sockets); - } else if (max_connection > SW_SESSION_LIST_SIZE) { - max_connection = SW_SESSION_LIST_SIZE; - swWarn("max_connection is exceed the SW_SESSION_LIST_SIZE, it's reset to %u", SW_SESSION_LIST_SIZE); - } // package max length for (auto ls : ports) { if (ls->protocol.package_max_length < SW_BUFFER_MIN_SIZE) { @@ -714,6 +720,15 @@ int Server::create() { locations = new std::unordered_set; } + uint32_t minimum_connection = (worker_num + task_worker_num) * 2 + 32; + if (ports.size() > 0) { + minimum_connection += ports.back()->socket_fd; + } + if (max_connection < minimum_connection) { + max_connection = SwooleG.max_sockets; + swWarn("max_connection must be bigger than %u, it's reset to %u", minimum_connection, SwooleG.max_sockets); + } + if (factory_mode == SW_MODE_BASE) { return create_reactor_processes(); } else { diff --git a/src/server/reactor_process.cc b/src/server/reactor_process.cc index 47d27b94aaf..89610c75d56 100644 --- a/src/server/reactor_process.cc +++ b/src/server/reactor_process.cc @@ -317,7 +317,7 @@ static int swReactorProcess_loop(swProcessPool *pool, swWorker *worker) { } #endif - reactor->max_socket = serv->max_connection; + reactor->max_socket = serv->get_max_connection(); reactor->close = Server::close_connection; diff --git a/src/server/reactor_thread.cc b/src/server/reactor_thread.cc index 406b8cd5f8f..f0e5b2d8fb8 100644 --- a/src/server/reactor_thread.cc +++ b/src/server/reactor_thread.cc @@ -839,7 +839,7 @@ static int ReactorThread_init(Server *serv, Reactor *reactor, uint16_t reactor_i reactor->ptr = serv; reactor->id = reactor_id; reactor->wait_exit = 0; - reactor->max_socket = serv->max_connection; + reactor->max_socket = serv->get_max_connection(); reactor->close = Server::close_connection; reactor->set_exit_condition(SW_REACTOR_EXIT_CONDITION_DEFAULT, [thread](Reactor *reactor, int &event_num) -> bool { diff --git a/swoole_server.cc b/swoole_server.cc index a261a7a1701..63ac01f3139 100644 --- a/swoole_server.cc +++ b/swoole_server.cc @@ -1117,7 +1117,7 @@ void php_swoole_server_before_start(swServer *serv, zval *zobject) { add_assoc_long(zsetting, "output_buffer_size", serv->output_buffer_size); } if (!zend_hash_str_exists(Z_ARRVAL_P(zsetting), ZEND_STRL("max_connection"))) { - add_assoc_long(zsetting, "max_connection", serv->max_connection); + add_assoc_long(zsetting, "max_connection", serv->get_max_connection()); } uint32_t i; @@ -2308,7 +2308,7 @@ static PHP_METHOD(swoole_server, set) { // max_connection if (php_swoole_array_get_value(vht, "max_connection", ztmp) || php_swoole_array_get_value(vht, "max_conn", ztmp)) { zend_long v = zval_get_long(ztmp); - serv->max_connection = SW_MAX(0, SW_MIN(v, UINT32_MAX)); + serv->set_max_connection(SW_MAX(0, SW_MIN(v, UINT32_MAX))); } // heartbeat_check_interval if (php_swoole_array_get_value(vht, "heartbeat_check_interval", ztmp)) {