crossroads

Git mirror of https://crossroads.e-tunity.com/
git clone git://git.finwo.net/app/crossroads
Log | Files | Refs

commit 82d44c0eef2b7c6a78d7148c77f788f4c45830dd
parent d4d4a0cf5b98a1b5a0e9430f35144e9970330163
Author: finwo <finwo@pm.me>
Date:   Sat,  3 Jan 2026 19:02:40 +0100

1.01

Diffstat:
MChangeLog | 9+++++++++
Mdoc/config.yo | 9+++++----
Mdoc/crossroads.html | 58+++++++++++++++++++++++++++++++++++++++++++++-------------
Mdoc/crossroads.man | 63+++++++++++++++++++++++++++++++++++++++++++++++++++------------
Mdoc/crossroads.pdf | 0
Mdoc/impatient.yo | 33++++++++++++++++++++++++++++-----
Mdoc/intro.yo | 29+++++++++++++++--------------
Metc/Makefile.def | 2+-
Msrc/choosebackend.c | 80+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------
Msrc/httpserversocket.c | 3++-
Mtools/makedist | 2+-
11 files changed, 219 insertions(+), 69 deletions(-)

diff --git a/ChangeLog b/ChangeLog @@ -1,6 +1,15 @@ ChangeLog for Crossroads ------------------------------------------------------------------------------ +1.01 [KK 2006-05-09] Small codechange in http_serversocket() for GCC < + 4.0. (There was accidentally post-3 code which I didn't notice:) + [KK 2006-05-10] Improved messaging in choose_backend(), in the + case of round robin balancing. Implemented weighted balancing with + "dispatchmode random". + [KK 2006-05-11] Updated the docs regarding the new primary site + http://crossroads.e-tunity.com. Promoted 1.01 to the next stable + release, versioned 1.02 as the next development release. + 1.00 [KK 2006-05-05] This version is identical to 0.33, except that crossroads will now be hosted in a publicly accessible SVN repository at svn://svn.e-tunity.com/crossroads. diff --git a/doc/config.yo b/doc/config.yo @@ -156,7 +156,8 @@ itemization( tt(dispatchmode) statement occurs. it() tt(dispatchmode random): Random selection. Probably only - for stress testing. + for stress testing, though when used with weights (see below) + it is a good distributor of new connections too. it() tt(dispatchmode bysize [ over) em(connections) tt(]): The next back end is the one @@ -366,11 +367,11 @@ startdit() default is 1. The weighing mechanism only applies to the dispatch modes - tt(byconnections), tt(bysize) and tt(byduration). - The weight is in fact a multiplier. E.g., if backend A has + tt(random), tt(byconnections), tt(bysize) and tt(byduration). + The weight is in fact a penalty factor. E.g., if backend A has tt(weight 2) and backend B has tt(weight 1), then backend B will be selected all the time, until its usage parameter is twice as - large as the parameter of A. + large as the parameter of A. Think of it as a 'sluggishness' statement. itemization( it() Syntax: tt(weight) em(number) tt(;) diff --git a/doc/crossroads.html b/doc/crossroads.html @@ -1,12 +1,12 @@ <a name="defs.yo"></a><html><head> -<title>Crossroads 0.33</title> +<title>Crossroads 1.01</title> <link rel="stylesheet" type="text/css" href="http://www.e-tunity.com/css/yodl.css"> <link rel="stylesheet" type="text/css" href="http://www.e-tunity.com/css/yodl.css"> <link rev="made" href="mailto:info@e-tunity.com"> </head> <body> <hr> -<h1>Crossroads 0.33</h1> +<h1>Crossroads 1.01</h1> <h2>Karel Kubat</h2> <h2>e-tunity</h2><h2>2005, 2006, ff.</h2> @@ -140,7 +140,12 @@ As quick reference, here are some important URL's for Crossroads: <li> <a href="http://public.e-tunity.com/crossroads/crossroads.html">http://public.e-tunity.com/crossroads/crossroads.html</a> is the documentation in HTML format (this text). Substitute - <em>.pdf</em> for <em>.html</em> to get the documentation in PDF format.</ul> + <em>.pdf</em> for <em>.html</em> to get the documentation in PDF format. +<p> +<li> <a href="svn://svn.e-tunity.com/crossroads">svn://svn.e-tunity.com/crossroads</a> is the SVN + repository; anonymous reading (fetching) is allowed. In order + to commit changes, <a href="mailto:karel@e-tunity.com">mail me</a> for + credentials.</ul> <p> <a name="l3"></a> <h3>1.2: Copyright and Disclaimer</h3> @@ -158,7 +163,10 @@ your modifications, with each distribution. While you are allowed to make any and all changes to the sources, I would appreciate hearing about them. If the changes concern new functionality or bugfixes, then I'll include them in a next -release, stating full credits. +release, stating full credits. If you want to seriously contribute (to +which you are heartily encouraged), then mail me and I'll get you +access to the Crossroads SVN repository, so that you can update and +commit as you like. <p> <a name="l4"></a> <h3>1.3: Terminology</h3> @@ -275,10 +283,33 @@ for getting crossroads up and running: <p> <ul> <p> -<li> Obtain the crossroads source archive. Change-dir to a - 'sources' directory on your system and unpack the archive. +<li> If you don't have SVN or don't want to use it: +<p> +<ul> + <li> Obtain the crossroads source archive at <br> + <a href="http://public.e-tunity.com/crossroads/crossroads-latest.tar.gz">http://public.e-tunity.com/crossroads/crossroads-latest.tar.gz</a>. +<p> +<li> Change-dir to a 'sources' directory on your system and + unpack the archive. +<p> +<li> Change-dir into the create directory <code>crossroads/</code>.</ul> +<p> +<li> If you have SVN and want to go for the newest snapshot: +<p> +<ul> + <li> Get the latest sources and snapshots using SVN from <br> + <code>svn://svn.e-tunity.com/crossroads</code>. +<p> +<li> You'll find the newest alpha version under + <code>crossroads/trunk</code> and the stable versions under + <code>crossroads/tags</code>, + e.g. <code>crossroads/tags/release-1.00</code>. <p> -<li> Change-dir into the created directory <code>crossroads/</code>. +<li> Choose which you want to use: the latest stable + release, or the bleeding edge alpha? In the former case, + change-dir to <code>crossroads/tags/release-</code><em>X.YY</em>, where + <em>X.YY</em> is a release ID. In the latter case, change-dir to + <code>crossroads/trunk</code>.</ul> <p> <li> Type <code>make install</code>. This installs the crossroads binary into <code>/usr/local/bin/</code>. If the compilation doesn't @@ -301,8 +332,8 @@ service www { </pre> <p> -Of course, make sure that you have webservers running on - 10.1.1.100 and 10.1.1.101. +That's off course assuming that you want to balance HTTP on + port 80 to two back ends at 10.1.1.100 and 10.1.1.101. <p> <li> Type <code>crossroads start</code>. <p> @@ -518,7 +549,8 @@ Roundrobin dispatching is the default method, when no <code>dispatchmode</code> statement occurs. <p> <li> <code>dispatchmode random</code>: Random selection. Probably only - for stress testing. + for stress testing, though when used with weights (see below) + it is a good distributor of new connections too. <p> <li> <code>dispatchmode bysize [ over</code> <em>connections</em> <code>]</code>: The next back end is the one @@ -730,11 +762,11 @@ The difference is that a <code>maxconnections</code> statement at the level of default is 1. <p> The weighing mechanism only applies to the dispatch modes - <code>byconnections</code>, <code>bysize</code> and <code>byduration</code>. - The weight is in fact a multiplier. E.g., if backend A has + <code>random</code>, <code>byconnections</code>, <code>bysize</code> and <code>byduration</code>. + The weight is in fact a penalty factor. E.g., if backend A has <code>weight 2</code> and backend B has <code>weight 1</code>, then backend B will be selected all the time, until its usage parameter is twice as - large as the parameter of A. + large as the parameter of A. Think of it as a 'sluggishness' statement. <p> <ul> <li> Syntax: <code>weight</code> <em>number</em> <code>;</code> diff --git a/doc/crossroads.man b/doc/crossroads.man @@ -1,6 +1,6 @@ -.TH "Crossroads 0\&.33" "2005, 2006, ff\&." +.TH "Crossroads 1\&.01" "2005, 2006, ff\&." .PP -.SH "Crossroads 0\&.33" +.SH "Crossroads 1\&.01" .SH "Karel Kubat" .SH "e-tunity" .SH "2005, 2006, ff\&." @@ -55,6 +55,12 @@ karel@e-tunity\&.com\&.) http://public\&.e-tunity\&.com/crossroads/crossroads\&.html is the documentation in HTML format (this text)\&. Substitute \fI\&.pdf\fP for \fI\&.html\fP to get the documentation in PDF format\&. +.IP +.IP o +svn://svn\&.e-tunity\&.com/crossroads is the SVN +repository; anonymous reading (fetching) is allowed\&. In order +to commit changes, mail me for +credentials\&. .PP .SH "1\&.2: Copyright and Disclaimer" @@ -73,7 +79,10 @@ your modifications, with each distribution\&. While you are allowed to make any and all changes to the sources, I would appreciate hearing about them\&. If the changes concern new functionality or bugfixes, then I\&'ll include them in a next -release, stating full credits\&. +release, stating full credits\&. If you want to seriously contribute (to +which you are heartily encouraged), then mail me and I\&'ll get you +access to the Crossroads SVN repository, so that you can update and +commit as you like\&. .PP .SH "1\&.3: Terminology" @@ -203,11 +212,40 @@ For the impatient, here\&'s the very-quick-but-very-superficial recipy for getting crossroads up and running: .PP .IP o -Obtain the crossroads source archive\&. Change-dir to a -\&'sources\&' directory on your system and unpack the archive\&. +If you don\&'t have SVN or don\&'t want to use it: +.IP +.IP o +Obtain the crossroads source archive at +.br +http://public\&.e-tunity\&.com/crossroads/crossroads-latest\&.tar\&.gz\&. +.IP +.IP o +Change-dir to a \&'sources\&' directory on your system and +unpack the archive\&. +.IP +.IP o +Change-dir into the create directory \f(CWcrossroads/\fP\&. +.IP +.IP o +If you have SVN and want to go for the newest snapshot: +.IP +.IP o +Get the latest sources and snapshots using SVN from +.br +\f(CWsvn://svn\&.e-tunity\&.com/crossroads\fP\&. +.IP +.IP o +You\&'ll find the newest alpha version under +\f(CWcrossroads/trunk\fP and the stable versions under +\f(CWcrossroads/tags\fP, +e\&.g\&. \f(CWcrossroads/tags/release-1\&.00\fP\&. .IP .IP o -Change-dir into the created directory \f(CWcrossroads/\fP\&. +Choose which you want to use: the latest stable +release, or the bleeding edge alpha? In the former case, +change-dir to \f(CWcrossroads/tags/release-\fP\fIX\&.YY\fP, where +\fIX\&.YY\fP is a release ID\&. In the latter case, change-dir to +\f(CWcrossroads/trunk\fP\&. .IP .IP o Type \f(CWmake install\fP\&. This installs the crossroads @@ -232,8 +270,8 @@ service www { .fi .IP -Of course, make sure that you have webservers running on -10\&.1\&.1\&.100 and 10\&.1\&.1\&.101\&. +That\&'s off course assuming that you want to balance HTTP on +port 80 to two back ends at 10\&.1\&.1\&.100 and 10\&.1\&.1\&.101\&. .IP .IP o Type \f(CWcrossroads start\fP\&. @@ -478,7 +516,8 @@ Roundrobin dispatching is the default method, when no .IP .IP o \f(CWdispatchmode random\fP: Random selection\&. Probably only -for stress testing\&. +for stress testing, though when used with weights (see below) +it is a good distributor of new connections too\&. .IP .IP o \f(CWdispatchmode bysize [ over\fP \fIconnections\fP \f(CW]\fP: @@ -716,11 +755,11 @@ higher the weight, the less likely a back end will be chosen\&. The default is 1\&. .IP The weighing mechanism only applies to the dispatch modes -\f(CWbyconnections\fP, \f(CWbysize\fP and \f(CWbyduration\fP\&. -The weight is in fact a multiplier\&. E\&.g\&., if backend A has +\f(CWrandom\fP, \f(CWbyconnections\fP, \f(CWbysize\fP and \f(CWbyduration\fP\&. +The weight is in fact a penalty factor\&. E\&.g\&., if backend A has \f(CWweight 2\fP and backend B has \f(CWweight 1\fP, then backend B will be selected all the time, until its usage parameter is twice as -large as the parameter of A\&. +large as the parameter of A\&. Think of it as a \&'sluggishness\&' statement\&. .IP .IP o Syntax: \f(CWweight\fP \fInumber\fP \f(CW;\fP diff --git a/doc/crossroads.pdf b/doc/crossroads.pdf Binary files differ. diff --git a/doc/impatient.yo b/doc/impatient.yo @@ -4,10 +4,33 @@ for getting crossroads up and running: itemization( - it() Obtain the crossroads source archive. Change-dir to a - 'sources' directory on your system and unpack the archive. + it() If you don't have SVN or don't want to use it: - it() Change-dir into the created directory tt(crossroads/). + itemization( + it() Obtain the crossroads source archive at nl() + lurl(http://public.e-tunity.com/crossroads/crossroads-latest.tar.gz). + + it() Change-dir to a 'sources' directory on your system and + unpack the archive. + + it() Change-dir into the create directory tt(crossroads/).) + + it() If you have SVN and want to go for the newest snapshot: + + itemization( + it() Get the latest sources and snapshots using SVN from nl() + tt(svn://svn.e-tunity.com/crossroads). + + it() You'll find the newest alpha version under + tt(crossroads/trunk) and the stable versions under + tt(crossroads/tags), + e.g. tt(crossroads/tags/release-1.00). + + it() Choose which you want to use: the latest stable + release, or the bleeding edge alpha? In the former case, + change-dir to tt(crossroads/tags/release-)em(X.YY), where + em(X.YY) is a release ID. In the latter case, change-dir to + tt(crossroads/trunk).) it() Type tt(make install). This installs the crossroads binary into tt(/usr/local/bin/). If the compilation doesn't @@ -28,8 +51,8 @@ service www { } }) - Of course, make sure that you have webservers running on - 10.1.1.100 and 10.1.1.101. + That's off course assuming that you want to balance HTTP on + port 80 to two back ends at 10.1.1.100 and 10.1.1.101. it() Type tt(crossroads start). diff --git a/doc/intro.yo b/doc/intro.yo @@ -30,20 +30,17 @@ subsect(Obtaining Crossroads) As quick reference, here are some important URL's for Crossroads: itemization( - it() lurl(http://public.e-tunity.com) is the site that serves - Crossroads and other packages. You can browse this at leisure + it() lurl(http:/crossroads.e-tunity.com) is the site that serves + Crossroads. You can browse this at leisure for documentation, sources, and so on. - it() - lurl(http://public.e-tunity.com/crossroads/crossroads-latest.tar.gz) is - the 'latest' distribution archive. (Older versions aren't - stored. If you really need an old version, contact me at - url(karel@e-tunity.com)(mailto:karel@e-tunity.com).) + it() lurl(http://freshmeat.net/projects/crossr) is the + Freshmeat announcement page. - it() - lurl(http://public.e-tunity.com/crossroads/crossroads.html) is - the documentation in HTML format (this text). Substitute - em(.pdf) for em(.html) to get the documentation in PDF format.) + it() lurl(svn://svn.e-tunity.com/crossroads) is the SVN + repository; anonymous reading (fetching) is allowed. In order + to commit changes, url(mail me)(mailto:karel@e-tunity.com) for + credentials.) subsect(Copyright and Disclaimer) @@ -61,7 +58,10 @@ your modifications, with each distribution. While you are allowed to make any and all changes to the sources, I would appreciate hearing about them. If the changes concern new functionality or bugfixes, then I'll include them in a next -release, stating full credits. +release, stating full credits. If you want to seriously contribute (to +which you are heartily encouraged), then mail me and I'll get you +access to the Crossroads SVN repository, so that you can update and +commit as you like. subsect(Terminology) @@ -166,4 +166,5 @@ subsect(Porting issues for pre-0.26 installations) is that 0.26 introduces em(sticky HTTP sessions) that span multiple TCP connections, and the term em(session) is used strictly in that sense -- and no longer for a - TCP connection.) -\ No newline at end of file + TCP connection.) + +\ No newline at end of file diff --git a/etc/Makefile.def b/etc/Makefile.def @@ -3,7 +3,7 @@ # Versioning. This defines the overall version ID and must match the topmost # entry in the ChangeLog. -VER = 1.00 +VER = 1.01 # Default config DEFAULT_CONF = /etc/crossroads.conf diff --git a/src/choosebackend.c b/src/choosebackend.c @@ -1,11 +1,12 @@ #include "crossroads.h" void choose_backend () { - int backends[MAX_BACKEND], nbackends = 0, i; - unsigned long long values[MAX_BACKEND]; - unsigned long long nbest; + int backends[MAX_BACKEND], nbackends = 0, i, j, k, + target_set = 0, flat_weights = 1, total_weights = 0, + random_weight, *weights, highest_weight = 0; + unsigned long long values[MAX_BACKEND], nbest; unsigned nclients; - int target_set = 0; + struct timeval tv; /* Check that we're allowed to accept at all. */ if (activeservice->maxconnections && @@ -15,7 +16,7 @@ void choose_backend () { current_backend = -1; return; } - + /* Populate the array of selectable backends. */ for (i = 0; i < activeservice->nbackend; i++) { /* Backend i is a candidate if: @@ -35,7 +36,7 @@ void choose_backend () { backends[nbackends++] = i; } } - + /* No backends? Nogo. */ if (!nbackends) { current_backend = -1; @@ -44,8 +45,7 @@ void choose_backend () { } /* Only one backend? Then it's always the first one, - * whatever you do. - */ + * whatever you do. */ if (nbackends == 1) { current_backend = backends[0]; servicereport->last_backend = current_backend; @@ -55,7 +55,7 @@ void choose_backend () { /* More than 1 backend available.. make a wise choice. */ switch (activeservice->dispatchtype) { - + case ds_roundrobin: /* Find the currently used backend, go one forward. */ for (i = 0; i < nbackends; i++) @@ -64,19 +64,63 @@ void choose_backend () { i %= nbackends; current_backend = backends[i]; servicereport->last_backend = current_backend; - msg ("Chosen backend (roundrobin): %d", current_backend); + msg ("Chosen backend (roundrobin): %d", + current_backend); return; } /* None found.. try the first one (run to momma). */ current_backend = backends[0]; servicereport->last_backend = current_backend; + msg ("Chosen backend (roundrobin, without historical info): %d", + current_backend); return; - + case ds_random: - /* Choose a random one of the availables. */ + /* Re-randomize. */ + gettimeofday (&tv, 0); + srand ((unsigned) tv.tv_usec); + + /* First of all let's see if all the weights are the same. */ + for (i = 0; i < nbackends; i++) { + total_weights += activeservice->backend[backends[i]].weight; + values[i] = activeservice->backend[backends[i]].weight; + if (activeservice->backend[backends[i]].weight != 1) + flat_weights = 0; + if (highest_weight < activeservice->backend[backends[i]].weight) + highest_weight = activeservice->backend[backends[i]].weight; + } + + if (! flat_weights) { + /* Non-flat weight random balancing. Determine the chance + * to hit a given back end. First we populate the weights array. + * Eg imagine we have 3 back ends with weights 1,2,4. Then the + * weights vector will be: 0,0,0,0,1,1,2 (0/1/2 being the indices + * of the candidate back ends) + */ + weights = xmalloc (total_weights * sizeof(int)); + k = 0; + for (i = 0; i < nbackends; i++) + for (j = 0; + j < highest_weight / + activeservice->backend[backends[i]].weight; + j++) + weights[k++] = i; + for (k = 0; k < total_weights; k++) + msg ("random: weights[%d] = %d", k, weights[k]); + + random_weight = rand() % total_weights; + current_backend = backends[weights[random_weight]]; + servicereport->last_backend = current_backend; + msg ("Chosen backend (weighted random): %d, " + "due to random weight %d (out of %d total)", + current_backend, random_weight, total_weights); + return; + } + + /* ELSE: Choose a random one of the availables. */ current_backend = backends[rand() % nbackends]; servicereport->last_backend = current_backend; - msg ("Chosen backend (random): %d", current_backend); + msg ("Chosen backend (flat-weight random): %d", current_backend); return; case ds_bysize: @@ -108,7 +152,7 @@ void choose_backend () { current_backend = backends[i]; servicereport->last_backend = current_backend; msg ("By size weighing: best so far is %d (value %g)", - current_backend, nbest); + current_backend, nbest); } msg ("Chosen backend (by size): %d", current_backend); return; @@ -120,7 +164,7 @@ void choose_backend () { * compute using the averaged value. However if the averaged * value is 0 (not yet computed), we take the true value. */ if (activeservice->dispatchover && - servicereport->backendstate[backends[i]].avg_nsec) + servicereport->backendstate[backends[i]].avg_nsec) values[i] = servicereport->backendstate[backends[i]].avg_nsec * 1000000 * @@ -143,7 +187,7 @@ void choose_backend () { current_backend = backends[i]; servicereport->last_backend = current_backend; msg ("By duration weighing: best so far is %d (value %g)", - current_backend, nbest); + current_backend, nbest); } msg ("Chosen backend (by duration): %d", current_backend); return; @@ -175,9 +219,9 @@ void choose_backend () { } msg ("Chosen backend (by connections): %d", current_backend); return; - + default: - /* Internal fry.. */ + /* Internal fry.. */ error ("Internal error: unhandled dispatch type %d", activeservice->dispatchtype); } diff --git a/src/httpserversocket.c b/src/httpserversocket.c @@ -1,9 +1,10 @@ #include "crossroads.h" int http_serversocket (unsigned char const *buf) { - msg ("Searching for back end for HTTP request."); int i, sock; + msg ("Searching for back end for HTTP request."); + /* Try to find a sticky cookie in the request. */ for (i = 0; i < activeservice->nbackend; i++) { if (servicereport->backendstate[i].avail != st_available) diff --git a/tools/makedist b/tools/makedist @@ -18,7 +18,7 @@ print ("Making crossroads distribution.. version is $ver\n"); my $distdir = "/tmp/crossroads-$ver"; if (-d $distdir) { print ("Removing old dist dir $distdir\n"); - run ("rm -r $distdir"); + run ("rm -rf $distdir"); } print ("Preparing for distro (make documentation, make clean)\n"); run ("make documentation");