mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-01-19 12:10:46 +00:00
OPTIM: http: don't stop polling for read on the client side after a request
We used to unconditionally disable client-side polling after the client has posted its request. The goal was to avoid subscribing the file descriptor to the poller for nothing. This is perfect for the HTTP close mode where we know we won't have to read on the client side anymore. However, when keep-alive is maintained with the client, this makes the situation worse. Indeed, after the first response, we'll have to wait for the client to send a next request and since this is never immediate, we'll certainly poll. So what happens is that polling is enabled after a response and disabled after a request, so the polling is constantly alternating, which is very expensive with epoll_ctl(). The solution implemented in this patch consists in only disabling the polling if the client-side is not in keep-alive mode. That way we have the best of both worlds. In close, we really close, and in keep-alive, we poll only once. The performance gained by this change is important, with haproxy jumping from 158kreq/s to 184kreq/s (+16%) in HTTP keep-alive mode on a machine which at best does 222k/s in raw TCP mode. With this patch and the previous one, a keep-alive run with a fast enough server (or enough concurrent connections to cover the connect time) does no epoll_ctl() anymore during a run of ab -k. The net measured gain is 19%.
This commit is contained in:
parent
1208266356
commit
3988d9342f
@ -4473,8 +4473,15 @@ int http_sync_req_state(struct session *s)
|
|||||||
* this CRLF must be read so that it does not remain in the kernel
|
* this CRLF must be read so that it does not remain in the kernel
|
||||||
* buffers, otherwise a close could cause an RST on some systems
|
* buffers, otherwise a close could cause an RST on some systems
|
||||||
* (eg: Linux).
|
* (eg: Linux).
|
||||||
|
* Note that if we're using keep-alive on the client side, we'd
|
||||||
|
* rather poll now and keep the polling enabled for the whole
|
||||||
|
* session's life than enabling/disabling it between each
|
||||||
|
* response and next request.
|
||||||
*/
|
*/
|
||||||
if (!(s->be->options & PR_O_ABRT_CLOSE) && txn->meth != HTTP_METH_POST)
|
if (((txn->flags & TX_CON_WANT_MSK) != TX_CON_WANT_SCL) &&
|
||||||
|
((txn->flags & TX_CON_WANT_MSK) != TX_CON_WANT_KAL) &&
|
||||||
|
!(s->be->options & PR_O_ABRT_CLOSE) &&
|
||||||
|
txn->meth != HTTP_METH_POST)
|
||||||
channel_dont_read(chn);
|
channel_dont_read(chn);
|
||||||
|
|
||||||
/* if the server closes the connection, we want to immediately react
|
/* if the server closes the connection, we want to immediately react
|
||||||
@ -4566,7 +4573,10 @@ int http_sync_req_state(struct session *s)
|
|||||||
|
|
||||||
if (txn->req.msg_state == HTTP_MSG_CLOSED) {
|
if (txn->req.msg_state == HTTP_MSG_CLOSED) {
|
||||||
http_msg_closed:
|
http_msg_closed:
|
||||||
if (!(s->be->options & PR_O_ABRT_CLOSE))
|
/* see above in MSG_DONE why we only do this in these states */
|
||||||
|
if (((txn->flags & TX_CON_WANT_MSK) != TX_CON_WANT_SCL) &&
|
||||||
|
((txn->flags & TX_CON_WANT_MSK) != TX_CON_WANT_KAL) &&
|
||||||
|
!(s->be->options & PR_O_ABRT_CLOSE))
|
||||||
channel_dont_read(chn);
|
channel_dont_read(chn);
|
||||||
goto wait_other_side;
|
goto wait_other_side;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user