* released 1.1.16

* implement HTTP health checks when option "httpchk" is specified.
* put the changelog into a new CHANGELOG file
* updated the Formilux init script
This commit is contained in:
willy tarreau 2005-12-17 13:32:07 +01:00
parent e867b4881f
commit bc4e1fb68a
7 changed files with 232 additions and 19 deletions

130
CHANGELOG Normal file
View File

@ -0,0 +1,130 @@
* ChangeLog :
*
* 2002/09/01 : 1.1.16
* - implement HTTP health checks when option "httpchk" is specified.
* 2002/08/07 : 1.1.15
* - replaced setpgid()/setpgrp() with setsid() for better portability, because
* setpgrp() doesn't have the same meaning under Solaris, Linux, and OpenBSD.
* 2002/07/20 : 1.1.14
* - added "postonly" cookie mode
* 2002/07/15 : 1.1.13
* - tv_diff used inverted parameters which led to negative times !
* 2002/07/13 : 1.1.12
* - fixed stats monitoring, and optimized some tv_* for most common cases.
* - replaced temporary 'newhdr' with 'trash' to reduce stack size
* - made HTTP errors more HTML-fiendly.
* - renamed strlcpy() to strlcpy2() because of a slightly difference between
* their behaviour (return value), to avoid confusion.
* - restricted HTTP messages to HTTP proxies only
* - added a 502 message when the connection has been refused by the server,
* to prevent clients from believing this is a zero-byte HTTP 0.9 reply.
* - changed 'Cache-control:' from 'no-cache="set-cookie"' to 'private' when
* inserting a cookie, because some caches (apache) don't understand it.
* - fixed processing of server headers when client is in SHUTR state
* 2002/07/04 :
* - automatically close fd's 0,1 and 2 when going daemon ; setpgrp() after
* setpgid()
* 2002/06/04 : 1.1.11
* - fixed multi-cookie handling in client request to allow clean deletion
* in insert+indirect mode. Now, only the server cookie is deleted and not
* all the header. Should now be compliant to RFC2109.
* - added a "nocache" option to "cookie" to specify that we explicitly want
* to add a "cache-control" header when we add a cookie.
* It is also possible to add an "Expires: <old-date>" to keep compatibility
* with old/broken caches.
* 2002/05/10 : 1.1.10
* - if a cookie is used in insert+indirect mode, it's desirable that the
* the servers don't see it. It was not possible to remove it correctly
* with regexps, so now it's removed automatically.
* 2002/04/19 : 1.1.9
* - don't use snprintf()'s return value as an end of message since it may
* be larger. This caused bus errors and segfaults in internal libc's
* getenv() during localtime() in send_log().
* - removed dead insecure send_syslog() function and all references to it.
* - fixed warnings on Solaris due to buggy implementation of isXXXX().
* 2002/04/18 : 1.1.8
* - option "dontlognull"
* - fixed "double space" bug in config parser
* - fixed an uninitialized server field in case of dispatch
* with no existing server which could cause a segfault during
* logging.
* - the pid logged was always the father's, which was wrong for daemons.
* - fixed wrong level "LOG_INFO" for message "proxy started".
* 2002/04/13 :
* - http logging is now complete :
* - ip:port, date, proxy, server
* - req_time, conn_time, hdr_time, tot_time
* - status, size, request
* - source address
* 2002/04/12 : 1.1.7
* - added option forwardfor
* - added reqirep, reqidel, reqiallow, reqideny, rspirep, rspidel
* - added "log global" in "listen" section.
* 2002/04/09 :
* - added a new "global" section :
* - logs
* - debug, quiet, daemon modes
* - uid, gid, chroot, nbproc, maxconn
* 2002/04/08 : 1.1.6
* - regex are now chained and not limited anymore.
* - unavailable server now returns HTTP/502.
* - increased per-line args limit to 40
* - added reqallow/reqdeny to block some request on matches
* - added HTTP 400/403 responses
* 2002/04/03 : 1.1.5
* - connection logging displayed incorrect source address.
* - added proxy start/stop and server up/down log events.
* - replaced log message short buffers with larger trash.
* - enlarged buffer to 8 kB and replace buffer to 4 kB.
* 2002/03/25 : 1.1.4
* - made rise/fall/interval time configurable
* 2002/03/22 : 1.1.3
* - fixed a bug : cr_expire and cw_expire were inverted in CL_STSHUT[WR]
* which could lead to loops.
* 2002/03/21 : 1.1.2
* - fixed a bug in buffer management where we could have a loop
* between event_read() and process_{cli|srv} if R==BUFSIZE-MAXREWRITE.
* => implemented an adjustable buffer limit.
* - fixed a bug : expiration of tasks in wait queue timeout is used again,
* and running tasks are skipped.
* - added some debug lines for accept events.
* - send warnings for servers up/down.
* 2002/03/12 : 1.1.1
* - fixed a bug in total failure handling
* - fixed a bug in timestamp comparison within same second (tv_cmp_ms)
* 2002/03/10 : 1.1.0
* - fixed a few timeout bugs
* - rearranged the task scheduler subsystem to improve performance,
* add new tasks, and make it easier to later port to librt ;
* - allow multiple accept() for one select() wake up ;
* - implemented internal load balancing with basic health-check ;
* - cookie insertion and header add/replace/delete, with better strings
* support.
* 2002/03/08
* - reworked buffer handling to fix a few rewrite bugs, and
* improve overall performance.
* - implement the "purge" option to delete server cookies in direct mode.
* 2002/03/07
* - fixed some error cases where the maxfd was not decreased.
* 2002/02/26
* - now supports transparent proxying, at least on linux 2.4.
* 2002/02/12
* - soft stop works again (fixed select timeout computation).
* - it seems that TCP proxies sometimes cannot timeout.
* - added a "quiet" mode.
* - enforce file descriptor limitation on socket() and accept().
* 2001/12/30 : release of version 1.0.2 : fixed a bug in header processing
* 2001/12/19 : release of version 1.0.1 : no MSG_NOSIGNAL on solaris
* 2001/12/16 : release of version 1.0.0.
* 2001/12/16 : added syslog capability for each accepted connection.
* 2001/11/19 : corrected premature end of files and occasional SIGPIPE.
* 2001/10/31 : added health-check type servers (mode health) which replies OK then closes.
* 2001/10/30 : added the ability to support standard TCP proxies and HTTP proxies
* with or without cookies (use keyword http for this).
* 2001/09/01 : added client/server header replacing with regexps.
* eg:
* cliexp ^(Host:\ [^:]*).* Host:\ \1:80
* srvexp ^Server:\ .* Server:\ Apache
* 2000/11/29 : first fully working release with complete FSMs and timeouts.
* 2000/11/28 : major rewrite
* 2000/11/26 : first write

