Skip to content

Commit

Permalink
Improve server max connection (#3595)
Browse files Browse the repository at this point in the history
* Set max_connection before server create

* add core test

* fix tests, revert task_worker_num, optimize code

* revert

* revert minimum_connection

* defense

* add server.min_connection test
  • Loading branch information
matyhtf authored Aug 25, 2020
1 parent 0144910 commit e360010
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 22 deletions.
33 changes: 33 additions & 0 deletions core-tests/src/server/server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
2 changes: 1 addition & 1 deletion examples/cpp/test_server.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
12 changes: 7 additions & 5 deletions include/server.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down Expand Up @@ -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() {

This comment has been minimized.

Copy link
@langgl

langgl Jul 6, 2022

6

return max_connection;
}

int create_pipe_buffers();
int create_worker(swWorker *worker);
void disable_accept();
Expand Down Expand Up @@ -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);
Expand Down
39 changes: 27 additions & 12 deletions src/server/master.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -714,6 +720,15 @@ int Server::create() {
locations = new std::unordered_set<std::string>;
}

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 {
Expand Down
2 changes: 1 addition & 1 deletion src/server/reactor_process.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
2 changes: 1 addition & 1 deletion src/server/reactor_thread.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
4 changes: 2 additions & 2 deletions swoole_server.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)) {
Expand Down

0 comments on commit e360010

Please sign in to comment.