I have previously written a post on load balancing for Xojo web app developers using Nginx. You can see the post here. This is an update to that post focusing on Haproxy instead of Nginx.
You can learn more about and download Haproxy here.
Why choose Haproxy over Nginx?
global log 127.0.0.1 local0 maxconn 4096 daemon defaults log global mode http option httplog option dontlognull retries 3 option redispatch maxconn 2000 contimeout 5000 clitimeout 50000 srvtimeout 50000 frontend http-in bind *:80 acl is_myapp1 hdr_end(host) -i myapp1.mydomain.com acl is_myapp2 hdr_end(host) -i myapp2.mydomain.com use_backend myapp1pool if is_myapp1 use_backend myapp2pool if is_myapp2 default_backend myapp1pool backend myapp1pool option httpchk OPTIONS / option forwardfor option http-server-close cookie serverid insert indirect nocache server node1 127.0.0.1:8080 check cookie node1 server node2 127.0.0.1:8081 check cookie node2 server node3 127.0.0.1:8082 check cookie node3 backend myapp2pool option httpchk OPTIONS / option forwardfor option http-server-close cookie serverid insert indirect nocache server node1 127.0.0.1:8090 check cookie node1 server node2 127.0.0.1:8091 check cookie node2 server node3 127.0.0.1:8092 check cookie node3
The above configuration shows how to set up basic Xojo compatible load balancing (for standalone apps) and also how to set up different apps under different sub-hosts on the same server. Here are some things to notice:
The timeouts here are values that are working well for me. Feel free to play with them. If they are too low you will run into “Application went offline” messages.
This uses ACLs (Access Control List) to change backends depending on the hostname being requested. This allows you to set up multiple apps on the same server under different hostnames (e.g. app.hostname.com and otherapp.hostname.com). This feature is really powerful and flexible, just scratching the surface here. But this works great. You can have an unlimited number of ACLs/hosts/apps being routed here. The ACL rule names, host names and backend names can be whatever you want – these are just placeholders.
Set up a separate backend for every app you want to serve. This injects a cookie called “serverid” and assigns it a value of “node1”, “node2”, or “node3” depending on which backend app-instance it routes to. Once the cookie is set, haproxy routes subsequent requests from that user to the same app-instance, maintaining the session. Xojo also includes a “sessionid” cookie which it uses to maintain session.
Because Xojo web apps only utilize a single processor core per instance the total processing power of the server is underused. There is no multi-processor capability within the Xojo web app itself automatically. It requires either load balancing multiple app-instances or an app that uses helper processes. For me, this is the simpler solution. Once set up it is fairly trivial to multiply out an app’s capacity to take advantage of processors. This does not accelerate the app for any single user, but can make a substantial difference across multiple users.
In the previous post I covered a nice, easy way to handle startup and shutdown of multiple instances of an app across different server ports. Be sure to check that out as well.
Feel free to leave a comment here or on the Xojo Forum.