From 532bb554aa695be7d6919697a43222a8b5a07bb5 Mon Sep 17 00:00:00 2001 From: willy tarreau Date: Sat, 13 May 2006 18:40:37 +0200 Subject: [PATCH] [DOC] update documentation to explain the server's maxconn --- doc/haproxy-en.txt | 279 +++++++++++++++++++++++++++++++-------------- doc/haproxy-fr.txt | 257 +++++++++++++++++++++++++++++------------ 2 files changed, 373 insertions(+), 163 deletions(-) diff --git a/doc/haproxy-en.txt b/doc/haproxy-en.txt index 45b70aeb84..2f9660e59d 100644 --- a/doc/haproxy-en.txt +++ b/doc/haproxy-en.txt @@ -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 -n - -N + = 'maxconn' in 'global' section + -N + = '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 enforces a memory usage limit to a maximum of 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 len timeout + appsession len timeout -- is the cookie, the server uses for it's session-handling -- how many bytes/characters should be used for matching equal +- is the cookie, the server uses for it's session-handling +- how many bytes/characters should be used for matching equal sessions -- after this inactivaty time, in ms, the cookie will be deleted +- 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 -1/-1/-1/8490 -1 0 - - CR-- 2/2 "" +- haproxy[18113]: 127.0.0.1:34548 [15/Oct/2003:15:18:55] relais-http -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 -1/-1/-1/50001 408 0 - - cR-- 2/2 "" +- haproxy[18113]: 127.0.0.1:34549 [15/Oct/2003:15:19:06] relais-http -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 diff --git a/doc/haproxy-fr.txt b/doc/haproxy-fr.txt index 8bb25a1c53..e10595f630 100644 --- a/doc/haproxy-fr.txt +++ b/doc/haproxy-fr.txt @@ -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 -n - -N + = 'maxconn' dans la section 'global' + -N + = '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 -1/-1/-1/8490 -1 0 - - CR-- 2/2 "" +- haproxy[18113]: 127.0.0.1:34548 [15/Oct/2003:15:18:55] relais-http -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 -1/-1/-1/50001 408 0 - - cR-- 2/2 "" +- haproxy[18113]: 127.0.0.1:34549 [15/Oct/2003:15:19:06] relais-http -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