This just keeps coming back to bug me. I don't think the client closing the connection should result in a 5XX code. 5XX should indicate a server issue, and the client closing the connection before the server has a chance to respond isn't a server issue. Only if the server doesn't respond within the configured timeout should it be a 5XX.
Nginx uses 499 for "client closed connection". Perhaps haproxy could use that status code as well when `option abortonclose` is used. -Patrick ------------------------------------------------------------------------ *From: *Patrick Hemmer <hapr...@stormcloud9.net> *Sent: * 2014-04-02 15:50:22 E *To: *haproxy@formilux.org *Subject: *Re: haproxy intermittently not connecting to backend > That makes perfect sense. Thank you very much. > > -Patrick > > ------------------------------------------------------------------------ > *From: *Willy Tarreau <w...@1wt.eu> > *Sent: * 2014-04-02 15:38:04 E > *To: *Patrick Hemmer <hapr...@stormcloud9.net> > *CC: *haproxy@formilux.org > *Subject: *Re: haproxy intermittently not connecting to backend > >> Hi Patrick, >> >> On Tue, Apr 01, 2014 at 03:20:15PM -0400, Patrick Hemmer wrote: >>> We have an issue with haproxy (1.5-dev22-1a34d57) where it is >>> intermittently not connecting to the backend server. However the >>> behavior it is exhibiting seems strange. >>> The reason I say strange is that in one example, it logged that the >>> client disconnected after ~49 seconds with a connection flags of "CC--". >>> However our config has "timeout connect 5000", so it should have timed >>> out connecting to the backend server after 5 seconds. Additionally we >>> have "retries 3" in the config, so upon timing out, it should have tried >>> another backend server, but it never did (the retries counter in the log >>> shows "0"). >> No, retries impacts only retries to the same server, it's "option redispatch" >> which allows the last retry to be performed on another server. But you have >> it anyway. >> >>> At the time of this log entry, the backend server is responding >>> properly. For the ~49 seconds prior to the log entry, the backend server >>> has taken other requests. The backend server is also another haproxy >>> (same version). >>> >>> Here's an example of one such log entry: >> [fixed version pasted here] >> >>> 198.228.211.13:60848 api~ platform-push/i-84d931a5 49562/0/-1/-1/49563 >>> 0/0/0/0/0 0/0 691/212 503 CC-- 4F8E-4624 + GET >>> /1/sync/notifications/subscribe?sync_box_id=12496&sender=D7A9F93D-F653-4527-A022-383AD55A1943 >>> HTTP/1.1 >> OK in fact the client did not wait 49 seconds. If you look closer, you'll >> see that the client remained silent for 49 seconds (typically a connection >> pool or a preconnect) and closed immediately after sending the request (in >> the same millisecond). Since you have "option abortonclose", the connection >> was aborted before the server had a chance to respond. >> >> So I can easily imagine that you randomly get this error, you're in a race >> condition, if the server responds immediately, you win the race and the >> request is handled, otherwise it's aborted. >> >> Please start by removing "option abortonclose", I think it will fix the >> issue. >> Second thing you can do is to remove "option httpclose" or replace it with >> "option http-server-close" which is active and not just passive. The >> connections >> will last less time on your servers which is always appreciated. >> >> I'm not seeing any other issue, so with just this you should be fine. >> >>> The log format is defined as: >>> %ci:%cp\ %ft\ %b/%s\ %Tq/%Tw/%Tc/%Tr/%Tt\ %ac/%fc/%bc/%sc/%rc\ %sq/%bq\ >>> %U/%B\ %ST\ %tsc\ %ID\ +\ %r >>> >>> Running a "show errors" on the stats socket did not return any relevant >>> results. >>> >>> Here's the relevant portions of the haproxy config. It is not the entire >>> thing as the whole config is 1,513 lines long. >>> >>> global >>> log 127.0.0.1 local0 >>> maxconn 20480 >>> user haproxy >>> group haproxy >>> daemon >>> stats socket /var/run/hapi/haproxy/haproxy.sock level admin >>> >>> defaults >>> log global >>> mode http >>> option httplog >>> option dontlognull >>> option log-separate-errors >>> retries 3 >>> option redispatch >>> timeout connect 5000 >>> timeout client 60000 >>> timeout server 170000 >>> option clitcpka >>> option srvtcpka >>> option abortonclose >>> option splice-auto >>> monitor-uri /haproxy/ping >>> stats enable >>> stats uri /haproxy/stats >>> stats refresh 15 >>> stats auth user:pass >>> >>> frontend api >>> bind *:80 >>> bind *:443 ssl crt /etc/haproxy/server.pem >>> maxconn 20000 >>> option httpclose >>> option forwardfor >>> acl internal src 10.0.0.0/8 >>> acl have_request_id req.fhdr(X-Request-Id) -m found >>> http-request set-nice -100 if internal >>> http-request add-header X-API-URL %[path] if !internal >>> http-request add-header X-Request-Timestamp %Ts.%ms >>> http-request add-header X-Request-Id %[req.fhdr(X-Request-Id)] if >>> internal have_request_id >>> http-request set-header X-Request-Id %{+X}o%pid-%rt if !internal || >>> !have_request_id >>> http-request add-header X-API-Host i-4a3b1c6a >>> unique-id-format %{+X}o%pid-%rt >>> log-format %ci:%cp\ %ft\ %b/%s\ %Tq/%Tw/%Tc/%Tr/%Tt\ >>> %ac/%fc/%bc/%sc/%rc\ %sq/%bq\ %U/%B\ %ST\ %tsc\ %ID\ +\ %r >>> default_backend DEFAULT_404 >>> >>> acl rewrite-found req.hdr(X-Rewrite-ID,1) -m found >>> >>> acl nqXn_path path_reg ^/1/sync/notifications/subscribe/([^\ ?]*)$ >>> acl nqXn_method method OPTIONS GET HEAD POST PUT DELETE TRACE CONNECT >>> PATCH >>> http-request set-header X-Rewrite-Id nqXn if !rewrite-found nqXn_path >>> nqXn_method >>> acl rewrite-nqXn req.hdr(X-Rewrite-Id) -m str nqXn >>> use_backend platform-push if rewrite-nqXn >>> reqrep ^(OPTIONS|GET|HEAD|POST|PUT|DELETE|TRACE|CONNECT|PATCH)\ >>> /1/sync/notifications/subscribe/([^\ ?]*)([\ ?].*|$) \1\ >>> /1/sync/subscribe/\2\3 if rewrite-nqXn >>> >>> >>> backend platform-push >>> option httpchk GET /ping >>> default-server inter 15s fastinter 1s >>> server i-6eaf724d 10.230.23.64:80 check observe layer4 >>> server i-84d931a5 10.230.42.8:80 check observe layer4 >>> >> Regards, >> Willy >> >> >