diff --git a/doc/html/highload.html b/doc/html/highload.html index a3693cf..b57a687 100644 --- a/doc/html/highload.html +++ b/doc/html/highload.html @@ -285,3 +285,16 @@ requirements. system bus are bottlenecks.

TCP_NODELAY and splice are not contrary to each over and should be combined on high-speed connections. + +

Add grace delay to reduce system calls

+ +
proxy -g8000,3,10
+First parameter is average read size we want to keep, second parameter is +minimal number of packets in the same direction to apply algorythm, +last value is delay added after polling and prior to reading data. +An example above adds 10 millisecond delay before reading data if average +polling size is below 8000 bytes and 3 read operations are made in the same +direction. It's specially usefule with splice.
logdump 1 1
is useful +to see how grace delays work, choose delay value to avoid filling the read +pipe/buffer (typically 64K) but keep the request sizes close to chosen average +on large file upload/download. diff --git a/man/3proxy.cfg.3 b/man/3proxy.cfg.3 index c29d5c3..82ba02a 100644 --- a/man/3proxy.cfg.3 +++ b/man/3proxy.cfg.3 @@ -110,6 +110,8 @@ disable NTLM authentication (required if passwords are stored in Unix crypt form .B -n1 enable NTLMv1 authentication. .br +.B -g(GRACE_TRAFF,GRACE_NUM,GRACE_DELAY) +delay GRACE_DELAY milliseconds before polling if average polling size below GRACE_TRAFF bytes and GRACE_NUM read operations in single directions are detected within 1 second. Useful to minimize polling .B -s (for admin) secure, allow only secure operations, currently only traffic counters view without ability to reset. diff --git a/src/common.c b/src/common.c index 871f7bc..b4e85d5 100644 --- a/src/common.c +++ b/src/common.c @@ -103,6 +103,7 @@ struct extparam conf = { 0, 0, -1, 0, 0, 0, 0, 0, 500, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 6, 600, 1048576, NULL, NULL, diff --git a/src/proxy.c b/src/proxy.c index 8bc7a38..881ef1e 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -131,7 +131,7 @@ char * proxy_stringtable[] = { NULL }; -#define LINESIZE 4096 +#define LINESIZE 32768 #define BUFSIZE (LINESIZE*2) #define FTPBUFSIZE 1536 diff --git a/src/proxy.h b/src/proxy.h index b30ebe8..1756648 100644 --- a/src/proxy.h +++ b/src/proxy.h @@ -30,7 +30,7 @@ #define MAXNSERVERS 5 #define UDPBUFSIZE 16384 -#define TCPBUFSIZE 8192 +#define TCPBUFSIZE 65536 #define SRVBUFSIZE (param->srv->bufsize?param->srv->bufsize:((param->service == S_UDPPM)?UDPBUFSIZE:TCPBUFSIZE)) diff --git a/src/proxymain.c b/src/proxymain.c index 8d5e1d7..e5cdda1 100644 --- a/src/proxymain.c +++ b/src/proxymain.c @@ -223,6 +223,7 @@ int MODULEMAINFUNC (int argc, char** argv){ #ifdef WITHSLICE " -s Use slice() - faster proxing, but no filtering for data\n" #endif + "-g(GRACE_TRAFF,GRACE_NUM,GRACE_DELAY) - delay GRACE_DELAY milliseconds before polling if average polling size below GRACE_TRAFF bytes and GRACE_NUM read operations in single directions are detected within 1 second to minimize polling\n" " -fFORMAT logging format (see documentation)\n" " -l log to stderr\n" " -lFILENAME log to FILENAME\n" @@ -428,6 +429,9 @@ int MODULEMAINFUNC (int argc, char** argv){ case 'a': srv.anonymous = 1 + atoi(argv[i]+2); break; + case 'g': + sscanf(argv[i]+2, "%d,%d,%d", &srv.gracetraf, &srv.gracenum, &srv.gracedelay); + break; case 's': #ifdef WITHSPLICE if(isudp || srv.service == S_ADMIN) diff --git a/src/sockmap.c b/src/sockmap.c index 19b603f..2f34a63 100644 --- a/src/sockmap.c +++ b/src/sockmap.c @@ -60,6 +60,7 @@ int sockmap(struct clientparam * param, int timeo, int usesplice){ int res; SASIZETYPE sasize; int needaction = 0; + int graceclinum=0, gracesrvnum=0, graceclitraf=0, gracesrvtraf=0, gracetime=0; #ifdef WITHSPLICE uint64_t inclientpipe = 0, inserverpipe = 0; @@ -158,6 +159,18 @@ sprintf(logbuf, "int FROMCLIENT = %d, TOCLIENTBUF = %d, FROMCLIENTBUF = %d, TOSE log(logbuf); #endif + if(needaction && param->srv->gracedelay && !sleeptime){ + if(gracetime != conf.time){ + gracetime = conf.time; + graceclinum=gracesrvnum=graceclitraf=gracesrvtraf=0; + } + else { + if( (graceclinum && graceclitraf && graceclinum>=param->srv->gracenum && (!param->srv->gracetraf || graceclitraf/graceclinum <= param->srv->gracetraf)) || + (gracesrvnum && gracesrvtraf && gracesrvnum>=param->srv->gracenum && (!param->srv->gracetraf || gracesrvtraf/gracesrvnum <= param->srv->gracetraf))) { + sleeptime = param->srv->gracedelay; + } + } + } if(needaction > 2 && !sleeptime){ if(needaction > (MAXFAILATTEMPT+1)){RETURN (93);} sleeptime = (1<<(needaction-2)); @@ -354,6 +367,9 @@ log(logbuf); #ifdef WITHLOG log("done read from client to pipe"); #endif + graceclinum++; + graceclitraf += res; + gracesrvnum = gracesrvtraf = 0; inclientpipe += res; if(inclientpipe >= MAXSPLICE) TOCLIENTPIPE = 0; needaction = 0; @@ -388,6 +404,9 @@ log(logbuf); #ifdef WITHLOG log("done read from server to pipe\n"); #endif + gracesrvnum++; + gracesrvtraf += res; + graceclinum = graceclitraf = 0; param->nreads++; param->statssrv64 += res; inserverpipe += res; @@ -426,6 +445,9 @@ log("read from client to buf"); #ifdef WITHLOG log("done read from client to buf"); #endif + graceclinum++; + graceclitraf += res; + gracesrvnum = gracesrvtraf = 0; inclientbuf += res; param->cliinbuf += res; if(param->clibufsize == param->cliinbuf) TOCLIENTBUF = 0; @@ -451,6 +473,9 @@ log("read from server to buf"); #ifdef WITHLOG log("done read from server to buf"); #endif + gracesrvnum++; + gracesrvtraf += res; + graceclinum = graceclitraf = 0; param->nreads++; param->statssrv64 += res; inserverbuf += res; diff --git a/src/structures.h b/src/structures.h index 6d929ca..3de7795 100644 --- a/src/structures.h +++ b/src/structures.h @@ -437,6 +437,7 @@ struct srvparam { int noforce; int anonymous; int clisockopts, srvsockopts, lissockopts, cbcsockopts, cbssockopts; + int gracetraf, gracenum, gracedelay; #ifdef WITHSPLICE int usesplice; #endif @@ -576,6 +577,7 @@ struct extparam { demon, maxchild, needreload, timetoexit, version, noforce, bandlimver, parentretries; int authcachetype, authcachetime; int filtermaxsize; + int gracetraf, gracenum, gracedelay; unsigned char *logname, **archiver; ROTATION logtype, countertype; char * counterfile;