Friday, August 14, 2015

Load balancing option for shared hosting scenario

I suppose things happen for a reason. A few weeks back, I set up a gmail account for my mom when she had asked about how to get started blogging. Finally, this evening, I sat down with her and showed her the ropes.  This came at a time when I had been googling for a few days on how to set up a simple Apache load balancer using mod_proxy and mod_proxy_balancer - so I figured, why not jot down a few lines in a blog myself?

The purpose was not so much to load-balance, but rather, to try and serve up the same pages, transparent to the user, in php and ruby , for example (and a third and fourth language, if necessary), and from the same machine. Why, you ask? Just because...! Well, in all seriousness, I did come across a good use case, when trying to transition a website from one language to another, maybe, as this guy had done. I could think of another academic use, to compare the speeds that certain tasks can be executed in specific languages that run our websites. But there was disappointment in store for me, I hadn't considered the fact that Apache configs are off-limits for shared hosting situations. At least that's how it is for BlueHost if you don't have a VPS or a dedicated host.

As I searched for alternatives, I stumbled upon Gearman. It's just a piece of software that divides up the workload of its client code into workers. Could this do what I was trying to do? Well, whether it did or not, first thing I would have to check is how to get it built and running on a shared host. Some more googling, and I found a page on installing Gearman from source - while it pointed me to the right dependencies, I could not install any of them like gperf, uuid, etc. So I set out to build all  the dependencies from their respective sources.

First, I downloaded gperf (watch out, not gperftools), and built it, and it went without a hitch

wget http://ftp.gnu.org/pub/gnu/gperf/gperf-3.0.4.tar.gz
tar xvzf gperf-3.0.4.tar.gz
cd gperf-3.0.4
./configure --prefix=<my home dir>
make

Then I had to build libuuid (couldn't wget  directly from sourceforge, so scp'd it after a local download), this one was easy too

tar xvzf libuuid-1.0.3.tar.gz
cd libuuid-1.0.3
./configure
make

I had to change the name of libuuid-1.0.3 directory to uuid for the next step to run.

The final step to build gearmand took quite a bit of trial and error, mainly to set the correct environmental variables, like CPPFLAGS, LDFLAGS, GPERF, that would make both configure and make happy. Without subjecting you to the pain, here's the final one that built gearmand and libgearman

wget https://launchpad.net/gearmand/1.2/1.1.11/+download/gearmand-1.1.11.tar.gz
tar xvzf gearmand-1.1.11.tar.gz
cd gearmand-1.1.11
GPERF="$HOME/pecl/gperf-3.0.4" CPPFLAGS="-I$HOME/pecl -L$HOME/pecl/lib" LDFLAGS="-L$HOME/pecl/lib" ./configure --prefix="$HOME/pecl" --exec-prefix="$HOME/pecl"
make
make install

Note: In my actual commands I didn't use $HOME, I typed in the full path for $HOME, but it should work too. In case there is an error, I am sure there will be some comments from visitors.
Also, pecl is the directory where I ran all the original tar commands from, and lib is a directory I created where I symlinked to the libuuid.so files created as a result of building libuuid. I realized later I could have directly used the location of .libs directory inside the uuid package. 'make install' put the binary gearmand in the $HOME/sbin directory, and the header files in $HOME/include. I had to manually create a $HOME/var/log directory before trying to run the program.

$HOME/sbin/gearmand --verbose DEBUG -d

Tailing the log told me it was running fine

tail -f $HOME/var/log/gearmand.log

With all the software thus built from source in my own directory, the only remaining thing was to build the shared library gearman.so so as to be able to use it from php.

wget https://pecl.php.net/get/gearman-1.1.2.tgz
tar xvzf gearman-1.1.2.tgz
cd gearman-1.1.2
phpize
GEARMAN_LIB_DIR=$HOME/pecl/lib GEARMAN_INC_DIR=$HOME/include ./configure
make

I copied gearman.so from gearman-1.1.2/modules to my php extension directory $HOME/php/extensions (check your php.ini file to find out what yours is), and added the following line to php.ini

extension=gearman.so

Now, to check if I can call this from a simple php page like so

cat > gearman_check.php
<?php
print gearman_version() . "\n";
?>

Run the simple program from the command prompt

<command-prompt> # php gearman_check.php
Content-type: text/html

1.1.12

That works. 
The load balancing code will be for another episode.