Hi Aleks, On Sat, Aug 11, 2018 at 10:27:42AM +0200, Aleksandar Lazic wrote: > I think it is a requeue mechanism for the connection and not a selector for > a server or a backend, but I can be wrong.
That's it. I'll try to explain shortly. You're probably aware how the queuing mechanism works in haproxy when maxconn is set on a server : once maxconn is reached, requests are queue either into the server's queue, if something forces this request to use this specific server (cookie, ...) otherwise into the backend's queue. Till now, our queues were very fair (it was already shown on some blog posts from various users over the last decade). A server would always consult both its own queue and the backend's queue and pick the oldest request so that the order of arrival was always preserved. Now with this new feature, it is possible to change the dequeuing order when a server picks a request from the queues. There are two criteria for this : - the request's class - the position in the queue for a given class. The server will always consult classes with lowest value first. And within this class, it will pick the oldest waiting request. The "set-priority-class" action allows you to set the class, and mark a request as very important or unimportant. A good rule of thumb is to consider that rare but important requests should be given a low class number, that common requests should be given the default class number (unchanged) and that expensive and painful requests which are not very urgent should be given a high class number (dequeued only once no other request competes with them). The "set-priority-offset" action allows to tweak the apparent age of the request in the queue so that a server can pick a request before another one for a given class. This is not used to deal with the request's importance, but with the preferred response time. For example, if your site periodically refreshes the pages but cannot start to render before all objects are loaded, it could happen that the browser clears the page when reloading the HTML part, then takes ages to fetch css, js, etc, making the page unreadable for several seconds every minute for a reader. By applying a time offset to these extra components, you will make the mandatory elements such as CSS or JS load much faster than the HTML one, resulting in an extra delay before starting to fetch the HTML part (hence the page is not yet cleared), and a shorter delay for the CSS/JS parts (making it render faster once cleared). Similarly you could be a hosting provider willing to offer certain guarantees on the page load time to certain customers. With this you could easily say that those paying for premium service are guaranteed to see a 100 ms faster load time than those paying the entry level one, simply by applying a -100ms offset on their requests. Some people want to use such features the other way around. Certain sites have low importance stuff like an avatar upload button, a profile settings page, etc, on which people "waste their time" instead of making use of the main site, but still making use of the bandwidth and processing power. Sometimes they simply want to say that such auxiliary requests are applied an extra delay when there's competition to reach the servers. Just by adding an extra 1 second offset to such requests, you'll slow them down when the servers are highly loaded, and preserve the resources for the other requests. It's really impressive when you run two load generators in parallel. You will typically see, say, 100 ms response time for both of them by default. Then you apply +100ms to the requests coming from one of them, and then you'll see a distribution like 66/166ms with the load of the slow one dropping as its response time increases, giving more resources to the other one, allowing its traffic to be processed faster. I hope I helped clear your doubts. I'm having a few comments below : > listen|frontend test001 > bind :8080 > # some other options > http-request set-priority-class -10s if PAY_BUTTON The class just uses integers, not delays. Also it's an interesting case you have here, as many sites prefer to *increase* the delay on the pay button or even once there's anything in your cart. There's a reason : visitors who don't find what they're looking for are likely to quit the site, so you need to improve their experience while they're searching. Once their shopping cart is filled with a few articles, they're not willing to spend as much time looking for them again on another site, so they're very likely to accept to wait (even if that scares them). Thus by delaying their traffic you can improve others' experience. Yes I know it's dirty, but I don't operate a shopping site :-) > http-request set-priority-offset 5s if LOGO That's a typically good example, yes, as nobody cares about the logo being loaded fast. > # as a sample expression can also be this, right? > http-request set-priority-class \ > %[req.fhdr(User-Agent),51d.single(DeviceType,IsMobile,IsTablet)] No, it takes a constant expression. I'm not sure whether it would really make sense to make it support sample expressions. I'm not necessarily against it, it's just that I think it comes with extra cost and complexity for very low value in the end. Very likely you can do this using 2 or 3 rules only. > # could this work ? > use_backend high_priority if priority-class > 5 We don't have a sample fetch to retrieve the value, but it would be trivial to implement as the value is present in the stream. Feel free to take a look at how priority-class and priority-offset work for this. Right now you can already achieve this by setting a variable anyway, but I can see value in using the class to take a routing decision. Cheers, Willy