Xojo Conferences
MBSOct2019CologneDE
XDCMarch2020NashvilleUS

« MBS Xojo Plugins, ver… | Home | Free tickets for stud… »

Simple load balancer for Xojo Web app


Recently we implemented some web applications for a client. We use cgi deployment with a linux server running apache, so the apache can handle the SSL stuff. If you have 20 people on one instance, it may get a bit slow for each user. To improve performance, we installed the application several times on the web server. For this we build the app several times with different app names and different identifiers. So we have MyApp1, MyApp2, MyApp3 and MyApp4. All have an unique identifier like com.company.myapp1 to 4. You can easily build that with a build script automatically.

 

Once you have all 4 copies of the app on the web server, you may need a little load balancing script. But first, each instance must be able to tell how many sessions it has, so we got a status query for the HandleSpecialURL event. The simple version looks like this:

 

EventHandler Function HandleSpecialURL(Request As WebRequest) As Boolean

#Pragma BackgroundTasks False

if Request.Path = "Status" then

Dim j As New JSONItem

Dim a As app = app

j.Value("MemoryUsed") = runtime.MemoryUsed

j.Value("ObjectCount") = runtime.ObjectCount

j.Value("SessionCount") = a.SessionCount

j.Value("Name") = a.ExecutableFile.Name

Request.Print j.ToString

return true

end if

End EventHandler

 

The actual version for the client does much more like being able to do authorization and list the sessions in detail, so the admin can see in a nice tool what webpages are currently being used. Anyway, once you can query session count from outside, you can use that in a script to distribute people. We got this script for you:

 

#!/usr/bin/php

<?php

 

// simply http query and return answer

function get_content($URL)

{

      $ch = curl_init();

      curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

      curl_setopt($ch, CURLOPT_URL, $URL);

      $data = curl_exec($ch);

      curl_close($ch);

      return $data;

}

 

// Fallback URL if all are unreachable

$bestURL = "http://webapps.monkeybreadsoftware.de/offline.html";

$bestSessionCount = 9999;

 

for ($x = 1; $x <= 4; $x++) 

{

$StatusURL = "http://webapps.monkeybreadsoftware.de/MyApp".$x."/myapp.cgi";

$JSON = get_content($StatusURL."/api/status");

 

if (strlen($JSON) > 0)

{

$j = json_decode($JSON, true);

if ($j == NULL)

{

// Server answer not JSON!?

}

else

{

$SessionCount = $j["SessionCount"];

if ($SessionCount < $bestSessionCount)

{

$bestURL = $StatusURL;

$bestSessionCount = $SessionCount;

}

}

}

}

 

# redirect to best match

header('Location: '.$bestURL);

?>

 

This could be saved as index.php in a folder, so you can redirect people there without the index.php in the URL. The script has a fallback URL to go to when all applications are offline. This doesn't happen often, but it can happen. The script queries status for all 4 and looks for the URL with the smallest number of sessions. On the end we just redirect to the new location with the application.

 

We ask user to use a start URL like http://webapps.monkeybreadsoftware.de/ and that will trigger index.php and redirect to the final app like http://webapps.monkeybreadsoftware.de/MyApp1/myapp.cgi URL.

 

If you have questions, please do not hesitate to contact us. We'll include the sample with future plugin examples.

03 03 19 - 19:07
two comments

Wow!

This is just what I was looking for!

As a web app scales up, degrading speed as users count goes up is a serious concern.

In order to better take advantage of this solution, how should one go about deploying the libraries?
A typical Xojo Web App cgi deployment looks like this inside the ‘cgi-bin’ folder:

‘mywebapp Libs’ Folder
‘mywebapp Resources’ Folder
.htaccess
‘config.cfg’
‘mywebapp’
‘mywebapp.cgi’

I have not tested it, but it appears to me that one can either have several ‘Libs’ and ‘Resources’ folders named accordingly to each ‘.cgi’ file and have several ‘config.cfg’ named as ‘config1.cfg’, ‘config2.cfg’ and so on… That also demands changes inside ‘mywebapp.cgi’ files to address references to ‘config.cfg’, right?

Taking this approach a little further, is it possible to make changes inside the cgi scripts in order to avoid having several ‘Lib’ and ‘Resources’ folders?
Leonidas Brasileiro (URL) - 08 03 19 - 12:12

We simply make a separate folder of each instance on the Webserver.
The files can be hard links, maybe even symbolic links to reduce disk space. We simply didn’t care.
We renamed the cgi file to be index.cgi and made apache use index.cgi if no file name is given.

This way we have just the urls:

webapps.domain.com/
webapps.domain.com/app1/
webapps.domain.com/app2/
webapps.domain.com/app3/
webapps.domain.com/app4/

and you go on the first URL and than you are sent to one of the following folders.
Christian Schmitz (URL) - 08 03 19 - 13:31


  
Remember personal info?

Emoticons / Textile


Notify:
Hide email:

Small print: All html tags except <b> and <i> will be removed from your comment. You can make links by just typing the url or mail-address.