Xojo Web App with load balancer
Recently I had to run a Xojo web app on a server for a client. We wanted to run four copies at once and distribute all users to them equally. Let me document how I do this for future installations.
We installed apache2 on the Linux machine:
sudo apt update sudo apt install apache2 -y
Then we enable the required modules:
sudo a2enmod proxy sudo a2enmod proxy_http sudo a2enmod proxy_balancer sudo a2enmod lbmethod_byrequests sudo a2enmod headers
We enable the proxy, the balancer and lbmethod_byrequests, the the default load-balancing algorithm (round robin based on request count).
Then we add this to the VirtualHost entry for our website, usually a subdomain. We use a different subdomain for each web app running on the same server. In the proxy settings we let all requests go to the cluster and have the module rewrite all returning links back to the main page. We store the route picked in a cookie, so follow up requests go to the same application.
Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED
<Proxy "balancer://mycluster">
BalancerMember "http://localhost:8081" route=1
BalancerMember "http://localhost:8082" route=2
BalancerMember "http://localhost:8083" route=3
BalancerMember "http://localhost:8084" route=4
ProxySet stickysession=ROUTEID
</Proxy>
ProxyPass "/" "balancer://mycluster/"
ProxyPassReverse "/" "balancer://mycluster/"
We have a start script in /var/www/WebTest/start and then we can use it with a cron job our web apps.
#!/bin/bash
# List of ports to use
ports=(8081 8082 8083 8084)
# Path to the executable
app="/var/www/WebTest/WebTest"
# Common options
opts="--NetworkInterfaceIndex Loopback --SecureNetworkInterfaceIndex Loopback"
# Timestamp function
timestamp() {
date +"[%Y-%m-%d %H:%M:%S]"
}
echo "$(timestamp) Checking ports and starting WebTest where needed..."
for port in "${ports[@]}"; do
# Check if the port is already in use (listening)
if ss -ltn | awk '{print $4}' | grep -q ":$port$"; then
echo "Port $port is already in use. Skipping..."
else
echo "Starting WebTest on port $port..."
sudo "$app" $opts --port="$port" &
sleep 1 # small delay to avoid race conditions
fi
done
This script will check if the WebTest app runs already on each port and launch it if needed. We can run this via crontab, so every minute we check if one crashed and restart it.
if everything works, the system will run our cronjob. To add it, we first make sure the script is executable:
sudo chmod 755 /var/www/WebTest/start
Then we open the crontab file for editing:
sudo crontab -e
And we add a new entry to launch the script every 5 minutes and redirect output to a log file:
*/5 * * * * /var/www/WebTest/start >> /var/log/start_webtest.log 2>&1
This should do it. You may check the configuration with
sudo crontab -land then wait 5 minutes to see if the log file gets created.
We can watch the log file being modified:
tail -f /var/log/start_webtest.log
If someone tries it (me in a few months?), please let me know whether this works fine. If not, we can update this for the future.