Merge branch 'haproxy-1.2.12'
This commit is contained in:
commit
a4197319b4
@ -1,6 +1,14 @@
|
||||
ChangeLog :
|
||||
===========
|
||||
|
||||
2006/04/15 : 1.2.12
|
||||
Very few changes preparing for more important changes to support per-server
|
||||
session limitations and queueing :
|
||||
- ignore leading empty lines in HTTP requests as suggested by RFC2616.
|
||||
- added the 'weight' parameter to the servers, limited to 1..256. It applies
|
||||
to roundrobin and source hash.
|
||||
- the optional '-s' option could clobber '-st' and '-sf' if compiled in.
|
||||
|
||||
2006/03/30 : 1.2.11.1
|
||||
- under some conditions, it might have been possible that when the
|
||||
last dead server became available, it would not have been used
|
||||
|
2
Makefile
2
Makefile
@ -2,7 +2,7 @@
|
||||
# You should use it this way :
|
||||
# make TARGET=os CPU=cpu
|
||||
|
||||
VERSION := 1.2.11.1
|
||||
VERSION := 1.2.12
|
||||
|
||||
# Select target OS. TARGET must match a system for which COPTS and LIBS are
|
||||
# correctly defined below.
|
||||
|
5
TODO
5
TODO
@ -77,7 +77,7 @@ ok>
|
||||
- les options des serveurs ?
|
||||
- les filtres et regex ?
|
||||
|
||||
5) implémenter "balance source" pour faire un hash sur la source.
|
||||
* implémenter "balance source" pour faire un hash sur la source.
|
||||
permettre de spécifier un masque sur lequel s'applique le hachage,
|
||||
ainsi qu'une option pour hacher en fonction de l'adresse dans le
|
||||
champ "x-forwarded-for". Problème pour le support des pannes: ce
|
||||
@ -138,7 +138,7 @@ Todo for 1.2
|
||||
* listen [ip6::...ip6]/port[-port]
|
||||
- server xxx ipv4 | ipv4: | ipv4:port[-port] | ipv6/ | ipv6/port[-port]
|
||||
* appcookie
|
||||
- weighted round robin
|
||||
* weighted round robin
|
||||
- option to shutdown(listen_sock) when max connections reached
|
||||
* epoll
|
||||
- replace the event scheduler with an O(log(N)) one
|
||||
@ -149,4 +149,5 @@ Todo for 1.2
|
||||
activity on the buffer's pointers from touching the buffer page itself.
|
||||
- make buffer size configurable in global options
|
||||
* monitor number of simultaneous sessions in logs (per srv/inst/global)
|
||||
* ignore leading empty lines in HTTP requests
|
||||
|
||||
|
@ -2,9 +2,9 @@
|
||||
H A - P r o x y
|
||||
Reference Manual
|
||||
-------------------
|
||||
version 1.2.9
|
||||
version 1.2.12
|
||||
willy tarreau
|
||||
2006/03/01
|
||||
2006/04/15
|
||||
|
||||
============
|
||||
| Abstract |
|
||||
@ -42,11 +42,14 @@ There are only a few command line options :
|
||||
exits with code 1 if a syntax error was found.
|
||||
-p <pidfile> asks the process to write down each of its children's
|
||||
pids to this file in daemon mode.
|
||||
-sf specifies a list of pids to send a FINISH signal to after startup.
|
||||
-st specifies a list of pids to send a TERMINATE signal to after startup.
|
||||
-s shows statistics (only if compiled in)
|
||||
-l shows even more statistics (implies '-s')
|
||||
-de disables use of epoll()
|
||||
-dp disables use of poll()
|
||||
|
||||
-db disables background mode (stays in foreground, useful for debugging)
|
||||
-m <megs> enforces a memory usage limit to a maximum of <megs> megabytes.
|
||||
|
||||
The maximal number of connections per proxy is used as the default parameter for
|
||||
each instance for which the 'maxconn' paramter is not set in the 'listen' section.
|
||||
@ -59,9 +62,24 @@ section. When the proxy runs in this mode, it dumps every connections,
|
||||
disconnections, timestamps, and HTTP headers to stdout. This should NEVER
|
||||
be used in an init script since it will prevent the system from starting up.
|
||||
|
||||
For debugging, the '-db' option is very useful as it temporarily disables
|
||||
daemon mode and multi-process mode. The service can then be stopped by simply
|
||||
pressing Ctrl-C, without having to edit the config nor run full debug.
|
||||
|
||||
Statistics are only available if compiled in with the 'STATTIME' option. It's
|
||||
only used during code optimization phases.
|
||||
|
||||
The '-st' and '-sf' options are used to inform previously running processes
|
||||
that a configuration is being reloaded. They will receive the SIGTTOU signal to
|
||||
ask them to temporarily stop listening to the ports so that the new process
|
||||
can grab them. If anything wrong happens, the new process will send them a
|
||||
SIGTTIN to tell them to re-listen to the ports and continue their normal
|
||||
work. Otherwise, it will either ask them to finish (-sf) their work then softly
|
||||
exit, or immediately terminate (-st), breaking existing sessions. A typical use
|
||||
of this allows a configuration reload without service interruption :
|
||||
|
||||
# haproxy -p /var/run/haproxy.pid -sf $(cat /var/run/haproxy.pid)
|
||||
|
||||
======================
|
||||
| Configuration file |
|
||||
======================
|
||||
@ -219,7 +237,7 @@ Example :
|
||||
|
||||
1.4) Startup modes
|
||||
------------------
|
||||
The service can start in several different :
|
||||
The service can start in several different modes :
|
||||
- foreground / background
|
||||
- quiet / normal / debug
|
||||
|
||||
@ -230,6 +248,9 @@ returns immediately after forking. That's accomplished by the 'daemon' option
|
||||
in the 'global' section, which is the equivalent of the '-D' command line
|
||||
argument.
|
||||
|
||||
The '-db' command line argument overrides the 'daemon' and 'nbproc' global
|
||||
options to make the process run in normal, foreground mode.
|
||||
|
||||
Moreover, certain alert messages are still sent to the standard output even
|
||||
in 'daemon' mode. To make them disappear, simply add the 'quiet' option in the
|
||||
'global' section. This option has no command-line equivalent.
|
||||
@ -282,6 +303,9 @@ Example :
|
||||
# to stop only those processes among others :
|
||||
# kill $(</var/run/haproxy-private.pid)
|
||||
|
||||
# to reload a new configuration with minimal service impact and without
|
||||
# breaking existing sessions :
|
||||
# haproxy -f haproxy.cfg -p $(</var/run/haproxy-private.pid) -st $(</var/run/haproxy-private.pid)
|
||||
|
||||
1.7) Polling mechanisms
|
||||
-----------------------
|
||||
@ -479,7 +503,7 @@ amount of simultaneous ones. When the limit is reached, it simply stops
|
||||
listening, but the system may still be accepting them because of the back log
|
||||
queue. These connections will be processed later when other ones have freed
|
||||
some slots. This provides a serialization effect which helps very fragile
|
||||
servers resist to high loads. Se further for system limitations.
|
||||
servers resist to high loads. See further for system limitations.
|
||||
|
||||
Example :
|
||||
---------
|
||||
@ -528,6 +552,8 @@ Please note that the 'grace' parameter is ignored for SIGTTOU, as well as for
|
||||
SIGUSR1 when the process was in the pause mode. Please also note that it would
|
||||
be useful to save the pidfile before starting a new instance.
|
||||
|
||||
This mechanism fully exploited since 1.2.11 with the '-st' and '-sf' options
|
||||
(see above).
|
||||
|
||||
2.5) Connections expiration time
|
||||
--------------------------------
|
||||
@ -576,6 +602,9 @@ Example :
|
||||
# we can retry 3 times max after a failure
|
||||
retries 3
|
||||
|
||||
Please note that the reconnection attempt may lead to getting the connection
|
||||
sent to a new server if the original one died between connection attempts.
|
||||
|
||||
|
||||
2.7) Address of the dispatch server (deprecated)
|
||||
------------------------------------------------
|
||||
@ -766,9 +795,10 @@ The proxy can perform the load-balancing itself, both in TCP and in HTTP modes.
|
||||
This is the most interesting mode which obsoletes the old 'dispatch' mode
|
||||
described above. It has advantages such as server health monitoring, multiple
|
||||
port binding and port mapping. To use this mode, the 'balance' keyword is used,
|
||||
followed by the selected algorithm. As of version 1.1.23, only 'roundrobin' is
|
||||
available, which is also the default value if unspecified. In this mode, there
|
||||
will be no dispatch address, but the proxy needs at least one server.
|
||||
followed by the selected algorithm. Up to version 1.2.11, only 'roundrobin' was
|
||||
available, which is also the default value if unspecified. Starting with
|
||||
version 1.2.12, a new 'source' keyword appeared. In this mode, there will be no
|
||||
dispatch address, but the proxy needs at least one server.
|
||||
|
||||
Example : same as the last one, with internal load balancer
|
||||
---------
|
||||
@ -829,6 +859,42 @@ Examples :
|
||||
server srv1 192.168.1.1:+1000
|
||||
server srv2 192.168.1.2:+1000
|
||||
|
||||
As previously stated, version 1.2.12 brought the 'source' keyword. When this
|
||||
keyword is used, the client's IP address is hashed and evenly distributed among
|
||||
the available servers so that a same source IP will always go to the same
|
||||
server as long as there are no change in the number of available servers. This
|
||||
can be used for instance to bind HTTP and HTTPS to the same server. It can also
|
||||
be used to improve stickyness when one part of the client population does not
|
||||
accept cookies. In this case, only those ones will be perturbated should a
|
||||
server fail.
|
||||
|
||||
NOTE: It is important to consider the fact that many clients surf the net
|
||||
through proxy farms which assign different IP addresses for each
|
||||
request. Others use dialup connections with a different IP at each
|
||||
connection. Thus, the 'source' parameter should be used with extreme
|
||||
care.
|
||||
|
||||
Examples :
|
||||
----------
|
||||
|
||||
# make a same IP go to the same server whatever the service
|
||||
|
||||
listen http_proxy
|
||||
bind :80,:443
|
||||
mode http
|
||||
balance source
|
||||
server web1 192.168.1.1
|
||||
server web2 192.168.1.2
|
||||
|
||||
# try to improve client-server binding by using both source IP and cookie :
|
||||
|
||||
listen http_proxy :80
|
||||
mode http
|
||||
cookie SERVERID
|
||||
balance source
|
||||
server web1 192.168.1.1 cookie server01
|
||||
server web2 192.168.1.2 cookie server02
|
||||
|
||||
|
||||
3.1) Server monitoring
|
||||
----------------------
|
||||
@ -1029,6 +1095,54 @@ option :
|
||||
redispatch # send back to dispatch in case of connection failure
|
||||
|
||||
|
||||
3.3) Assigning different weights to servers
|
||||
-------------------------------------------
|
||||
Sometimes you will need to bring new servers to increase your server farm's
|
||||
capacity, but the new server will be either smaller (emergency use of anything
|
||||
that fits) or bigger (when investing in new hardware). For this reason, it
|
||||
might be wise to be able to send more clients to biggest servers. Till version
|
||||
1.2.11, it was necessary to replicate the same server multiple times in the
|
||||
configuration. Starting with 1.2.12, the 'weight' option is available. HAProxy
|
||||
then computes the most homogenous possible map of servers based on their
|
||||
weights so that the load gets distributed as smoothly as possible among
|
||||
them. The weight, between 1 and 256, should reflect one server's capacity
|
||||
relative to others. This way, if a server fails, the remaining capacities are
|
||||
still respected.
|
||||
|
||||
Example :
|
||||
---------
|
||||
# fair distribution among two opterons and one old pentium3
|
||||
|
||||
listen web_appl 0.0.0.0:80
|
||||
mode http
|
||||
cookie SERVERID insert nocache indirect
|
||||
balance roundrobin
|
||||
server pentium3-800 192.168.1.1:80 cookie server01 weight 8 check
|
||||
server opteron-2.0G 192.168.1.2:80 cookie server02 weight 20 check
|
||||
server opteron-2.4G 192.168.1.3:80 cookie server03 weight 24 check
|
||||
server web-backup1 192.168.2.1:80 cookie server04 check backup
|
||||
server web-excuse 192.168.3.1:80 check backup
|
||||
|
||||
Notes :
|
||||
-------
|
||||
- if unspecified, the default weight is 1
|
||||
|
||||
- the weight does not impact health checks, so it is cleaner to use weights
|
||||
than replicating the same server several times
|
||||
|
||||
- weights also work on backup servers if the 'allbackups' option is used
|
||||
|
||||
- the weights also apply to the source address load balancing
|
||||
('balance source').
|
||||
|
||||
- whatever the weights, the first server will always be assigned first. This
|
||||
is helpful for troubleshooting.
|
||||
|
||||
- for the purists, the map calculation algorithm gives precedence to first
|
||||
server, so the map is the most uniform when servers are declared in
|
||||
ascending order relative to their weights.
|
||||
|
||||
|
||||
4) Additionnal features
|
||||
=======================
|
||||
|
||||
|
@ -2,9 +2,9 @@
|
||||
H A - P r o x y
|
||||
Manuel de référence
|
||||
-------------------
|
||||
version 1.2.9
|
||||
version 1.2.12
|
||||
willy tarreau
|
||||
2006/03/01
|
||||
2006/04/15
|
||||
|
||||
================
|
||||
| Introduction |
|
||||
@ -46,10 +46,14 @@ Les options de lancement sont peu nombreuses :
|
||||
détectée.
|
||||
-p <fichier> indique au processus père qu'il doit écrire les PIDs de ses
|
||||
fils dans ce fichier en mode démon.
|
||||
-sf specifie une liste de PIDs auxquels envoyer un signal FINISH
|
||||
-st specifie une liste de PIDs auxquels envoyer un signal TERMINATE
|
||||
-s affiche les statistiques (si option compilée)
|
||||
-l ajoute des informations aux statistiques
|
||||
-de désactive l'utilisation de epoll()
|
||||
-dp désactive l'utilisation de poll()
|
||||
-db désactive la mise en arrière-plan (utile pour débugger)
|
||||
-m <megs> applique une limitation de <megs> Mo d'utilisation mémoire
|
||||
|
||||
Le nombre maximal de connexion simultanées par proxy est le paramètre par
|
||||
défaut pour les proxies pour lesquels ce paramètre n'est pas précisé dans le
|
||||
@ -64,10 +68,27 @@ Le mode debug correspond
|
||||
mode, toutes les connexions, déconnexions, et tous les échanges d'en-têtes HTTP
|
||||
sont affichés.
|
||||
|
||||
Pour debugger, l'option '-db' est très pratique car elle désactive
|
||||
temporairement le mode daemon et le mode multi-processus. Le service peut alors
|
||||
être arrêté par un simple appui sur Ctrl-C, sans avoir à modifier la
|
||||
configuration ni à activer le mode debug complet.
|
||||
|
||||
Les statistiques ne sont disponibles que si le programme a été compilé avec
|
||||
l'option "STATTIME". Il s'agit principalement de données brutes n'ayant
|
||||
d'utilité que lors de benchmarks par exemple.
|
||||
|
||||
Les paramètres '-st' et '-sf' sont utilisés pour informer des processus
|
||||
existants que la configuration va être rechargée. Ils recevront le signal
|
||||
SIGTTOU, leur demandant de libérer les ports en écoute afin que le nouveau
|
||||
processus puisse les prendre. Si quoi que ce soit se passe mal, le nouveau
|
||||
processus leur enverra un signal SIGTTIN pour leur indiquer qu'ils peuvent
|
||||
se remettre en écoute et continuer leur travail. En revanche, si la
|
||||
configuration se charge correctement, alors ils recevront un signal de demande
|
||||
de fin de travail en douceur (-sf), ou de terminaison immédiate (-st) qui
|
||||
coupera les sessions en cours. Un usage typique tel que celui-ci permet de
|
||||
recharger une configuration sans interruption de service :
|
||||
|
||||
# haproxy -p /var/run/haproxy.pid -sf $(cat /var/run/haproxy.pid)
|
||||
|
||||
============================
|
||||
| Fichier de configuration |
|
||||
@ -247,6 +268,9 @@ initialisation. Il faut le mettre en arri
|
||||
au processus appelant. C'est ce que fait l'option 'daemon' de la section
|
||||
'global', et qui est l'équivalent du paramètre '-D' de la ligne de commande.
|
||||
|
||||
Le paramètre de ligne de commande '-db' inhibe les options globales 'daemon'
|
||||
et 'nbproc' pour faire fonctionner le processus en mode normal, avant-plan.
|
||||
|
||||
Par ailleurs, certains messages d'alerte sont toujours envoyés sur la sortie
|
||||
standard, même en mode 'daemon'. Pour ne plus les voir ailleurs que dans les
|
||||
logs, il suffit de passer en mode silencieux par l'ajout de l'option 'quiet'.
|
||||
@ -301,6 +325,9 @@ Exemple :
|
||||
# pour stopper seulement ces processus parmi d'autres :
|
||||
# kill $(</var/run/haproxy-private.pid)
|
||||
|
||||
# pour recharger une configuration avec un impact minimal sur le service,
|
||||
# et sans casser les sessions existantes :
|
||||
# haproxy -f haproxy.cfg -p $(</var/run/haproxy-private.pid) -st $(</var/run/haproxy-private.pid)
|
||||
|
||||
1.7) Mécanismes de traitements des événements
|
||||
---------------------------------------------
|
||||
@ -553,6 +580,8 @@ noter que le param
|
||||
signal SIGUSR1 une fois le processus en pause. Aussi, il peut s'avérer très
|
||||
utile de sauver le fichier de pid avant de démarrer une nouvelle instance.
|
||||
|
||||
Ce mécanisme est pleinement exploité à partir de la version 1.2.11 avec les
|
||||
options '-st' et '-sf' (voir plus haut).
|
||||
|
||||
2.5) Temps d'expiration des connexions
|
||||
--------------------------------------
|
||||
@ -603,6 +632,9 @@ Exemple :
|
||||
# on essaie encore trois fois maxi
|
||||
retries 3
|
||||
|
||||
Il est à noter que la tentative de reconnexion peut amener à utiliser un autre
|
||||
serveur si le premier a disparu entre deux tentatives de connexion.
|
||||
|
||||
|
||||
2.7) Adresse du serveur
|
||||
-----------------------
|
||||
@ -768,9 +800,10 @@ Attention : la syntaxe a chang
|
||||
Le relais peut effectuer lui-même la répartition de charge entre les différents
|
||||
serveurs définis pour un service donné, en mode TCP comme en mode HTTP. Pour
|
||||
cela, on précise le mot clé 'balance' dans la définition du service,
|
||||
éventuellement suivi du nom d'un algorithme de répartition. En version 1.1.9,
|
||||
seul 'roundrobin' est géré, et c'est aussi la valeur implicite par défaut. Il
|
||||
est évident qu'en cas d'utilisation du répartiteur interne, il ne faudra pas
|
||||
éventuellement suivi du nom d'un algorithme de répartition. Jusqu'à la version
|
||||
1.2.11, seul 'roundrobin' était géré, et c'est aussi la valeur implicite par
|
||||
défaut. Avec la version 1.2.12, le nouveau mot clé 'source' est apparu. Il est
|
||||
évident qu'en cas d'utilisation du répartiteur interne, il ne faudra pas
|
||||
spécifier d'adresse de dispatch, et qu'il faudra au moins un serveur.
|
||||
|
||||
Exemple : même que précédemment en répartition interne
|
||||
@ -833,6 +866,44 @@ Exemples :
|
||||
server srv1 192.168.1.1:+1000
|
||||
server srv2 192.168.1.2:+1000
|
||||
|
||||
Comme indiqué précédemment, la version 1.2.12 apporta le nouveau mot clé
|
||||
'source'. Lorsque celui-ci est utilisé, l'adresse IP du client est hachée et
|
||||
distribuée de manière homogène parmi les serveurs disponibles, de sorte qu'une
|
||||
même adresse IP aille toujours sur le même serveur tant qu'il n'y a aucun
|
||||
changement dans le nombre de serveurs disponibles. Ceci peut être utilisé par
|
||||
exemple pour attacher le HTTP et le HTTPS sur un même serveur pour un même
|
||||
client. Cela peut également être utilisé pour améliorer la persistance
|
||||
lorsqu'une partie de la population des clients n'accepte pas les cookies. Dans
|
||||
ce cas, seuls ces derniers seront perturbés par la perte d'un serveur.
|
||||
|
||||
NOTE: il est important de prendre en compte le fait que beaucoup d'internautes
|
||||
naviguent à travers des fermes de proxies qui assignent des adresses IP
|
||||
différentes à chaque requête. D'autres internautes utilisent des liens à
|
||||
la demande et obtiennent une adresse IP différente à chaque connexion. De
|
||||
ce fait, le paramètre 'source' doit être utilisé avec une extrème
|
||||
précaution.
|
||||
|
||||
Exemples :
|
||||
----------
|
||||
|
||||
# assurer qu'une même adresse IP ira sur le même serveur pour tout service
|
||||
|
||||
listen http_proxy
|
||||
bind :80,:443
|
||||
mode http
|
||||
balance source
|
||||
server web1 192.168.1.1
|
||||
server web2 192.168.1.2
|
||||
|
||||
# améliorer la persistance par l'utilisation de la source en plus du cookie :
|
||||
|
||||
listen http_proxy :80
|
||||
mode http
|
||||
cookie SERVERID
|
||||
balance source
|
||||
server web1 192.168.1.1 cookie server01
|
||||
server web2 192.168.1.2 cookie server02
|
||||
|
||||
|
||||
3.1) Surveillance des serveurs
|
||||
------------------------------
|
||||
@ -844,6 +915,7 @@ Il est possible de sp
|
||||
tests du serveur par le paramètre "inter", le nombre d'échecs acceptés par le
|
||||
paramètre "fall", et le nombre de succès avant reprise par le paramètre "rise".
|
||||
Les paramètres non précisés prennent les valeurs suivantes par défaut :
|
||||
|
||||
- inter : 2000
|
||||
- rise : 2
|
||||
- fall : 3
|
||||
@ -866,10 +938,12 @@ consid
|
||||
deux tests (paramètre "inter"). Pour activer ce mode, spécifier l'option
|
||||
"httpchk", éventuellement suivie d'une méthode et d'une URI. L'option "httpchk"
|
||||
accepte donc 4 formes :
|
||||
|
||||
- option httpchk -> OPTIONS / HTTP/1.0
|
||||
- option httpchk URI -> OPTIONS <URI> HTTP/1.0
|
||||
- option httpchk METH URI -> <METH> <URI> HTTP/1.0
|
||||
- option httpchk METH URI VER -> <METH> <URI> <VER>
|
||||
|
||||
Voir les exemples ci-après.
|
||||
|
||||
Depuis la version 1.1.17, il est possible de définir des serveurs de secours,
|
||||
@ -1038,6 +1112,59 @@ tente de s'y connecter, il faut pr
|
||||
redispatch # renvoyer vers dispatch si serveur HS.
|
||||
|
||||
|
||||
3.3) Assignation de poids différents à des serveurs
|
||||
---------------------------------------------------
|
||||
Parfois il arrive d'ajouter de nouveaux serveurs pour accroître la capacité
|
||||
d'une ferme de serveur, mais le nouveau serveur est soit beaucoup plus petit
|
||||
que les autres (dans le cas d'un ajout d'urgence de matériel de récupération),
|
||||
soit plus puissant (lors d'un investissement dans du matériel neuf). Pour cette
|
||||
raison, il semble parfois judicieux de pouvoir envoyer plus de clients vers les
|
||||
plus gros serveurs. Jusqu'à la version 1.2.11, il était nécessaire de répliquer
|
||||
plusieurs fois les définitions des serveurs pour augmenter leur poids. Depuis
|
||||
la version 1.2.12, l'option 'weight' est disponible. HAProxy construit alors
|
||||
une vue des serveurs disponibles la plus homogène possible en se basant sur
|
||||
leur poids de sorte que la charge se distribue de la manière la plus lisse
|
||||
possible. Le poids compris entre 1 et 256 doit refléter la capacité d'un
|
||||
serveur par rapport aux autres. De cette manière, si un serveur disparait, les
|
||||
capacités restantes sont toujours respectées.
|
||||
|
||||
|
||||
Exemple :
|
||||
---------
|
||||
# distribution équitable sur 2 opteron and un ancien pentium3
|
||||
|
||||
listen web_appl 0.0.0.0:80
|
||||
mode http
|
||||
cookie SERVERID insert nocache indirect
|
||||
balance roundrobin
|
||||
server pentium3-800 192.168.1.1:80 cookie server01 weight 8 check
|
||||
server opteron-2.0G 192.168.1.2:80 cookie server02 weight 20 check
|
||||
server opteron-2.4G 192.168.1.3:80 cookie server03 weight 24 check
|
||||
server web-backup1 192.168.2.1:80 cookie server04 check backup
|
||||
server web-excuse 192.168.3.1:80 check backup
|
||||
|
||||
Notes :
|
||||
-------
|
||||
- lorsque le poids n'est pas spécifié, la valeur par défaut est à 1
|
||||
|
||||
- le poids n'impacte pas les tests de fonctionnement (health checks), donc il
|
||||
est plus propre d'utiliser les poids que de répliquer le même serveur
|
||||
plusieurs fois.
|
||||
|
||||
- les poids s'appliquent également aux serveurs de backup si l'option
|
||||
'allbackups' est positionnée.
|
||||
|
||||
- le poids s'applique aussi à la répartition selon la source
|
||||
('balance source').
|
||||
|
||||
- quels que soient les poids, le premier serveur sera toujours assigné en
|
||||
premier. Cette règle facilite les diagnostics.
|
||||
|
||||
- pour les puristes, l'algorithme de calculation de la vue des serveurs donne
|
||||
une priorité aux premiers serveurs, donc la vue est la plus uniforme si les
|
||||
serveurs sont déclarés dans l'ordre croissant de leurs poids.
|
||||
|
||||
|
||||
4) Fonctionnalités additionnelles
|
||||
=================================
|
||||
|
||||
|
104
examples/haproxy-small.spec
Normal file
104
examples/haproxy-small.spec
Normal file
@ -0,0 +1,104 @@
|
||||
Summary: HA-Proxy is a TCP/HTTP reverse proxy for high availability environments
|
||||
Name: haproxy
|
||||
Version: 1.2.12
|
||||
Release: 1
|
||||
License: GPL
|
||||
Group: System Environment/Daemons
|
||||
URL: http://w.ods.org/tools/%{name}/
|
||||
Source0: http://w.ods.org/tools/%{name}/%{name}-%{version}.tar.gz
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-root
|
||||
BuildRequires: pcre-devel
|
||||
Requires: /sbin/chkconfig, /sbin/service
|
||||
|
||||
%description
|
||||
HA-Proxy is a TCP/HTTP reverse proxy which is particularly suited for high
|
||||
availability environments. Indeed, it can:
|
||||
- route HTTP requests depending on statically assigned cookies
|
||||
- spread the load among several servers while assuring server persistence
|
||||
through the use of HTTP cookies
|
||||
- switch to backup servers in the event a main one fails
|
||||
- accept connections to special ports dedicated to service monitoring
|
||||
- stop accepting connections without breaking existing ones
|
||||
- add/modify/delete HTTP headers both ways
|
||||
- block requests matching a particular pattern
|
||||
|
||||
It needs very little resource. Its event-driven architecture allows it to easily
|
||||
handle thousands of simultaneous connections on hundreds of instances without
|
||||
risking the system's stability.
|
||||
|
||||
%prep
|
||||
%setup -q
|
||||
|
||||
%build
|
||||
%{__make} REGEX="pcre" "COPTS.pcre=-DUSE_PCRE $(pcre-config --cflags)" DEBUG="" TARGET=linux24e SMALL_OPTS="-DBUFSIZE=8030 -DMAXREWRITE=1030 -DSYSTEM_MAXCONN=1024" DEBUG="" LIBS.pcre="-L\$(PCREDIR)/lib -Wl,-Bstatic -lpcreposix -lpcre -Wl,-Bdynamic"
|
||||
|
||||
%install
|
||||
[ "%{buildroot}" != "/" ] && %{__rm} -rf %{buildroot}
|
||||
|
||||
%{__install} -d %{buildroot}%{_sbindir}
|
||||
%{__install} -d %{buildroot}%{_sysconfdir}/rc.d/init.d
|
||||
%{__install} -d %{buildroot}%{_sysconfdir}/%{name}
|
||||
|
||||
%{__install} -s %{name} %{buildroot}%{_sbindir}/
|
||||
%{__install} -c -m 644 examples/%{name}.cfg %{buildroot}%{_sysconfdir}/%{name}/
|
||||
%{__install} -c -m 755 examples/%{name}.init %{buildroot}%{_sysconfdir}/rc.d/init.d/%{name}
|
||||
|
||||
%clean
|
||||
[ "%{buildroot}" != "/" ] && %{__rm} -rf %{buildroot}
|
||||
|
||||
%post
|
||||
/sbin/chkconfig --add %{name}
|
||||
|
||||
%preun
|
||||
if [ $1 = 0 ]; then
|
||||
/sbin/service %{name} stop >/dev/null 2>&1 || :
|
||||
/sbin/chkconfig --del %{name}
|
||||
fi
|
||||
|
||||
%postun
|
||||
if [ "$1" -ge "1" ]; then
|
||||
/sbin/service %{name} condrestart >/dev/null 2>&1 || :
|
||||
fi
|
||||
|
||||
%files
|
||||
%defattr(-,root,root)
|
||||
%doc CHANGELOG TODO examples doc/haproxy-en.txt doc/haproxy-fr.txt doc/architecture.txt
|
||||
%attr(0755,root,root) %{_sbindir}/%{name}
|
||||
%dir %{_sysconfdir}/%{name}
|
||||
%attr(0644,root,root) %config(noreplace) %{_sysconfdir}/%{name}/%{name}.cfg
|
||||
%attr(0755,root,root) %config %{_sysconfdir}/rc.d/init.d/%{name}
|
||||
|
||||
%changelog
|
||||
* Wed Apr 15 2006 Willy Tarreau <willy@w.ods.org>
|
||||
- updated to 1.2.12
|
||||
|
||||
* Wed Mar 30 2006 Willy Tarreau <willy@w.ods.org>
|
||||
- updated to 1.2.11.1
|
||||
|
||||
* Wed Mar 19 2006 Willy Tarreau <willy@w.ods.org>
|
||||
- updated to 1.2.10
|
||||
|
||||
* Wed Mar 15 2006 Willy Tarreau <willy@w.ods.org>
|
||||
- updated to 1.2.9
|
||||
|
||||
* Sat Jan 22 2005 Willy Tarreau <willy@w.ods.org>
|
||||
- updated to 1.2.3 (1.1.30)
|
||||
|
||||
* Sun Nov 14 2004 Willy Tarreau <w@w.ods.org>
|
||||
- updated to 1.1.29
|
||||
- fixed path to config and init files
|
||||
- statically linked PCRE to increase portability to non-pcre systems
|
||||
|
||||
* Sun Jun 6 2004 Willy Tarreau <willy@w.ods.org>
|
||||
- updated to 1.1.28
|
||||
- added config check support to the init script
|
||||
|
||||
* Tue Oct 28 2003 Simon Matter <simon.matter@invoca.ch>
|
||||
- updated to 1.1.27
|
||||
- added pid support to the init script
|
||||
|
||||
* Wed Oct 22 2003 Simon Matter <simon.matter@invoca.ch>
|
||||
- updated to 1.1.26
|
||||
|
||||
* Thu Oct 16 2003 Simon Matter <simon.matter@invoca.ch>
|
||||
- initial build
|
@ -1,6 +1,6 @@
|
||||
Summary: HA-Proxy is a TCP/HTTP reverse proxy for high availability environments
|
||||
Name: haproxy
|
||||
Version: 1.2.11.1
|
||||
Version: 1.2.12
|
||||
Release: 1
|
||||
License: GPL
|
||||
Group: System Environment/Daemons
|
||||
@ -71,6 +71,9 @@ fi
|
||||
%attr(0755,root,root) %config %{_sysconfdir}/rc.d/init.d/%{name}
|
||||
|
||||
%changelog
|
||||
* Wed Apr 15 2006 Willy Tarreau <willy@w.ods.org>
|
||||
- updated to 1.2.12
|
||||
|
||||
* Wed Mar 30 2006 Willy Tarreau <willy@w.ods.org>
|
||||
- updated to 1.2.11.1
|
||||
|
||||
|
322
haproxy.c
322
haproxy.c
@ -88,11 +88,11 @@
|
||||
#include "include/appsession.h"
|
||||
|
||||
#ifndef HAPROXY_VERSION
|
||||
#define HAPROXY_VERSION "1.2.11.1"
|
||||
#define HAPROXY_VERSION "1.2.12"
|
||||
#endif
|
||||
|
||||
#ifndef HAPROXY_DATE
|
||||
#define HAPROXY_DATE "2006/03/30"
|
||||
#define HAPROXY_DATE "2006/04/15"
|
||||
#endif
|
||||
|
||||
/* this is for libc5 for example */
|
||||
@ -511,6 +511,8 @@ struct server {
|
||||
int inter; /* time in milliseconds */
|
||||
int result; /* 0 = connect OK, -1 = connect KO */
|
||||
int curfd; /* file desc used for current test, or -1 if not in test */
|
||||
unsigned char uweight, eweight; /* user-specified weight-1, and effective weight-1 */
|
||||
unsigned int wscore; /* weight score, used during srv map computation */
|
||||
struct proxy *proxy; /* the proxy this server belongs to */
|
||||
};
|
||||
|
||||
@ -577,8 +579,12 @@ struct proxy {
|
||||
struct in_addr mon_net, mon_mask; /* don't forward connections from this net (network order) FIXME: should support IPv6 */
|
||||
int state; /* proxy state */
|
||||
struct sockaddr_in dispatch_addr; /* the default address to connect to */
|
||||
struct server *srv, *cursrv; /* known servers, current server */
|
||||
int srv_act, srv_bck; /* # of servers */
|
||||
struct server *srv; /* known servers */
|
||||
int srv_act, srv_bck; /* # of running servers */
|
||||
int tot_wact, tot_wbck; /* total weights of active and backup servers */
|
||||
struct server **srv_map; /* the server map used to apply weights */
|
||||
int srv_map_sz; /* the size of the effective server map */
|
||||
int srv_rr_idx; /* next server to be elected in round robin mode */
|
||||
char *cookie_name; /* name of the cookie to look for */
|
||||
int cookie_len; /* strlen(cookie_name), computed only once */
|
||||
char *appsession_name; /* name of the cookie to look for */
|
||||
@ -1807,77 +1813,101 @@ static inline void session_free(struct session *s) {
|
||||
/*
|
||||
* This function recounts the number of usable active and backup servers for
|
||||
* proxy <p>. These numbers are returned into the p->srv_act and p->srv_bck.
|
||||
* This function also recomputes the total active and backup weights.
|
||||
*/
|
||||
static inline void recount_servers(struct proxy *px) {
|
||||
static void recount_servers(struct proxy *px) {
|
||||
struct server *srv;
|
||||
|
||||
px->srv_act = 0; px->srv_bck = 0;
|
||||
px->srv_act = 0; px->srv_bck = px->tot_wact = px->tot_wbck = 0;
|
||||
for (srv = px->srv; srv != NULL; srv = srv->next) {
|
||||
if (srv->state & SRV_RUNNING) {
|
||||
if (srv->state & SRV_BACKUP)
|
||||
if (srv->state & SRV_BACKUP) {
|
||||
px->srv_bck++;
|
||||
else
|
||||
px->tot_wbck += srv->eweight + 1;
|
||||
} else {
|
||||
px->srv_act++;
|
||||
px->tot_wact += srv->eweight + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* This function recomputes the server map for proxy px. It
|
||||
* relies on px->tot_wact and px->tot_wbck, so it must be
|
||||
* called after recount_servers(). It also expects px->srv_map
|
||||
* to be initialized to the largest value needed.
|
||||
*/
|
||||
static void recalc_server_map(struct proxy *px) {
|
||||
int o, tot, flag;
|
||||
struct server *cur, *best;
|
||||
|
||||
if (px->srv_act) {
|
||||
flag = SRV_RUNNING;
|
||||
tot = px->tot_wact;
|
||||
} else if (px->srv_bck) {
|
||||
flag = SRV_RUNNING | SRV_BACKUP;
|
||||
if (px->options & PR_O_USE_ALL_BK)
|
||||
tot = px->tot_wbck;
|
||||
else
|
||||
tot = 1; /* the first server is enough */
|
||||
} else {
|
||||
px->srv_map_sz = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/* this algorithm gives priority to the first server, which means that
|
||||
* it will respect the declaration order for equivalent weights, and
|
||||
* that whatever the weights, the first server called will always be
|
||||
* the first declard. This is an important asumption for the backup
|
||||
* case, where we want the first server only.
|
||||
*/
|
||||
for (cur = px->srv; cur; cur = cur->next)
|
||||
cur->wscore = 0;
|
||||
|
||||
for (o = 0; o < tot; o++) {
|
||||
int max = 0;
|
||||
best = NULL;
|
||||
for (cur = px->srv; cur; cur = cur->next) {
|
||||
if ((cur->state & (SRV_RUNNING | SRV_BACKUP)) == flag) {
|
||||
int v;
|
||||
|
||||
/* If we are forced to return only one server, we don't want to
|
||||
* go further, because we would return the wrong one due to
|
||||
* divide overflow.
|
||||
*/
|
||||
if (tot == 1) {
|
||||
best = cur;
|
||||
break;
|
||||
}
|
||||
|
||||
cur->wscore += cur->eweight + 1;
|
||||
v = (cur->wscore + tot) / tot; /* result between 0 and 3 */
|
||||
if (best == NULL || v > max) {
|
||||
max = v;
|
||||
best = cur;
|
||||
}
|
||||
}
|
||||
}
|
||||
px->srv_map[o] = best;
|
||||
best->wscore -= tot;
|
||||
}
|
||||
px->srv_map_sz = tot;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function tries to find a running server for the proxy <px> following
|
||||
* the round-robin method. Depending on the number of active/backup servers,
|
||||
* it will either look for active servers, or for backup servers.
|
||||
* If any server is found, it will be returned and px->cursrv will be updated
|
||||
* If any server is found, it will be returned and px->srv_rr_idx will be updated
|
||||
* to point to the next server. If no valid server is found, NULL is returned.
|
||||
*/
|
||||
static inline struct server *get_server_rr(struct proxy *px) {
|
||||
struct server *srv;
|
||||
struct server *end;
|
||||
if (px->srv_map_sz == 0)
|
||||
return NULL;
|
||||
|
||||
if (px->srv_act) {
|
||||
srv = px->cursrv;
|
||||
if (srv == NULL)
|
||||
srv = px->srv;
|
||||
end = srv;
|
||||
do {
|
||||
if ((srv->state & (SRV_RUNNING | SRV_BACKUP)) == SRV_RUNNING) {
|
||||
px->cursrv = srv->next;
|
||||
return srv;
|
||||
}
|
||||
|
||||
srv = srv->next;
|
||||
if (srv == NULL)
|
||||
srv = px->srv;
|
||||
} while (srv != end);
|
||||
/* note that theorically we should not get there */
|
||||
}
|
||||
|
||||
if (px->srv_bck) {
|
||||
/* By default, we look for the first backup server if all others are
|
||||
* DOWN. But in some cases, it may be desirable to load-balance across
|
||||
* all backup servers.
|
||||
*/
|
||||
if (px->options & PR_O_USE_ALL_BK)
|
||||
srv = px->cursrv;
|
||||
else
|
||||
srv = px->srv;
|
||||
|
||||
if (srv == NULL)
|
||||
srv = px->srv;
|
||||
end = srv;
|
||||
do {
|
||||
if (srv->state & SRV_RUNNING) {
|
||||
px->cursrv = srv->next;
|
||||
return srv;
|
||||
}
|
||||
srv = srv->next;
|
||||
if (srv == NULL)
|
||||
srv = px->srv;
|
||||
} while (srv != end);
|
||||
/* note that theorically we should not get there */
|
||||
}
|
||||
|
||||
/* if we get there, it means there are no available servers at all */
|
||||
return NULL;
|
||||
if (px->srv_rr_idx < 0 || px->srv_rr_idx >= px->srv_map_sz)
|
||||
px->srv_rr_idx = 0;
|
||||
return px->srv_map[px->srv_rr_idx++];
|
||||
}
|
||||
|
||||
|
||||
@ -1889,58 +1919,20 @@ static inline struct server *get_server_rr(struct proxy *px) {
|
||||
* NULL is returned.
|
||||
*/
|
||||
static inline struct server *get_server_sh(struct proxy *px, char *addr, int len) {
|
||||
struct server *srv;
|
||||
unsigned int h, l;
|
||||
|
||||
if (px->srv_act) {
|
||||
unsigned int h, l;
|
||||
if (px->srv_map_sz == 0)
|
||||
return NULL;
|
||||
|
||||
l = h = 0;
|
||||
if (px->srv_act > 1) {
|
||||
while ((l + sizeof (int)) <= len) {
|
||||
h ^= ntohl(*(unsigned int *)(&addr[l]));
|
||||
l += sizeof (int);
|
||||
}
|
||||
h %= px->srv_act;
|
||||
}
|
||||
|
||||
for (srv = px->srv; srv; srv = srv->next) {
|
||||
if ((srv->state & (SRV_RUNNING | SRV_BACKUP)) == SRV_RUNNING) {
|
||||
if (!h)
|
||||
return srv;
|
||||
h--;
|
||||
}
|
||||
l = h = 0;
|
||||
if (px->srv_act > 1) {
|
||||
while ((l + sizeof (int)) <= len) {
|
||||
h ^= ntohl(*(unsigned int *)(&addr[l]));
|
||||
l += sizeof (int);
|
||||
}
|
||||
/* note that theorically we should not get there */
|
||||
h %= px->srv_map_sz;
|
||||
}
|
||||
|
||||
if (px->srv_bck) {
|
||||
unsigned int h, l;
|
||||
|
||||
/* By default, we look for the first backup server if all others are
|
||||
* DOWN. But in some cases, it may be desirable to load-balance across
|
||||
* all backup servers.
|
||||
*/
|
||||
l = h = 0;
|
||||
if (px->srv_bck > 1 && px->options & PR_O_USE_ALL_BK) {
|
||||
while ((l + sizeof (int)) <= len) {
|
||||
h ^= ntohl(*(unsigned int *)(&addr[l]));
|
||||
l += sizeof (int);
|
||||
}
|
||||
h %= px->srv_bck;
|
||||
}
|
||||
|
||||
for (srv = px->srv; srv; srv = srv->next) {
|
||||
if (srv->state & SRV_RUNNING) {
|
||||
if (!h)
|
||||
return srv;
|
||||
h--;
|
||||
}
|
||||
}
|
||||
/* note that theorically we should not get there */
|
||||
}
|
||||
|
||||
/* if we get there, it means there are no available servers at all */
|
||||
return NULL;
|
||||
return px->srv_map[h];
|
||||
}
|
||||
|
||||
|
||||
@ -3311,6 +3303,32 @@ int process_cli(struct session *t) {
|
||||
|
||||
if (ptr == req->h) { /* empty line, end of headers */
|
||||
int line, len;
|
||||
|
||||
/*
|
||||
* first, let's check that it's not a leading empty line, in
|
||||
* which case we'll ignore and remove it (according to RFC2616).
|
||||
*/
|
||||
if (req->h == req->data) {
|
||||
/* to get a complete header line, we need the ending \r\n, \n\r, \r or \n too */
|
||||
if (ptr > req->r - 2) {
|
||||
/* this is a partial header, let's wait for more to come */
|
||||
req->lr = ptr;
|
||||
break;
|
||||
}
|
||||
|
||||
/* now we know that *ptr is either \r or \n,
|
||||
* and that there are at least 1 char after it.
|
||||
*/
|
||||
if ((ptr[0] == ptr[1]) || (ptr[1] != '\r' && ptr[1] != '\n'))
|
||||
req->lr = ptr + 1; /* \r\r, \n\n, \r[^\n], \n[^\r] */
|
||||
else
|
||||
req->lr = ptr + 2; /* \r\n or \n\r */
|
||||
/* ignore empty leading lines */
|
||||
buffer_replace2(req, req->h, req->lr, NULL, 0);
|
||||
req->h = req->lr;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* we can only get here after an end of headers */
|
||||
/* we'll have something else to do here : add new headers ... */
|
||||
|
||||
@ -5310,6 +5328,7 @@ int process_chk(struct task *t) {
|
||||
s->state &= ~SRV_RUNNING;
|
||||
if (s->health == s->rise) {
|
||||
recount_servers(s->proxy);
|
||||
recalc_server_map(s->proxy);
|
||||
Warning("%sServer %s/%s DOWN. %d active and %d backup servers left.%s\n",
|
||||
s->state & SRV_BACKUP ? "Backup " : "",
|
||||
s->proxy->id, s->id, s->proxy->srv_act, s->proxy->srv_bck,
|
||||
@ -5345,6 +5364,7 @@ int process_chk(struct task *t) {
|
||||
|
||||
if (s->health == s->rise) {
|
||||
recount_servers(s->proxy);
|
||||
recalc_server_map(s->proxy);
|
||||
Warning("%sServer %s/%s UP. %d active and %d backup servers online.%s\n",
|
||||
s->state & SRV_BACKUP ? "Backup " : "",
|
||||
s->proxy->id, s->id, s->proxy->srv_act, s->proxy->srv_bck,
|
||||
@ -5375,6 +5395,7 @@ int process_chk(struct task *t) {
|
||||
|
||||
if (s->health == s->rise) {
|
||||
recount_servers(s->proxy);
|
||||
recalc_server_map(s->proxy);
|
||||
Warning("%sServer %s/%s DOWN. %d active and %d backup servers left.%s\n",
|
||||
s->state & SRV_BACKUP ? "Backup " : "",
|
||||
s->proxy->id, s->id, s->proxy->srv_act, s->proxy->srv_bck,
|
||||
@ -6980,13 +7001,9 @@ int cfg_parse_listen(char *file, int linenum, char **args) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (curproxy->srv == NULL)
|
||||
curproxy->srv = newsrv;
|
||||
else
|
||||
curproxy->cursrv->next = newsrv;
|
||||
curproxy->cursrv = newsrv;
|
||||
|
||||
newsrv->next = NULL;
|
||||
/* the servers are linked backwards first */
|
||||
newsrv->next = curproxy->srv;
|
||||
curproxy->srv = newsrv;
|
||||
newsrv->proxy = curproxy;
|
||||
|
||||
do_check = 0;
|
||||
@ -7049,6 +7066,17 @@ int cfg_parse_listen(char *file, int linenum, char **args) {
|
||||
newsrv->state |= SRV_BACKUP;
|
||||
cur_arg ++;
|
||||
}
|
||||
else if (!strcmp(args[cur_arg], "weight")) {
|
||||
int w;
|
||||
w = atol(args[cur_arg + 1]);
|
||||
if (w < 1 || w > 256) {
|
||||
Alert("parsing [%s:%d] : weight of server %s is not within 1 and 256 (%d).\n",
|
||||
file, linenum, newsrv->id, w);
|
||||
return -1;
|
||||
}
|
||||
newsrv->uweight = w - 1;
|
||||
cur_arg += 2;
|
||||
}
|
||||
else if (!strcmp(args[cur_arg], "check")) {
|
||||
global.maxsock++;
|
||||
do_check = 1;
|
||||
@ -7065,7 +7093,7 @@ int cfg_parse_listen(char *file, int linenum, char **args) {
|
||||
cur_arg += 2;
|
||||
}
|
||||
else {
|
||||
Alert("parsing [%s:%d] : server %s only supports options 'backup', 'cookie', 'check', 'inter', 'rise', 'fall', 'port' and 'source'.\n",
|
||||
Alert("parsing [%s:%d] : server %s only supports options 'backup', 'cookie', 'check', 'inter', 'rise', 'fall', 'port', 'source', and 'weight'.\n",
|
||||
file, linenum, newsrv->id);
|
||||
return -1;
|
||||
}
|
||||
@ -7789,7 +7817,6 @@ int readcfgfile(char *file) {
|
||||
}
|
||||
|
||||
while (curproxy != NULL) {
|
||||
curproxy->cursrv = NULL;
|
||||
if (curproxy->state == PR_STSTOPPED) {
|
||||
curproxy = curproxy->next;
|
||||
continue;
|
||||
@ -7846,12 +7873,59 @@ int readcfgfile(char *file) {
|
||||
file, curproxy->id);
|
||||
cfgerr++;
|
||||
}
|
||||
else {
|
||||
while (newsrv != NULL) {
|
||||
/* nothing to check for now */
|
||||
newsrv = newsrv->next;
|
||||
}
|
||||
}
|
||||
|
||||
/* first, we will invert the servers list order */
|
||||
newsrv = NULL;
|
||||
while (curproxy->srv) {
|
||||
struct server *next;
|
||||
|
||||
next = curproxy->srv->next;
|
||||
curproxy->srv->next = newsrv;
|
||||
newsrv = curproxy->srv;
|
||||
if (!next)
|
||||
break;
|
||||
curproxy->srv = next;
|
||||
}
|
||||
|
||||
/* now, newsrv == curproxy->srv */
|
||||
if (newsrv) {
|
||||
struct server *srv;
|
||||
int pgcd;
|
||||
int act, bck;
|
||||
|
||||
/* We will factor the weights to reduce the table,
|
||||
* using Euclide's largest common divisor algorithm
|
||||
*/
|
||||
pgcd = newsrv->uweight + 1;
|
||||
for (srv = newsrv->next; srv && pgcd > 1; srv = srv->next) {
|
||||
int t, w;
|
||||
|
||||
w = srv->uweight + 1;
|
||||
while (w) {
|
||||
t = pgcd % w;
|
||||
pgcd = w;
|
||||
w = t;
|
||||
}
|
||||
}
|
||||
|
||||
act = bck = 0;
|
||||
for (srv = newsrv; srv; srv = srv->next) {
|
||||
srv->eweight = ((srv->uweight + 1) / pgcd) - 1;
|
||||
if (srv->state & SRV_BACKUP)
|
||||
bck += srv->eweight + 1;
|
||||
else
|
||||
act += srv->eweight + 1;
|
||||
}
|
||||
|
||||
/* this is the largest map we will ever need for this servers list */
|
||||
if (act < bck)
|
||||
act = bck;
|
||||
|
||||
curproxy->srv_map = (struct server **)calloc(act, sizeof(struct server *));
|
||||
/* recounts servers and their weights */
|
||||
recount_servers(curproxy);
|
||||
recalc_server_map(curproxy);
|
||||
}
|
||||
|
||||
if (curproxy->options & PR_O_LOGASAP)
|
||||
@ -8048,12 +8122,6 @@ void init(int argc, char **argv) {
|
||||
arg_mode |= MODE_DAEMON | MODE_QUIET;
|
||||
else if (*flag == 'q')
|
||||
arg_mode |= MODE_QUIET;
|
||||
#if STATTIME > 0
|
||||
else if (*flag == 's')
|
||||
arg_mode |= MODE_STATS;
|
||||
else if (*flag == 'l')
|
||||
arg_mode |= MODE_LOG;
|
||||
#endif
|
||||
else if (*flag == 's' && (flag[1] == 'f' || flag[1] == 't')) {
|
||||
/* list of pids to finish ('f') or terminate ('t') */
|
||||
|
||||
@ -8074,6 +8142,12 @@ void init(int argc, char **argv) {
|
||||
}
|
||||
}
|
||||
}
|
||||
#if STATTIME > 0
|
||||
else if (*flag == 's')
|
||||
arg_mode |= MODE_STATS;
|
||||
else if (*flag == 'l')
|
||||
arg_mode |= MODE_LOG;
|
||||
#endif
|
||||
else { /* >=2 args */
|
||||
argv++; argc--;
|
||||
if (argc == 0)
|
||||
|
Loading…
x
Reference in New Issue
Block a user