0

I am wanting to mimic a load balancer where if a person goes to

http://example.com/mysite

they will either be seeing the content of:

http://server2.example.com/mysite

or

http://server3.example.com/mysite

Using PHP I can randomly determine which site the user goes to, but how do I get that to display at http://example.com/mysite? Do I somehow use an iframe that takes up the entire height and width of the window? Or is there a way that would work better?

Basically, I want the user to only ever see http://example.com/mysite in the address bar and be oblivious as to which server they are viewing the page on. I don't mind if they look at the source code to see it, but I want to make sure the URL is the same.

The two sites make use of JavaScript (both server-side and client-side), PHP, and HTML. The sites make use of long-polling as well on the server-side JavaScript (Node).

Update

Thanks to Lawrence Cherone's suggestion I have implemented a load balancer in Apache as follows:

<VirtualHost *:80>
        ServerAdmin webmaster@example.com
        ServerName jpl.example.com

        ProxyRequests off

        <Proxy "balancer://mycluster">
                BalancerMember "http://203.0.113.22:3000"
                BalancerMember "http://203.0.113.23:3000"
        </Proxy>

        ProxyPass "/test/" "balancer://mycluster/"
        ProxyPassReverse "/test/" "balancer://mycluster/"

</VirtualHost>

Two remaining issues:

Issue 1

In order to allow for subdirectories I had to add a trailing slash to the ProxyPass and ProxyPassReverse lines.

This works to go from:

jpl.example.com/test/ => http://203.0.113.22:3000

jpl.example.com/test/subdir1/ => http://203.0.113.22:3000/subdir1/

jpl.example.com/test/subdir2/ => http://203.0.113.22:3000/subdir2/

But won't work if I leave off the trailing slash:

jpl.example.com/test

jpl.example.com/test/subdir1 

jpl.example.com/test/subdir2 

Any ideas how to get it to work if the user neglects to type in the trailing slash?

Issue 2

The second issue was becoming too convoluted so I moved it to its own question. The issue involves long polling no longer working because it cannot find socket.io.

unor
  • 92,415
  • 26
  • 211
  • 360
kojow7
  • 10,308
  • 17
  • 80
  • 135
  • Set up a proxy, so visiting `http://example.com/mysite` is forwarded to your other servers. – Lawrence Cherone Mar 23 '18 at 20:15
  • @LawrenceCherone Hmm, do you mean set up a proxy with PHP? The other sites make use of JavaScript for fetching data etc., so not sure that would fully work. – kojow7 Mar 23 '18 at 20:27
  • No, I mean a reverse proxy like [nginx](https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/), [caddy](https://caddyserver.com/docs/proxy) etc – Lawrence Cherone Mar 23 '18 at 20:29
  • @LawrenceCherone That sounds like something I'd have to research more. I am using Apache so would something on this page be what you are recommending: https://httpd.apache.org/docs/2.4/mod/mod_proxy_balancer.html – kojow7 Mar 23 '18 at 20:33
  • I am also needing to use long polling so would need something that would work with that too. – kojow7 Mar 23 '18 at 20:34
  • Yeah that would work too... yeah long polling will work. – Lawrence Cherone Mar 23 '18 at 20:34
  • Thank you. I will try out some experimentation. – kojow7 Mar 23 '18 at 21:59
  • @LawrenceCherone Thank you for your suggestion. It has opened my eyes up to a much better way to do this! I am, however, having two issues with this approach. The first issue is minor, the second issue is more important and have moved it to its own question. If you have any suggestions on how to deal with either of these please let me know. – kojow7 Mar 24 '18 at 20:22

3 Answers3

0

The below will iframe in the url of a site, based on a variable set in the URL, it could just as easily be a SESSION variable, ip address based, etc Is that what you're looking for?

<?php
//assuming your file is named index.php
  //index.php without user_criteria shows site 2
  ///index.php?user_criteria=tdorg shows site 1
$serverURL = (isset($_GET['user_criteria']) && $_GET['user_criteria'] == 'tdorg')?"http://trumpdonald.org/":"https://giphy.com/gifs/z48aJruaX0Jsk/embed"; 
//if the user criteria is set in the URL, use that.  Otherwise, default to url 1
?>
<iframe src="<?php echo $serverURL; ?>" width="100%" height="100%" />
pendo
  • 792
  • 2
  • 5
  • 27
0

If you are trying to build an actual load balancer, don't do it with PHP. Splitting the load of a server is a function of the server, not your application. But assuming there is some rational reason behind your question, I'll try to answer it.

Technically, you could just do this with a simple include :

<?php include 'http://'.$subdomain.'.example.com/mysite'; ?>

But that will not be performant since the page would be downloaded every time it is requested. Instead you may want to write the page to a file to cache it. So your php would do something like this pseudo code :

if cache file exists for this page
    get contents of file
    echo contents of file
else 
    get page from the other server
    write it to a cache file
    echo contents of file
Andrew Magill
  • 2,254
  • 4
  • 21
  • 28
0

In order to redirect to a website without it being visible to the user (in the adress bar) you can do the following:

  1. Make the server redirect to either server2 or server3. (Witch you've already done.)
  2. Inside the page you redirect to, insert this piece of JS code:
<script>
    window.history.pushState("", "[Title (ignored by most browsers)]", "[relative addres for the url you want to simulate (eg.: //example.com/mysite]");
</script>

When the page the server has redirected the browser to loads, this script will run, inserting the fake address to the address bar.

More info: Updating address bar with new URL without hash or reloading the page

PS.: Reloading the page will cause the fake addres to load. The forward an back navigation buttons in the browser may not work.

D. Pardal
  • 6,173
  • 1
  • 17
  • 37