mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-10-27 14:41:28 +01:00
MINOR: proxy: explicitly permit abortonclose on frontends and clarify the doc
The "abortonclose" option was recently deprecated in frontends because its action was essentially limited to the backend part (queuing etc). But in 3.3 we started to support it for TLS on frontends, though it would only work when placed in a defaults section. Let's officially support it in frontends, and take this opportunity to clarify the documentation on this topic, which was incomplete regarding frontend and TLS support. Now the doc tries to better cover the different use cases.
This commit is contained in:
parent
f657ffc6e7
commit
c42e62d890
@ -5571,7 +5571,7 @@ maxconn X X X -
|
|||||||
mode X X X X
|
mode X X X X
|
||||||
monitor fail - X X -
|
monitor fail - X X -
|
||||||
monitor-uri X X X -
|
monitor-uri X X X -
|
||||||
option abortonclose (*) X - X X
|
option abortonclose (*) X X X X
|
||||||
option allbackups (*) X - X X
|
option allbackups (*) X - X X
|
||||||
option checkcache (*) X - X X
|
option checkcache (*) X - X X
|
||||||
option clitcpka (*) X X X -
|
option clitcpka (*) X X X -
|
||||||
@ -9044,46 +9044,56 @@ monitor-uri <uri>
|
|||||||
|
|
||||||
option abortonclose
|
option abortonclose
|
||||||
no option abortonclose
|
no option abortonclose
|
||||||
Enable or disable early dropping of aborted requests pending in queues.
|
Enable or disable early abortion of not started processing when client closes
|
||||||
|
|
||||||
May be used in the following contexts: tcp, http
|
May be used in the following contexts: tcp, http
|
||||||
|
|
||||||
May be used in sections : defaults | frontend | listen | backend
|
May be used in sections : defaults | frontend | listen | backend
|
||||||
yes | no | yes | yes
|
yes | yes | yes | yes
|
||||||
|
|
||||||
Arguments : none
|
Arguments : none
|
||||||
|
|
||||||
In presence of very high loads, the servers will take some time to respond.
|
TCP connections support being closed independently in each direction, and a
|
||||||
The per-instance connection queue will inflate, and the response time will
|
connection with only one direction closed is often said to be "half-closed".
|
||||||
increase respective to the size of the queue times the average per-stream
|
Originally when the HTTP ecosystem was mostly made of the "close mode", with
|
||||||
response time. When clients will wait for more than a few seconds, they will
|
only one request and one response per connection before closing, it was
|
||||||
often hit the "STOP" button on their browser, leaving a useless request in
|
pretty frequent to see scripted clients send their request, close the sending
|
||||||
the queue, and slowing down other users, and the servers as well, because the
|
side, wait for the response, receive the close indication and be done with
|
||||||
request will eventually be served, then aborted at the first error
|
this. But with the arrival of keep-alive and more advanced protocols, this
|
||||||
encountered while delivering the response.
|
practice has practically disappeared and the only cases where a client closes
|
||||||
|
before receiving its response is essentially when the user wants to abort a
|
||||||
|
transfer, or when a timeout strikes and the connection is closed.
|
||||||
|
|
||||||
As there is no way to distinguish between a full STOP and a simple output
|
These two situations (half-closed vs abort) are undistinguishable from the
|
||||||
close on the client side, HTTP agents should be conservative and consider
|
server side (here the HAProxy listener). This is a problem because leaving
|
||||||
that the client might only have closed its output channel while waiting for
|
the connection alive and continuing to process a request when clients abort
|
||||||
the response. However, this introduces risks of congestion when lots of users
|
can cost a lot of resources, particularly if the closure is the result of a
|
||||||
do the same, and is completely useless nowadays because probably no client at
|
user hitting the "reload" button, as it means new requests are queued without
|
||||||
all will close the stream while waiting for the response. Some HTTP agents
|
the previous ones being aborted. And conversely, systematically aborting when
|
||||||
support this behavior (Squid, Apache, HAProxy), and others do not (TUX, most
|
facing such a half-close situation would break a number of TCP applications
|
||||||
hardware-based load balancers). So the probability for a closed input channel
|
and even some HTTP ones on internal networks interacting with legacy agents.
|
||||||
to represent a user hitting the "STOP" button is close to 100%, and the risk
|
|
||||||
of being the single component to break rare but valid traffic is extremely
|
|
||||||
low, which adds to the temptation to be able to abort a stream early while
|
|
||||||
still not served and not pollute the servers.
|
|
||||||
|
|
||||||
In HAProxy, the user can choose the desired behavior using the option
|
The "abortonclose" option permits to choose the desired behavior:
|
||||||
"abortonclose". By default (without the option) the behavior is HTTP
|
- when present in a frontend, it will avoid processing TLS handshakes which
|
||||||
compliant and aborted requests will be served. But when the option is
|
are pending on a half-closed connection. This can be the result of a user
|
||||||
specified, a stream with an incoming channel closed will be aborted while
|
hitting "reload" during an HTTPS request under high load such as a VRRP
|
||||||
it is still possible, either pending in the queue for a connection slot, or
|
fail-over between an active HAProxy node and the backup one: all clients
|
||||||
during the connection establishment if the server has not yet acknowledged
|
reconnect at the same time to the new node, and all have to perform a
|
||||||
the connection request. This considerably reduces the queue size and the load
|
costly, full TLS handshake. If it takes more than a few seconds, it's
|
||||||
on saturated servers when users are tempted to click on STOP, which in turn
|
likely that some users will give up, and it's pointless to waste CPU
|
||||||
reduces the response time for other users.
|
cycles on their handshakes. Given the CPU cost of TLS handshakes, it is
|
||||||
|
recommended to leave this option enabled on internet-facing frontends.
|
||||||
|
|
||||||
|
- when present in a backend, it will cause half-closed connections to try
|
||||||
|
to abort a request that was not yet sent to a server (i.e. when it's
|
||||||
|
pending in the queue or when trying to connect). If the request is
|
||||||
|
already being served by a server, then the connection to the server is
|
||||||
|
in turn switched to half-close to indicate the same condition to the
|
||||||
|
server, which will then decide how to proceed.
|
||||||
|
|
||||||
|
The recommendation is to enable this option on internet-facing TLS endpoints
|
||||||
|
and HTTP services, and to disable it for pure TCP ones as well as unexposed
|
||||||
|
legacy environments.
|
||||||
|
|
||||||
If this option has been enabled in a "defaults" section, it can be disabled
|
If this option has been enabled in a "defaults" section, it can be disabled
|
||||||
in a specific instance by prepending the "no" keyword before it.
|
in a specific instance by prepending the "no" keyword before it.
|
||||||
|
|||||||
@ -82,7 +82,7 @@ struct show_srv_ctx {
|
|||||||
/* proxy->options */
|
/* proxy->options */
|
||||||
const struct cfg_opt cfg_opts[] =
|
const struct cfg_opt cfg_opts[] =
|
||||||
{
|
{
|
||||||
{ "abortonclose", PR_O_ABRT_CLOSE, PR_CAP_BE, 0, 0 },
|
{ "abortonclose", PR_O_ABRT_CLOSE, PR_CAP_BE|PR_CAP_FE, 0, 0 },
|
||||||
{ "allbackups", PR_O_USE_ALL_BK, PR_CAP_BE, 0, 0 },
|
{ "allbackups", PR_O_USE_ALL_BK, PR_CAP_BE, 0, 0 },
|
||||||
{ "checkcache", PR_O_CHK_CACHE, PR_CAP_BE, 0, PR_MODE_HTTP },
|
{ "checkcache", PR_O_CHK_CACHE, PR_CAP_BE, 0, PR_MODE_HTTP },
|
||||||
{ "clitcpka", PR_O_TCP_CLI_KA, PR_CAP_FE, 0, 0 },
|
{ "clitcpka", PR_O_TCP_CLI_KA, PR_CAP_FE, 0, 0 },
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user