commit 82d44c0eef2b7c6a78d7148c77f788f4c45830dd
parent d4d4a0cf5b98a1b5a0e9430f35144e9970330163
Author: finwo <finwo@pm.me>
Date: Sat, 3 Jan 2026 19:02:40 +0100
1.01
Diffstat:
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");