[MEDIUM] don't limit peers nor stats socket to maxconn nor maxconnrate

The peers and the stats socket are control sockets, they must not be
limited by traffic rules.
This commit is contained in:
Willy Tarreau 2011-09-07 18:00:47 +02:00
parent 3ae65a16b9
commit 3c63fd828a
7 changed files with 35 additions and 10 deletions

View File

@ -84,6 +84,11 @@ enum {
#define LI_O_TCP_RULES 0x0010 /* run TCP rules checks on the incoming connection */
#define LI_O_CHK_MONNET 0x0020 /* check the source against a monitor-net rule */
#define LI_O_ACC_PROXY 0x0040 /* find the proxied address in the first request line */
#define LI_O_UNLIMITED 0x0080 /* listener not subject to global limits (peers & stats socket) */
/* Note: if a listener uses LI_O_UNLIMITED, it is highly recommended that it adds its own
* maxconn setting to the global.maxsock value so that its resources are reserved.
*/
/* The listener will be directly referenced by the fdtab[] which holds its
* socket. The listener provides the protocol-specific accept() function to

View File

@ -1278,6 +1278,8 @@ int cfg_parse_peers(const char *file, int linenum, char **args, int kwm)
curpeers->peers_fe->listen->frontend = ((struct proxy *)curpeers->peers_fe);
curpeers->peers_fe->listen->handler = process_session;
curpeers->peers_fe->listen->analysers |= ((struct proxy *)curpeers->peers_fe)->fe_req_ana;
curpeers->peers_fe->listen->options |= LI_O_UNLIMITED; /* don't make the peers subject to global limits */
global.maxsock += curpeers->peers_fe->listen->maxconn;
}
}
} /* neither "peer" nor "peers" */

View File

@ -206,7 +206,7 @@ static int stats_parse_global(char **args, int section_type, struct proxy *curpx
}
global.stats_sock.state = LI_INIT;
global.stats_sock.options = LI_O_NONE;
global.stats_sock.options = LI_O_UNLIMITED;
global.stats_sock.accept = session_accept;
global.stats_fe->accept = stats_accept;
global.stats_sock.handler = process_session;

View File

@ -68,6 +68,7 @@
#include <types/global.h>
#include <types/proto_tcp.h>
#include <types/acl.h>
#include <types/peers.h>
#include <proto/auth.h>
#include <proto/acl.h>
@ -603,6 +604,18 @@ void init(int argc, char **argv)
global.maxsock += global.maxconn * 2; /* each connection needs two sockets */
global.maxsock += global.maxpipes * 2; /* each pipe needs two FDs */
if (global.stats_fe)
global.maxsock += global.stats_fe->maxconn;
if (peers) {
/* peers also need to bypass global maxconn */
struct peers *p = peers;
for (p = peers; p; p = p->next)
if (p->peers_fe)
global.maxsock += p->peers_fe->maxconn;
}
if (global.tune.maxpollevents <= 0)
global.tune.maxpollevents = MAX_POLL_EVENTS;

View File

@ -1271,7 +1271,8 @@ static struct session *peer_session_create(struct peer *peer, struct peer_sessio
l->nbconn++; /* warning! right now, it's up to the handler to decrease this */
p->feconn++;/* beconn will be increased later */
jobs++;
actconn++;
if (!(s->listener->options & LI_O_UNLIMITED))
actconn++;
totalconn++;
return s;

View File

@ -2086,7 +2086,8 @@ struct task *process_session(struct task *t)
s->fe->feconn--;
if (s->flags & SN_BE_ASSIGNED)
s->be->beconn--;
actconn--;
if (!(s->listener->options & LI_O_UNLIMITED))
actconn--;
jobs--;
s->listener->nbconn--;
if (s->listener->state == LI_FULL)

View File

@ -1156,7 +1156,7 @@ int stream_sock_accept(int fd)
return 0;
}
if (global.cps_lim) {
if (global.cps_lim && !(l->options & LI_O_UNLIMITED)) {
int max = freq_ctr_remain(&global.conn_per_sec, global.cps_lim, 0);
if (unlikely(!max)) {
@ -1193,7 +1193,7 @@ int stream_sock_accept(int fd)
struct sockaddr_storage addr;
socklen_t laddr = sizeof(addr);
if (unlikely(actconn >= global.maxconn)) {
if (unlikely(actconn >= global.maxconn) && !(l->options & LI_O_UNLIMITED)) {
limit_listener(l, &global_listener_queue);
task_schedule(global_listener_queue_task, tick_add(now_ms, 1000)); /* try again in 1 second */
return 0;
@ -1252,12 +1252,14 @@ int stream_sock_accept(int fd)
}
/* increase the per-process number of cumulated connections */
update_freq_ctr(&global.conn_per_sec, 1);
if (global.conn_per_sec.curr_ctr > global.cps_max)
global.cps_max = global.conn_per_sec.curr_ctr;
if (!(l->options & LI_O_UNLIMITED)) {
update_freq_ctr(&global.conn_per_sec, 1);
if (global.conn_per_sec.curr_ctr > global.cps_max)
global.cps_max = global.conn_per_sec.curr_ctr;
actconn++;
}
jobs++;
actconn++;
totalconn++;
l->nbconn++;
@ -1273,8 +1275,9 @@ int stream_sock_accept(int fd)
* error due to a resource shortage, and we must stop the
* listener (ret < 0).
*/
if (!(l->options & LI_O_UNLIMITED))
actconn--;
jobs--;
actconn--;
l->nbconn--;
if (ret == 0) /* successful termination */
continue;