Hi David,
On Tue, Jun 05, 2012 at 06:17:15PM -0700, David Birdsong wrote:
> Is there a way to set the maxqueu for an entire backend?
No. When I developped the server maxqueue, I remember having done the same
for the backend (it even ended up in the doc, causing later confusion), but
I removed it during tests because I noticed it was totally useless the way
it worked. Initially the goal was to limit the queue in the backend, not
counting the servers, which did not make much sense since it depends whether
the clients have a cookie or not. Then I figured that we'd have to count all
the queues of all servers, and I did not want to do that for each connection
since it's always expensive for just a few use cases. So I removed it before
ever releasing it.
> I set maxqueu
> on default-server to 1, and on the frontend ACL required that
> connslots be greater than 1. I expected connslots to be maxconn * num
> server + 1 * num servers (connections + queue slots).
>
> I found that the backend still queued requests. My ACL could check the
> current queue size of the backend and route away from that backend if
> it's gt 0, but I figured connslots was the more correct approach. What
> am I doing or understanding wrongly?
You're not necessarily doing anything wrong, there are a wide number of
reasons for deciding not to queue in a specific way, and that's the first
thing to define. If you have maxconn on servers, you need some queues.
The server queues are only for requests which target a specific server.
If the request has no cookie set, it will remain in the backend queue so
that any server may pick it. So as you can see, you *need* to support
queues both in the backend and servers whenever you use maxconn.
If you would prevent the backend from queueing any connections, you would
constantly emit 503 to some visitors, because traffic is never perfectly
smooth (which is observed by your backend queue inflating).
The best way I found to manage queues is the avg_queue ACL. It returns
the average number of queued connections per active server. This means
that wherever the connections are queued, they're accounted for, and
divided by the number of servers. The result is an average queue length
for the backend, which translates in an average wait time for visitors.
I think it's the most efficient way of taking decisions based on queue
length because you don't need to consider any difference between new and
past visitors, and you don't care whether a server has a deeper queue
than another one. This way you can safely remove the maxqueue parameter
from your servers and only decide to switch to another backend based on
the avg_queue.
BTW, what I'd suggest if you use this is to split the traffic depending
on the persistence cookie : stop sending new visitors to a backend which
has too many queued connections, but still send existing ones there. You
will see that the load on the servers will then regulate itself very well
and become extremely smooth. And that way you can finely control your
response times. In short this looks like this :
frontend pub
acl bk_full avg_queue(bk_www) gt 10
acl has_cook cook_len(SRV) gt 0
use_backend bk_sorry if bk_full !has_cook
default_backend bk_www
backend bk_www
cookie SRV insert indirect nocache
server s1 1.1.1.1:80 cookie 1 maxconn 50
...
backend bk_sorry
server sorry 127.0.0.1:8080
Regards,
Willy