2
TODO
View File

@ -22,7 +22,7 @@
matchée dans la "session" pour accélérer les regex.
- gestion keep-alive
- handle parametrable HTTP health-checks replies
+ handle parametrable HTTP health-checks replies
- differentiate http headers and http uris
- support environment variables in config file
- support keep-alive

View File

@ -1,9 +1,9 @@
H A - P r o x y
---------------
version 1.1.14
version 1.1.16
willy tarreau
2002/07/20
2002/09/01
================
| Introduction |
@ -556,10 +556,9 @@ Exemple : m
3.1) Surveillance des serveurs
------------------------------
A cette date, l'état des serveurs n'est testé que par établissement de connexion
TCP toutes les 2 secondes, avec 3 essais pour déclarer un serveur en panne, 2
pour le déclarer utilisable. Un serveur hors d'usage ne sera pas utilisé dans le
processus de répartition de charge interne. Pour activer la surveillance,
Il est possible de tester l'état des serveurs par établissement de connexion TCP
ou par envoi d'une requête HTTP. Un serveur hors d'usage ne sera pas utilisé
dans leprocessus de répartition de charge interne. Pour activer la surveillance,
ajouter le mot clé 'check' à la fin de la déclaration du serveur. Il est
possible de spécifier l'intervalle (en millisecondes) séparant deux tests du
serveur par le paramètre "inter", le nombre d'échecs acceptés par le paramètre
@ -569,9 +568,19 @@ param
- rise : 2
- fall : 3
Le mode par défaut consiste à établir des connexions TCP uniquement. Dans
certains cas de pannes, des serveurs peuvent continuer à accepter les connexions
sans les traiter. Depuis la version 1.1.16, haproxy est en mesure d'envoyer des
requêtes HTTP courtes et très peu coûteuses : "OPTIONS / HTTP/1.0". Elles
présentent l'avantage d'être facilement extractibles des logs, et de ne pas
induire d'accès aux fichiers côté serveur. Seules les réponses 2xx et 3xx sont
considérées valides, les autres (y compris non-réponses) aboutissent à un échec.
Le temps maximal imparti pour une réponse est égal à l'intervalle entre deux
tests (paramètre "inter"). Pour activer ce mode, spécifier l'option "httpchk".
Exemples :
----------
# même que précédemment avec surveillance
# même que précédemment avec surveillance TCP
listen http_proxy 0.0.0.0:80
mode http
cookie SERVERID
@ -579,6 +588,15 @@ Exemples :
server web1 192.168.1.1:80 cookie server01 check
server web2 192.168.1.2:80 cookie server02 check inter 500 rise 1 fall 2
# même que précédemment avec surveillance HTTP
listen http_proxy 0.0.0.0:80
mode http
cookie SERVERID
balance roundrobin
option httpchk
server web1 192.168.1.1:80 cookie server01 check
server web2 192.168.1.2:80 cookie server02 check inter 500 rise 1 fall 2
# Insertion automatique de cookie dans la réponse du serveur, et suppression
# automatique dans la requête, tout en indiquant aux caches de ne pas garder
# ce cookie.

