[DOC] update documentation to explain the server's maxconn

This commit is contained in:
willy tarreau 2006-05-13 18:40:37 +02:00
parent 5f15c5517a
commit 532bb554aa
2 changed files with 373 additions and 163 deletions

View File

@ -2,9 +2,9 @@
H A - P r o x y
Reference Manual
-------------------
version 1.2.12
version 1.2.13
willy tarreau
2006/04/15
2006/05/13
============
| Abstract |
@ -20,6 +20,8 @@ availability environments. Indeed, it can :
- stop accepting connections without breaking existing ones ;
- add/modify/delete HTTP headers both ways ;
- block requests matching a particular pattern ;
- hold clients to the right application server depending on application
cookies
It needs very little resource. Its event-driven architecture allows it to easily
handle thousands of simultaneous connections on hundreds of instances without
@ -33,7 +35,9 @@ There are only a few command line options :
-f <configuration file>
-n <high limit for the total number of simultaneous connections>
-N <high limit for the per-proxy number of simultaneous connections>
= 'maxconn' in 'global' section
-N <high limit for the per-listener number of simultaneous connections>
= 'maxconn' in 'listen' or 'default' sections
-d starts in foregreound with debugging mode enabled
-D starts in daemon mode
-q disable messages on output
@ -51,8 +55,9 @@ There are only a few command line options :
-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.
The maximal number of connections per proxy instance is used as the default
parameter for each instance for which the 'maxconn' paramter is not set in the
'listen' section.
The maximal number of total connections limits the number of connections used by
the whole process if the 'maxconn' parameter is not set in the 'global' section.
@ -69,16 +74,7 @@ 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)
The '-st' and '-sf' options are used for hot reconfiguration (see below).
======================
| Configuration file |
@ -416,7 +412,7 @@ Note: the 'enabled' keyword allows to enable a service which has been disabled
A service can work in 3 different distinct modes :
- TCP
- HTTP
- monitoring
- health
TCP mode
--------
@ -463,8 +459,8 @@ Example :
mode health
option httpchk
Monitoring
----------
2.2.1 Monitoring
----------------
Versions 1.1.32 and 1.2.6 provide a new solution to check the proxy's
availability without perturbating the service. The 'monitor-net' keyword was
created to specify a network of equipments which CANNOT use the service for
@ -553,7 +549,21 @@ 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).
(see below).
2.4.1) Hot reconfiguration
--------------------------
The '-st' and '-sf' command line 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)
2.5) Connections expiration time
--------------------------------
@ -769,23 +779,32 @@ The server's response is searched for 'appsession' cookie, the first
'timeout'.
The syntax is:
appsession <SESSIONCOOKIE> len <MATCHLENGTH> timeout <HOLDTIME>
appsession <session_cookie> len <match_length> timeout <holdtime>
- <SESSIONCOOKIE> is the cookie, the server uses for it's session-handling
- <MATCHLENGTH> how many bytes/characters should be used for matching equal
- <session_cookie> is the cookie, the server uses for it's session-handling
- <match_length> how many bytes/characters should be used for matching equal
sessions
- <HOLDTIME> after this inactivaty time, in ms, the cookie will be deleted
- <holdtime> after this inactivaty time, in ms, the cookie will be deleted
from the sessionstore
The appsession is only per 'listen' section possible.
Example :
---------
listen http_proxy :80
mode http
appsession JSESSIONID len 52 timeout 300000
.
.
listen http_lb1 192.168.3.4:80
mode http
capture request header Cookie len 200
# Havind a ServerID cookie on the client allows him to reach
# the right server even after expiration of the appsession.
cookie ServerID insert nocache indirect
# Will memorize 52 bytes of the cookie 'JSESSIONID' and keep them
# for 3 hours. It will match it in the cookie and the URL field.
appsession JSESSIONID len 52 timeout 10800000
server first1 10.3.9.2:10805 check inter 3000 cookie first
server secon1 10.3.9.3:10805 check inter 3000 cookie secon
server first1 10.3.9.4:10805 check inter 3000 cookie first
server secon2 10.3.9.5:10805 check inter 3000 cookie secon
option httpchk GET /test.jsp
3) Autonomous load balancer
@ -1104,10 +1123,10 @@ 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.
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. Weight 1 represents the lowest frequency and 256 the highest. This way,
if a server fails, the remaining capacities are still respected.
Example :
---------
@ -1142,6 +1161,71 @@ Notes :
server, so the map is the most uniform when servers are declared in
ascending order relative to their weights.
The load distribution will follow exactly this sequence :
Request| 1 1 1 1
number | 1 2 3 4 5 6 7 8 9 0 1 2 3
--------+---------------------------
p3-800 | X . . . . . . X . . . . .
opt-20 | . X . X . X . . . X . X .
opt-24 | . . X . X . X . X . X . X
3.4) Limiting the number of concurrent sessions on each server
--------------------------------------------------------------
Some pre-forked servers such as Apache suffer from too many concurrent
sessions, because it's very expensive to run hundreds or thousands of
processes on one system. One solution is to increase the number of servers
and load-balance between them, but it is a problem when the only goal is
to resist to short surges.
To solve this problem, a new feature was implemented in HAProxy 1.2.13.
It's a per-server 'maxconn', associated with a per-server and a per-proxy
queue. This transforms haproxy into a request buffer between the thousands of
clients and the few servers. On many circumstances, lowering the maxconn value
will increase the server's performance and decrease the overall response times
because the servers will be less congested.
When a request tries to reach any server, the first non-saturated server is
used, respective to the load balancing algorithm. If all servers are saturated,
then the request gets queued into the instance's global queue. It will be
dequeued once a server will have freed a session and all previously queued
requests have been processed.
If a request references a particular server (eg: source hashing, or persistence
cookie), and if this server is full, then the request will be queued into the
server's dedicated queue. This queue has higher priority than the global queue,
so it's easier for already registered users to enter the site than for new
users.
For this, the logs have been enhanced to show the number of sessions per
server, the request's position in the queue and the time spent in the queue.
This helps doing capacity planning. See the 'logs' section below for more info.
Example :
---------
# be nice with P3 which only has 256 MB of RAM.
listen web_appl 0.0.0.0:80
maxconn 10000
mode http
cookie SERVERID insert nocache indirect
balance roundrobin
server pentium3-800 192.168.1.1:80 cookie s1 weight 8 maxconn 100 check
server opteron-2.0G 192.168.1.2:80 cookie s2 weight 20 maxconn 300 check
server opteron-2.4G 192.168.1.3:80 cookie s3 weight 24 maxconn 300 check
server web-backup1 192.168.2.1:80 cookie s4 check maxconn 200 backup
server web-excuse 192.168.3.1:80 check backup
Notes :
-------
- The requests will not stay indefinitely in the queue, they follow the
'contimeout' parameter, and if a request cannot be dequeued within this
timeout because the server is saturated or because the queue is filled,
the session will expire with a 503 error.
- setting too low values for maxconn might improve performance but might also
allow slow users to block access to the server for other users.
4) Additionnal features
=======================
@ -1311,7 +1395,8 @@ By default, connections are logged at the TCP level, as soon as the session
establishes between the client and the proxy. By enabling the 'tcplog' option,
the proxy will wait until the session ends to generate an enhanced log
containing more information such as session duration and its state during the
disconnection.
disconnection. The number of remaining session after disconnection is also
indicated (for the server, the listener, and the process).
Example of TCP logging :
------------------------
@ -1320,19 +1405,20 @@ Example of TCP logging :
option tcplog
log 192.168.2.200 local3
>>> haproxy[18989]: 127.0.0.1:34550 [15/Oct/2003:15:24:28] relais-tcp Srv1 0/5007 0 -- 1/1
>>> haproxy[18989]: 127.0.0.1:34550 [15/Oct/2003:15:24:28] relais-tcp Srv1 0/0/5007 0 -- 1/1/1 0/0
Field Format Example
1 process_name '[' pid ']:' haproxy[18989]:
2 client_ip ':' client_port 127.0.0.1:34550
3 '[' date ']' [15/Oct/2003:15:24:28]
4 listener_name relais-tcp
5 server_name Srv1
6 connect_time '/' total_time 0/5007
7 bytes_read 0
8 termination_state --
9 listener_conns '/' process_conns 1/1
Field Format Example
1 process_name '[' pid ']:' haproxy[18989]:
2 client_ip ':' client_port 127.0.0.1:34550
3 '[' date ']' [15/Oct/2003:15:24:28]
4 listener_name relais-tcp
5 server_name Srv1
6 queue_time '/' connect_time '/' total_time 0/0/5007
7 bytes_read 0
8 termination_state --
9 srv_conn '/' listener_conn '/' process_conn 1/1/1
10 position in srv_queue / listener_queue 0/0
Another option, 'httplog', provides more detailed information about HTTP
@ -1350,28 +1436,29 @@ Example of HTTP logging :
option dontlognull
log 192.168.2.200 local3
>>> haproxy[674]: 127.0.0.1:33319 [15/Oct/2003:08:31:57] relais-http Srv1 9/7/147/723 200 243 - - ---- 3/3 "HEAD / HTTP/1.0"
>>> haproxy[674]: 127.0.0.1:33319 [15/Oct/2003:08:31:57] relais-http Srv1 9/0/7/147/723 200 243 - - ---- 2/3/3 0/0 "HEAD / HTTP/1.0"
More complete example
haproxy[18989]: 10.0.0.1:34552 [15/Oct/2003:15:26:31] relais-http Srv1 3183/-1/-1/11215 503 0 - - SC-- 202/205 {w.ods.org|Mozilla} {} "HEAD / HTTP/1.0"
haproxy[18989]: 10.0.0.1:34552 [15/Oct/2003:15:26:31] relais-http Srv1 3183/-1/-1/-1/11215 503 0 - - SC-- 137/202/205 0/0 {w.ods.org|Mozilla} {} "HEAD / HTTP/1.0"
Field Format Example
Field Format Example
1 process_name '[' pid ']:' haproxy[18989]:
2 client_ip ':' client_port 10.0.0.1:34552
3 '[' date ']' [15/Oct/2003:15:26:31]
4 listener_name relais-http
5 server_name Srv1
6 Tq '/' Tc '/' Tr '/' Tt 3183/-1/-1/11215
7 HTTP_return_code 503
8 bytes_read 0
9 captured_request_cookie -
10 captured_response_cookie -
11 termination_state SC--
12 listener_conns '/' process_conns 202/205
13 '{' captured_request_headers '}' {w.ods.org|Mozilla}
14 '{' captured_response_headers '}' {}
15 '"' HTTP_request '"' "HEAD / HTTP/1.0"
1 process_name '[' pid ']:' haproxy[18989]:
2 client_ip ':' client_port 10.0.0.1:34552
3 '[' date ']' [15/Oct/2003:15:26:31]
4 listener_name relais-http
5 server_name Srv1
6 Tq '/' Tw '/' Tc '/' Tr '/' Tt 3183/-1/-1/-1/11215
7 HTTP_return_code 503
8 bytes_read 0
9 captured_request_cookie -
10 captured_response_cookie -
11 termination_state SC--
12 srv_conn '/' listener_conn '/' process_conn 137/202/205
13 position in srv_queue / listener_queue 0/0
14 '{' captured_request_headers '}' {w.ods.org|Mozilla}
15 '{' captured_response_headers '}' {}
16 '"' HTTP_request '"' "HEAD / HTTP/1.0"
Note for log parsers: the URI is ALWAYS the end of the line starting with the
first double quote '"'.
@ -1399,19 +1486,25 @@ Example :
option logasap
log 192.168.2.200 local3
>>> haproxy[674]: 127.0.0.1:33320 [15/Oct/2003:08:32:17] relais-http Srv1 9/7/14/+30 200 +243 - - ---- 3/3 "GET /image.iso HTTP/1.0"
>>> haproxy[674]: 127.0.0.1:33320 [15/Oct/2003:08:32:17] relais-http Srv1 9/10/7/14/+30 200 +243 - - ---- 1/1/3 1/0 "GET /image.iso HTTP/1.0"
4.2.3) Timing events
--------------------
Timers provide a great help in trouble shooting network problems. All values
are reported in milliseconds (ms). In HTTP mode, four control points are
reported under the form 'Tq/Tc/Tr/Tt' :
reported under the form 'Tq/Tw/Tc/Tr/Tt' :
- Tq: total time to get the client request.
It's the time elapsed between the moment the client connection was accepted
and the moment the proxy received the last HTTP header. The value '-1'
indicates that the end of headers (empty line) has never been seen.
- Tw: total time spent in the queues waiting for a connection slot. It
accounts for listener's queue as well as the server's queue, and depends
on the queue size, and the time needed for the server to complete previous
sessions. The value '-1' means that the request was killed before reaching
the queue.
- Tc: total time to establish the TCP connection to the server.
It's the time elapsed between the moment the proxy sent the connection
request, and the moment it was acknowledged, or between the TCP SYN packet
@ -1426,15 +1519,15 @@ reported under the form 'Tq/Tc/Tr/Tt' :
- Tt: total session duration time, between the moment the proxy accepted it
and the moment both ends were closed. The exception is when the 'logasap'
option is specified. In this case, it only equals (Tq+Tc+Tr), and is
option is specified. In this case, it only equals (Tq+Tw+Tc+Tr), and is
prefixed with a '+' sign. From this field, we can deduce Td, the data
transmission time, by substracting other timers when valid :
Td = Tt - (Tq + Tc + Tr)
Td = Tt - (Tq + Tw + Tc + Tr)
Timers with '-1' values have to be excluded from this equation.
In TCP mode ('option tcplog'), only Tc and Tt are reported.
In TCP mode ('option tcplog'), only Tw, Tc and Tt are reported.
These timers provide precious indications on trouble causes. Since the TCP
protocol defines retransmit delays of 3, 6, 12... seconds, we know for sure
@ -1458,13 +1551,15 @@ Most common cases :
after the response ends. Se further for how to disable HTTP keep-alive.
Other cases ('xx' means any value to be ignored) :
-1/xx/xx/Tt : the client was not able to send its complete request in time,
or that it aborted it too early.
Tq/-1/xx/Tt : the connection could not establish on the server. Either it
refused it or it timed out after Tt-Tq ms.
Tq/Tc/-1/Tt : the server has accepted the connection but did not return a
complete response in time, or it closed its connexion
unexpectedly, after Tt-(Tq+Tc) ms.
-1/xx/xx/xx/Tt: the client was not able to send its complete request in time,
or that it aborted it too early.
Tq/-1/xx/xx/Tt: it was not possible to process the request, maybe because
servers were out of order.
Tq/Tw/-1/xx/Tt: the connection could not establish on the server. Either it
refused it or it timed out after Tt-(Tq+Tw) ms.
Tq/Tw/Tc/-1/Tt: the server has accepted the connection but did not return a
complete response in time, or it closed its connexion
unexpectedly, after Tt-(Tq+Tw+Tc) ms.
4.2.4) Session state at disconnection
-------------------------------------
@ -1506,6 +1601,10 @@ HTTP, each of which has a special meaning :
R : waiting for complete REQUEST from the client (HTTP only). Nothing
was sent to any server.
Q : waiting in the QUEUE for a connection slot. This can only happen on
servers which have a 'maxconn' parameter set. No connection attempt
was made to any server.
C : waiting for CONNECTION to establish on the server. The server might
at most have noticed a connection attempt.
@ -1715,50 +1814,54 @@ Example :
Log :
Aug 9 20:26:09 localhost haproxy[2022]: 127.0.0.1:34014 [09/Aug/2004:20:26:09] relais-http netcache 0/0/162/+162 200 +350 - - ---- {fr.adserver.yahoo.co||http://fr.f416.mail.} {|864|private||} "GET http://fr.adserver.yahoo.com/"
Aug 9 20:30:46 localhost haproxy[2022]: 127.0.0.1:34020 [09/Aug/2004:20:30:46] relais-http netcache 0/0/182/+182 200 +279 - - ---- {w.ods.org||} {Formilux/0.1.8|3495|||} "GET http://w.ods.org/sytadin.html HTTP/1.1"
Aug 9 20:30:46 localhost haproxy[2022]: 127.0.0.1:34028 [09/Aug/2004:20:30:46] relais-http netcache 0/2/126/+128 200 +223 - - ---- {www.infotrafic.com||http://w.ods.org/syt} {Apache/2.0.40 (Red H|9068|||} "GET http://www.infotrafic.com/images/live/cartesidf/grandes/idf_ne.png HTTP/1.1"
Aug 9 20:26:09 localhost haproxy[2022]: 127.0.0.1:34014 [09/Aug/2004:20:26:09] relais-http netcache 0/0/0/162/+162 200 +350 - - ---- 0/0/0 0/0 {fr.adserver.yahoo.co||http://fr.f416.mail.} {|864|private||} "GET http://fr.adserver.yahoo.com/"
Aug 9 20:30:46 localhost haproxy[2022]: 127.0.0.1:34020 [09/Aug/2004:20:30:46] relais-http netcache 0/0/0/182/+182 200 +279 - - ---- 0/0/0 0/0 {w.ods.org||} {Formilux/0.1.8|3495|||} "GET http://w.ods.org/sytadin.html HTTP/1.1"
Aug 9 20:30:46 localhost haproxy[2022]: 127.0.0.1:34028 [09/Aug/2004:20:30:46] relais-http netcache 0/0/2/126/+128 200 +223 - - ---- 0/0/0 0/0 {www.infotrafic.com||http://w.ods.org/syt} {Apache/2.0.40 (Red H|9068|||} "GET http://www.infotrafic.com/images/live/cartesidf/grandes/idf_ne.png HTTP/1.1"
4.2.7) Examples of logs
-----------------------
- haproxy[674]: 127.0.0.1:33319 [15/Oct/2003:08:31:57] relais-http Srv1 6559/7/147/6723 200 243 - - ---- 3/5 "HEAD / HTTP/1.0"
- haproxy[674]: 127.0.0.1:33319 [15/Oct/2003:08:31:57] relais-http Srv1 6559/0/7/147/6723 200 243 - - ---- 1/3/5 0/0 "HEAD / HTTP/1.0"
=> long request (6.5s) entered by hand through 'telnet'. The server replied
in 147 ms, and the session ended normally ('----')
- haproxy[674]: 127.0.0.1:33320 [15/Oct/2003:08:32:17] relais-http Srv1 9/7/14/+30 200 +243 - - ---- 3/3 "GET /image.iso HTTP/1.0"
- haproxy[674]: 127.0.0.1:33319 [15/Oct/2003:08:31:57] relais-http Srv1 6559/1230/7/147/6870 200 243 - - ---- 99/239/324 0/9 "HEAD / HTTP/1.0"
=> Idem, but the request was queued in the global queue behind 9 other
requests, and waited there for 1230 ms.
- haproxy[674]: 127.0.0.1:33320 [15/Oct/2003:08:32:17] relais-http Srv1 9/0/7/14/+30 200 +243 - - ---- 1/3/3 0/0 "GET /image.iso HTTP/1.0"
=> request for a long data transfer. The 'logasap' option was specified, so
the log was produced just before transfering data. The server replied in
14 ms, 243 bytes of headers were sent to the client, and total time from
accept to first data byte is 30 ms.
- haproxy[674]: 127.0.0.1:33320 [15/Oct/2003:08:32:17] relais-http Srv1 9/7/14/30 502 243 - - PH-- 2/3 "GET /cgi-bin/bug.cgi? HTTP/1.0"
- haproxy[674]: 127.0.0.1:33320 [15/Oct/2003:08:32:17] relais-http Srv1 9/0/7/14/30 502 243 - - PH-- 0/2/3 0/0 "GET /cgi-bin/bug.cgi? HTTP/1.0"
=> the proxy blocked a server response either because of an 'rspdeny' or
'rspideny' filter, or because it blocked sensible information which risked
being cached. In this case, the response is replaced with a '502 bad
gateway'.
- haproxy[18113]: 127.0.0.1:34548 [15/Oct/2003:15:18:55] relais-http <NOSRV> -1/-1/-1/8490 -1 0 - - CR-- 2/2 ""
- haproxy[18113]: 127.0.0.1:34548 [15/Oct/2003:15:18:55] relais-http <NOSRV> -1/-1/-1/-1/8490 -1 0 - - CR-- 0/2/2 0/0 ""
=> the client never completed its request and aborted itself ('C---') after
8.5s, while the proxy was waiting for the request headers ('-R--').
Nothing was sent to the server.
- haproxy[18113]: 127.0.0.1:34549 [15/Oct/2003:15:19:06] relais-http <NOSRV> -1/-1/-1/50001 408 0 - - cR-- 2/2 ""
- haproxy[18113]: 127.0.0.1:34549 [15/Oct/2003:15:19:06] relais-http <NOSRV> -1/-1/-1/-1/50001 408 0 - - cR-- 2/2 0/0 ""
=> The client never completed its request, which was aborted by the time-out
('c---') after 50s, while the proxy was waiting for the request headers ('-R--').
Nothing was sent to the server, but the proxy could send a 408 return code
to the client.
- haproxy[18989]: 127.0.0.1:34550 [15/Oct/2003:15:24:28] relais-tcp Srv1 0/5007 0 cD
- haproxy[18989]: 127.0.0.1:34550 [15/Oct/2003:15:24:28] relais-tcp Srv1 0/0/5007 0 cD 0/0/0 0/0
=> This is a 'tcplog' entry. Client-side time-out ('c----') occured after 5s.
- haproxy[18989]: 10.0.0.1:34552 [15/Oct/2003:15:26:31] relais-http Srv1 3183/-1/-1/11215 503 0 - - SC-- 202/205 "HEAD / HTTP/1.0"
- haproxy[18989]: 10.0.0.1:34552 [15/Oct/2003:15:26:31] relais-http Srv1 3183/-1/-1/-1/11215 503 0 - - SC-- 115/202/205 0/0 "HEAD / HTTP/1.0"
=> The request took 3s to complete (probably a network problem), and the
connection to the server failed ('SC--') after 4 attemps of 2 seconds
(config says 'retries 3'), then a 503 error code was sent to the client.
There were 202 connections on this proxy, and 205 on the global process.
It is possible that the server refused the connection because of too many
already established.
There were 115 connections on this server, 202 connections on this proxy,
and 205 on the global process. It is possible that the server refused the
connection because of too many already established.
4.3) HTTP header manipulation

View File

@ -2,9 +2,9 @@
H A - P r o x y
Manuel de référence
-------------------
version 1.2.12
version 1.2.13
willy tarreau
2006/04/15
2006/05/13
================
| Introduction |
@ -21,6 +21,8 @@ environnement hautement disponible. En effet, il est capable de :
- interdire des requêtes qui vérifient certaines conditions ;
- utiliser des serveurs de secours lorsque les serveurs principaux sont hors
d'usage.
- maintenir des clients sur le bon serveur serveur d'application en fonction
de cookies applicatifs.
Il requiert peu de ressources, et son architecture événementielle mono-
processus lui permet facilement de gérer plusieurs milliers de connexions
@ -35,7 +37,9 @@ Les options de lancement sont peu nombreuses :
-f <fichier de configuration>
-n <nombre maximal total de connexions simultanées>
-N <nombre maximal de connexions simultanées par proxy>
= 'maxconn' dans la section 'global'
-N <nombre maximal de connexions simultanées par instance>
= 'maxconn' dans les sections 'listen' ou 'default'
-d active le mode debug
-D passe en daemon
-q désactive l'affichage de messages sur la sortie standard.
@ -77,18 +81,8 @@ Les statistiques ne sont disponibles que si le programme a
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)
Les paramètres '-st' et '-sf' sont utilisés pour la reconfiguration à chaud.
Voir la section à ce sujet.
============================
| Fichier de configuration |
@ -439,7 +433,7 @@ Remarque: le mot cl
Un service peut fonctionner dans trois modes différents :
- TCP
- HTTP
- supervision
- état de santé
Mode TCP
--------
@ -490,6 +484,8 @@ Exemple :
option httpchk
2.2.1 Supervision
-----------------
Les versions 1.1.32 et 1.2.6 apportent une nouvelle solution pour valider le
bon fonctionnement du proxy sans perturber le service. Le mot-clé 'monitor-net'
a été créé dans le butd de spécifier un réseau d'équipements qui ne PEUVENT PAS
@ -581,7 +577,23 @@ signal SIGUSR1 une fois le processus en pause. Aussi, il peut s'av
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).
options '-st' et '-sf' (voir ci-dessous).
2.4) Reconfiguration à chaud
----------------------------
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)
2.5) Temps d'expiration des connexions
--------------------------------------
@ -1125,8 +1137,9 @@ 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.
serveur par rapport aux autres. Le poids de 1 donne la fréquence d'apparition
la plus faible, et 256 la fréquence la plus élevée. De cette manière, si un
serveur disparait, les capacités restantes sont toujours respectées.
Exemple :
@ -1164,6 +1177,78 @@ Notes :
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.
La distribution du trafic suivra exactement le séquencement suivant :
Request| 1 1 1 1
number | 1 2 3 4 5 6 7 8 9 0 1 2 3
--------+---------------------------
p3-800 | X . . . . . . X . . . . .
opt-20 | . X . X . X . . . X . X .
opt-24 | . . X . X . X . X . X . X
3.4) Limitation du nombre de sessions concurrentes par serveur
--------------------------------------------------------------
Certains serveurs web multi-processus tels qu'Apache souffrent dès qu'il y a
trop de sessions concurrentes, parce qu'il est très coûteux de faire
fonctionner des centaines ou des milliers de processus sur un système. Une
solution consiste à augmenter le nombre de serveurs et de répartir la charge
entre eux, mais cela pose un problème lorsque le but est uniquement de résister
à des pics de charge occasionnels.
Pour résoudre ce problème, une nouvelle fonctionnalité a été implémentée dans
HAProxy 1.2.13. Il s'agit d'une limite "maxconn" par serveur, associée à une
file d'attente par serveur et par proxy. Ceci transforme HAProxy en un tampon
entre des milliers de clients et quelques serveurs. Dans bien des cas, le fait
de diminuer la valeur maxconn améliorera notablement les performances des
serveurs et diminuera les temps de réponse simplement parce que les serveurs
seront moins congestionnés.
Quand une requête cherche à joindre n'importe quel serveur, le premier serveur
non saturé est utilisé, en respectant l'algorithme de répartition de charge. Si
tous les serveurs sont saturés, alors la requête sera mise dans la file
d'attente globale de l'instance. Elle sortira de cette file d'attente lorsque
toutes les requêtes précédentes auront été libérées et qu'un serveur aura été
libéré d'une connexion pour la traiter.
Si une requête fait référence à un serveur en particulier (p.ex: hachage d'IP
source, ou persistance par cookie), et que ce server est saturé, alors la
requête sera mise dans la file d'attente dédiée à ce serveur. Cette file
d'attente est prioritaire sur la file d'attente globale, de sorte qu'il soit
plus facile d'atteindre le site pour les utilisateurs qui s'y trouvent déjà
que pour les nouveaux utilisateurs.
Pour cela, les logs ont dû être enrichis pour indiquer le nombre de sessions
par serveur, la position de la requête dans les files d'attentes, et le temps
passé en file d'attente. Ceci aide considérablement à faire de la prévision de
capacité. Voir la section 'logs' plus bas pour plus d'informations.
Exemple :
---------
# Prendre soin du P3 qui n'a que 256 Mo de RAM.
listen web_appl 0.0.0.0:80
maxconn 10000
mode http
cookie SERVERID insert nocache indirect
balance roundrobin
server pentium3-800 192.168.1.1:80 cookie s1 weight 8 maxconn 100 check
server opteron-2.0G 192.168.1.2:80 cookie s2 weight 20 maxconn 300 check
server opteron-2.4G 192.168.1.3:80 cookie s3 weight 24 maxconn 300 check
server web-backup1 192.168.2.1:80 cookie s4 check maxconn 200 backup
server web-excuse 192.168.3.1:80 check backup
Notes :
-------
- la requête ne restera pas indéfiniment en file d'attente, elle est
assujétie au paramètre 'contimeout', et si une requête ne peut pas
sortir de la file avant ce time-out, soit parce que le serveur est
saturé, soit parce qu'il y a trop de requêtes en file d'attente,
alors elle expirera avec une erreur 503.
- positionner des valeurs trop basses pour 'maxconn' peut améliorer les
performances mais aussi permettre à des utilisateurs trop lents de bloquer
un serveur pour les autres utilisateurs.
4) Fonctionnalités additionnelles
=================================
@ -1340,7 +1425,8 @@ Par d
de la session entre le client et le relais. En précisant l'option 'tcplog',
la connexion ne sera journalisée qu'en fin de session, ajoutant des précisions
sur son état lors de la déconnexion, ainsi que le temps de connexion et la
durée totale de la session.
durée totale de la session. Le nombre de sessions restantes après la
déconnexion est également indiqué (pour le serveur, l'instance et le process).
Exemple de journalisation TCP :
-------------------------------
@ -1349,19 +1435,20 @@ Exemple de journalisation TCP :
option tcplog
log 192.168.2.200 local3
>>> haproxy[18989]: 127.0.0.1:34550 [15/Oct/2003:15:24:28] relais-tcp Srv1 0/5007 0 -- 1/1
>>> haproxy[18989]: 127.0.0.1:34550 [15/Oct/2003:15:24:28] relais-tcp Srv1 0/0/5007 0 -- 1/1/1 0/0
Champ Format / Description Exemple
1 nom_processus '[' pid ']:' haproxy[18989]:
2 ip_client ':' port_client 127.0.0.1:34550
3 '[' date ']' [15/Oct/2003:15:24:28]
4 nom_instance relais-tcp
5 nom_serveur Srv1
6 temps_connect '/' temps_total 0/5007
7 octets lus 0
8 etat_terminaison --
9 conns_instance '/' conns_processus 1/1
Champ Format / Description Exemple
1 nom_processus '[' pid ']:' haproxy[18989]:
2 ip_client ':' port_client 127.0.0.1:34550
3 '[' date ']' [15/Oct/2003:15:24:28]
4 nom_instance relais-tcp
5 nom_serveur Srv1
6 temps_file '/' temps_connect '/' temps_total 0/0/5007
7 octets lus 0
8 etat_terminaison --
9 conn_srv '/' conns_inst '/' conns_processus 1/1/1
10 position en file d'attente srv '/' globale 0/0
Une autre option, 'httplog', fournit plus de détails sur le protocole HTTP,
notamment la requête et l'état des cookies. Dans les cas où un mécanisme de
@ -1378,29 +1465,30 @@ Exemple de journalisation HTTP :
option dontlognull
log 192.168.2.200 local3
>>> haproxy[674]: 127.0.0.1:33319 [15/Oct/2003:08:31:57] relais-http Srv1 9/7/147/723 200 243 - - ---- 3/3 "HEAD / HTTP/1.0"
>>> haproxy[674]: 127.0.0.1:33319 [15/Oct/2003:08:31:57] relais-http Srv1 9/0/7/147/723 200 243 - - ---- 2/3/3 0/0 "HEAD / HTTP/1.0"
Exemple plus complet :
haproxy[18989]: 10.0.0.1:34552 [15/Oct/2003:15:26:31] relais-http Srv1 3183/-1/-1/11215 503 0 - - SC-- 202/205 {w.ods.org|Mozilla} {} "HEAD / HTTP/1.0"
haproxy[18989]: 10.0.0.1:34552 [15/Oct/2003:15:26:31] relais-http Srv1 3183/-1/-1/-1/11215 503 0 - - SC-- 137/202/205 0/0 {w.ods.org|Mozilla} {} "HEAD / HTTP/1.0"
Champ Format / Description Exemple
1 nom_processus '[' pid ']:' haproxy[18989]:
2 ip_client ':' port_client 10.0.0.1:34552
3 '[' date ']' [15/Oct/2003:15:26:31]
4 nom_instance relais-http
5 nom_serveur Srv1
6 Tq '/' Tc '/' Tr '/' Tt 3183/-1/-1/11215
7 Code_retour_HTTP 503
8 octets lus 0
9 cookies_requête_capturés -
10 cookies_reponse_capturés -
11 etat_terminaison SC--
12 conns_instance '/' conns_processus 202/205
13 '{' entetes_requête_capturés '}' {w.ods.org|Mozilla}
14 '{' entetes_reponse_capturés '}' {}
15 '"' requête_HTTP '"' "HEAD / HTTP/1.0"
Champ Format / Description Exemple
1 nom_processus '[' pid ']:' haproxy[18989]:
2 ip_client ':' port_client 10.0.0.1:34552
3 '[' date ']' [15/Oct/2003:15:26:31]
4 nom_instance relais-http
5 nom_serveur Srv1
6 Tq '/' Tw '/' Tc '/' Tr '/' Tt 3183/-1/-1/-1/11215
7 Code_retour_HTTP 503
8 octets lus 0
9 cookies_requête_capturés -
10 cookies_reponse_capturés -
11 etat_terminaison SC--
12 conns_srv '/' conns_inst '/' conns_processus 137/202/205
13 position file serveur '/' globale 0/0
14 '{' entetes_requête_capturés '}' {w.ods.org|Mozilla}
15 '{' entetes_reponse_capturés '}' {}
16 '"' requête_HTTP '"' "HEAD / HTTP/1.0"
Note pour les analyseurs de logs : l'URI est TOUJOURS le dernier champ de la ligne, et
commence par un guillemet '"'.
@ -1437,7 +1525,7 @@ Exemple :
Pour déceler des problèmes réseau, les mesures du temps écoulé entre certains
événements sont d'une très grande utilité. Tous les temps sont mesurés en
millisecondes (ms). En mode HTTP, quatre points de mesure sont rapportés sous
la forme Tq/Tc/Tr/Tt :
la forme Tq/Tw/Tc/Tr/Tt :
- Tq: temps total de réception de la requête HTTP de la part du client.
C'est le temps qui s'est écoulé entre le moment où le client a établi
@ -1445,6 +1533,13 @@ la forme Tq/Tc/Tr/Tt :
en-tête HTTP validant la fin de la requête. Une valeur '-1' ici indique
que la requête complète n'a jamais été reçue.
- Tw: temps total passé dans les files d'attente avant d'obtenir une place
vers un serveur. Ceci tient compte à la fois de la file d'attente globale
et de celle du serveur, et dépend du nombre de requêtes dans la file et du
temps nécessaire au serveur pour compléter les sessions précédentes. La
valeur '-1' indique que la requête a été détruite avant d'atteindre une
file.
- Tc: temps d'établissement de la connexion TCP du relais vers le serveur.
C'est le temps écoulé entre le moment ou le relais a initié la demande de
connexion vers le serveur, et le moment où ce dernier l'a acquittée, c'est
@ -1462,15 +1557,15 @@ la forme Tq/Tc/Tr/Tt :
connexion du client a été acquittée et le moment où la connexion a été
refermée aux deux extrémités (client et serveur). La signification change
un peu si l'option 'logasap' est présente. Dans ce cas, le temps correspond
uniquement à (Tq + Tc + Tr), et se trouve préfixé d'un signe '+'. On peut
donc déduire Td, le temps de transfert des données, en excluant les autres
temps :
uniquement à (Tq + Tw + Tc + Tr), et se trouve préfixé d'un signe '+'. On
peut donc déduire Td, le temps de transfert des données, en excluant les
autres temps :
Td = Tt - (Tq + Tc + Tr)
Td = Tt - (Tq + Tw + Tc + Tr)
Les temps rapportés à '-1' sont simplement à éliminer de cette équation.
En mode TCP ('option tcplog'), seuls les deux indicateurs Tc et Tt sont
En mode TCP ('option tcplog'), seuls les deux indicateurs Tw, Tc et Tt sont
rapportés.
Ces temps fournissent de précieux renseignement sur des causes probables de
@ -1497,13 +1592,15 @@ Cas les plus fr
savoir comment désactiver le keep-alive HTTP.
Autres cas ('xx' représentant une valeur quelconque à ignorer) :
-1/xx/xx/Tt : le client n'a pas envoyé sa requête dans le temps imparti ou
-1/xx/xx/xx/Tt: le client n'a pas envoyé sa requête dans le temps imparti ou
a refermé sa connexion sans compléter la requête.
Tq/-1/xx/Tt : la connexion n'a pas pu s'établir vers le serveur (refus ou
time-out au bout de Tt-Tq ms).
Tq/Tc/-1/Tt : le serveur a accepté la connexion mais n'a pas répondu dans
Tq/-1/xx/xx/Tt: Il n'était pas possible de traiter la request, probablement
parce que tous les serveurs étaient hors d'usage.
Tq/Tw/-1/xx/Tt: la connexion n'a pas pu s'établir vers le serveur (refus ou
time-out au bout de Tt-(Tq+Tw) ms).
Tq/Tw/Tc/-1/Tt: le serveur a accepté la connexion mais n'a pas répondu dans
les temps ou bien a refermé sa connexion trop tôt, au bout
de Tt-(Tq+Tc) ms.
de Tt-(Tq+Tw+Tc) ms.
4.2.4) Conditions de déconnexion
--------------------------------
@ -1548,6 +1645,11 @@ une signification pr
R : attente d'une REQUETE HTTP complète de la part du client. Rien n'a
été transmis au serveur.
Q : attente en file d'attente (QUEUE) d'une place pour avoir une
connexion vers un serveur. Ne peut apparaître que sur un serveur
possédant un paramètre 'maxconn'. Aucune connexion n'a été envoyée
au serveur.
C : attente de l'établissement d'une CONNEXION vers le serveur. Le
serveur peut au plus avoir vu la tentative de connexion, mais
aucune donnée n'a été échangée.
@ -1780,34 +1882,38 @@ d'en-t
Log :
Aug 9 20:26:09 localhost haproxy[2022]: 127.0.0.1:34014 [09/Aug/2004:20:26:09] relais-http netcache 0/0/162/+162 200 +350 - - ---- {fr.adserver.yahoo.co||http://fr.f416.mail.} {|864|private||} "GET http://fr.adserver.yahoo.com/"
Aug 9 20:30:46 localhost haproxy[2022]: 127.0.0.1:34020 [09/Aug/2004:20:30:46] relais-http netcache 0/0/182/+182 200 +279 - - ---- {w.ods.org||} {Formilux/0.1.8|3495|||} "GET http://w.ods.org/sytadin.html HTTP/1.1"
Aug 9 20:30:46 localhost haproxy[2022]: 127.0.0.1:34028 [09/Aug/2004:20:30:46] relais-http netcache 0/2/126/+128 200 +223 - - ---- {www.infotrafic.com||http://w.ods.org/syt} {Apache/2.0.40 (Red H|9068|||} "GET http://www.infotrafic.com/images/live/cartesidf/grandes/idf_ne.png HTTP/1.1"
Aug 9 20:26:09 localhost haproxy[2022]: 127.0.0.1:34014 [09/Aug/2004:20:26:09] relais-http netcache 0/0/0/162/+162 200 +350 - - ---- 0/0/0 0/0 {fr.adserver.yahoo.co||http://fr.f416.mail.} {|864|private||} "GET http://fr.adserver.yahoo.com/"
Aug 9 20:30:46 localhost haproxy[2022]: 127.0.0.1:34020 [09/Aug/2004:20:30:46] relais-http netcache 0/0/0/182/+182 200 +279 - - ---- 0/0/0 0/0 {w.ods.org||} {Formilux/0.1.8|3495|||} "GET http://w.ods.org/sytadin.html HTTP/1.1"
Aug 9 20:30:46 localhost haproxy[2022]: 127.0.0.1:34028 [09/Aug/2004:20:30:46] relais-http netcache 0/0/2/126/+128 200 +223 - - ---- 0/0/0 0/0 {www.infotrafic.com||http://w.ods.org/syt} {Apache/2.0.40 (Red H|9068|||} "GET http://www.infotrafic.com/images/live/cartesidf/grandes/idf_ne.png HTTP/1.1"
4.2.7) Exemples de logs
-----------------------
- haproxy[674]: 127.0.0.1:33319 [15/Oct/2003:08:31:57] relais-http Srv1 6559/7/147/6723 200 243 - - ---- 3/5 "HEAD / HTTP/1.0"
- haproxy[674]: 127.0.0.1:33319 [15/Oct/2003:08:31:57] relais-http Srv1 6559/0/7/147/6723 200 243 - - ---- 1/3/5 0/0"HEAD / HTTP/1.0"
=> requête longue (6.5s) saisie à la main avec un client telnet. Le serveur a
répondu en 147 ms et la session s'est terminée normalement ('----')
- haproxy[674]: 127.0.0.1:33320 [15/Oct/2003:08:32:17] relais-http Srv1 9/7/14/+30 200 +243 - - ---- 3/3 "GET /image.iso HTTP/1.0"
- haproxy[674]: 127.0.0.1:33319 [15/Oct/2003:08:31:57] relais-http Srv1 6559/1230/7/147/6870 200 243 - - ---- 99/239/324 0/9 "HEAD / HTTP/1.0"
=> Idem, mais la requête a été mise en attente dans la file globale derrière
9 autres requêtes déjà présentes, et y a attendu 1230 ms.
- haproxy[674]: 127.0.0.1:33320 [15/Oct/2003:08:32:17] relais-http Srv1 9/0/7/14/+30 200 +243 - - ---- 1/3/3 0/0 "GET /image.iso HTTP/1.0"
=> requête pour un long transfert. L'option 'logasap' était spécifiée donc le
log a été généré juste avant le transfert de données. Le serveur a répondu
en 14 ms, 243 octets d'en-têtes ont été transférés au client, et le temps
total entre l'accept() et le premier octet de donnée est de 30 ms.
- haproxy[674]: 127.0.0.1:33320 [15/Oct/2003:08:32:17] relais-http Srv1 9/7/14/30 502 243 - - PH-- 2/3 "GET /cgi-bin/bug.cgi? HTTP/1.0"
- haproxy[674]: 127.0.0.1:33320 [15/Oct/2003:08:32:17] relais-http Srv1 9/0/7/14/30 502 243 - - PH-- 0/2/3 0/0 "GET /cgi-bin/bug.cgi? HTTP/1.0"
=> le proxy a bloqué une réponse du serveur soit à cause d'un filtre 'rspdeny'
ou 'rspideny', soit parce qu'il a détecté un risque de fuite sensible
d'informations risquant d'être cachées. Dans ce cas, la réponse est
remplacée par '502 bad gateway'.
- haproxy[18113]: 127.0.0.1:34548 [15/Oct/2003:15:18:55] relais-http <NOSRV> -1/-1/-1/8490 -1 0 - - CR-- 2/2 ""
- haproxy[18113]: 127.0.0.1:34548 [15/Oct/2003:15:18:55] relais-http <NOSRV> -1/-1/-1/-1/8490 -1 0 - - CR-- 0/2/2 0/0 ""
=> Le client n'a pas envoyé sa requête et a refermé la connexion lui-même
('C---') au bout de 8.5s, alors que le relais attendait l'en-tête ('-R--').
Aucune connexion n'a été envoyée vers le serveur.
- haproxy[18113]: 127.0.0.1:34549 [15/Oct/2003:15:19:06] relais-http <NOSRV> -1/-1/-1/50001 408 0 - - cR-- 2/2 ""
- haproxy[18113]: 127.0.0.1:34549 [15/Oct/2003:15:19:06] relais-http <NOSRV> -1/-1/-1/-1/50001 408 0 - - cR-- 0/2/2 0/0 ""
=> Le client n'a pas envoyé sa requête et son time-out a expiré ('c---') au
bout de 50s, alors que le relais attendait l'en-tête ('-R--'). Aucune
connexion n'a été envoyée vers le serveur, mais le relais a tout de même
@ -1817,13 +1923,14 @@ d'en-t
=> log en mode 'tcplog'. Expiration du time-out côté client ('cD') au bout de
5s.
- haproxy[18989]: 10.0.0.1:34552 [15/Oct/2003:15:26:31] relais-http Srv1 3183/-1/-1/11215 503 0 - - SC-- 202/205 "HEAD / HTTP/1.0"
- haproxy[18989]: 10.0.0.1:34552 [15/Oct/2003:15:26:31] relais-http Srv1 3183/-1/-1/-1/11215 503 0 - - SC-- 115/202/205 0/0 "HEAD / HTTP/1.0"
=> La requête client met 3s à entrer (peut-être un problème réseau), et la
connexion ('SC--') vers le serveur échoue au bout de 4 tentatives de 2
secondes (retries 3 dans la conf), puis un code 503 est retourné au client.
Il y avait 202 connexions sur cette instance, et 205 sur l'ensemble des
instances pour ce processus. Il est possible que le serveur ait refusé la
connexion parce qu'il y en avait déjà trop d'établies.
secondes (retries 3 dans la conf), puis un code 503 est retourné au
client. Il y avait 115 connexions sur ce serveur, 202 connexions sur cette
instance, et 205 sur l'ensemble des instances pour ce processus. Il est
possible que le serveur ait refusé la connexion parce qu'il y en avait
déjà trop d'établies.
4.3) Modification des en-têtes HTTP