View File

@ -23,7 +23,9 @@ listen proxy1 0.0.0.0:8000
#dispatch 127.0.0.1:31300
#dispatch 127.0.0.1:80
#dispatch 127.0.0.1:22
server nc 127.0.0.1:8080 cookie cookie1 check
option httpchk
server test 10.1.1.2:80 cookie cookie1 check inter 300
# server nc 127.0.0.1:8080 cookie cookie1 check inter 300
# server tuxlocal0 10.101.23.9:80 cookie cookie1 check
# server tuxlocal1 127.0.0.1:80 cookie cookie1 check
# server tuxlocal2 127.0.0.1:80 cookie cookie2 check

View File

@ -31,6 +31,7 @@ listen appli2-insert 0.0.0.0:10002
mode http
option httplog
option dontlognull
option httpchk
balance roundrobin
cookie SERVERID insert indirect nocache
server inst1 192.168.114.56:80 cookie server01 check inter 2000 fall 3

View File

@ -18,6 +18,8 @@
*
* ChangeLog :
*
* 2002/09/01 : 1.1.16
* - implement HTTP health checks when option "httpchk" is specified.
* 2002/08/07 : 1.1.15
* - replaced setpgid()/setpgrp() with setsid() for better portability, because
* setpgrp() doesn't have the same meaning under Solaris, Linux, and OpenBSD.
@ -147,7 +149,6 @@
*
* TODO:
* - handle properly intermediate incomplete server headers. Done ?
* - log proxies start/stop
* - handle hot-reconfiguration
*
*/
@ -176,8 +177,8 @@
#include <linux/netfilter_ipv4.h>
#endif
#define HAPROXY_VERSION "1.1.15"
#define HAPROXY_DATE "2002/08/07"
#define HAPROXY_VERSION "1.1.16"
#define HAPROXY_DATE "2002/09/01"
/* this is for libc5 for example */
#ifndef TCP_NODELAY
@ -342,6 +343,7 @@ int strlcpy2(char *dst, const char *src, int size) {
#define PR_O_NULLNOLOG 512 /* a connect without request will not be logged */
#define PR_O_COOK_NOC 1024 /* add a 'Cache-control' header with the cookie */
#define PR_O_COOK_POST 2048 /* don't insert cookies for requests other than a POST */
#define PR_O_HTTP_CHK 4096 /* use HTTP 'OPTIONS' method to check server health */
/* various session flags */
@ -2061,10 +2063,11 @@ int event_accept(int fd) {
/*
* This function is used only for server health-checks. It handles
* the connection acknowledgement and returns 1 if the socket is OK,
* the connection acknowledgement. If the proxy requires HTTP health-checks,
* it sends the request. In other cases, it returns 1 if the socket is OK,
* or -1 if an error occured.
*/
int event_srv_hck(int fd) {
int event_srv_chk_w(int fd) {
struct task *t = fdtab[fd].owner;
struct server *s = t->context;
@ -2073,14 +2076,69 @@ int event_srv_hck(int fd) {
getsockopt(fd, SOL_SOCKET, SO_ERROR, &skerr, &lskerr);
if (skerr)
s->result = -1;
else {
if (s->proxy->options & PR_O_HTTP_CHK) {
int ret;
/* we want to check if this host replies to "OPTIONS / HTTP/1.0"
* so we'll send the request, and won't wake the checker up now.
*/
#ifndef MSG_NOSIGNAL
ret = send(fd, "OPTIONS / HTTP/1.0\r\n\r\n", 22, MSG_DONTWAIT);
#else
ret = send(fd, "OPTIONS / HTTP/1.0\r\n\r\n", 22, MSG_DONTWAIT | MSG_NOSIGNAL);
#endif
if (ret == 22) {
FD_SET(fd, StaticReadEvent); /* prepare for reading reply */
FD_CLR(fd, StaticWriteEvent); /* nothing more to write */
return 0;
}
else
s->result = -1;
}
else {
/* good TCP connection is enough */
s->result = 1;
}
}
task_wakeup(&rq, t);
return 0;
}
/*
* This function is used only for server health-checks. It handles
* the server's reply to an HTTP request. It returns 1 if the server replies
* 2xx or 3xx (valid responses), or -1 in other cases.
*/
int event_srv_chk_r(int fd) {
char reply[64];
int len;
struct task *t = fdtab[fd].owner;
struct server *s = t->context;
int skerr, lskerr;
lskerr = sizeof(skerr);
getsockopt(fd, SOL_SOCKET, SO_ERROR, &skerr, &lskerr);
s->result = -1;
if (!skerr) {
#ifndef MSG_NOSIGNAL
len = recv(fd, reply, sizeof(reply), 0);
#else
len = recv(fd, reply, sizeof(reply), MSG_NOSIGNAL);
#endif
if ((len >= sizeof("HTTP/1.0 000")) &&
!memcmp(reply, "HTTP/1.", 7) &&
(reply[9] == '2' || reply[9] == '3')) /* 2xx or 3xx */
s->result = 1;
}
FD_CLR(fd, StaticReadEvent);
task_wakeup(&rq, t);
return 0;
}
/*
* this function writes the string <str> at position <pos> which must be in buffer <b>,
* and moves <end> just after the end of <str>.
@ -3277,8 +3335,8 @@ int process_chk(struct task *t) {
s->curfd = fd; /* that's how we know a test is in progress ;-) */
fdtab[fd].owner = t;
fdtab[fd].read = NULL;
fdtab[fd].write = &event_srv_hck;
fdtab[fd].read = &event_srv_chk_r;
fdtab[fd].write = &event_srv_chk_w;
fdtab[fd].state = FD_STCONN; /* connection in progress */
FD_SET(fd, StaticWriteEvent); /* for connect status */
fd_insert(fd);
@ -3981,6 +4039,10 @@ int cfg_parse_listen(char *file, int linenum, char **args) {
/* don't log empty requests */
curproxy->options |= PR_O_NULLNOLOG;
}
else if (!strcmp(args[1], "httpchk")) {
/* use HTTP request to check servers' health */
curproxy->options |= PR_O_HTTP_CHK;
}
else {
Alert("parsing [%s:%d] : unknown option <%s>.\n", file, linenum, args[1]);
return -1;

View File

@ -31,7 +31,7 @@ ulimit -n $maxfd
# ulimit -c unlimited
# soft stop
function dostop {
function do_stop {
pids=`pidof -o $$ -- $PNAME`
if [ ! -z "$pids" ]; then
echo "Asking $PNAME to terminate gracefully..."