Shell scripting in php to balance your load

19 Apr

It was an issue while I was working with an API module in Magento. I really like the environment and the PHP ticks they used in their development especially I become a great fan of Factory Pattern now.

I had an API call to complete the checkout from a remote server using Magento API and the checkout process executes another 10 to 12 API calls in another server to complete the total process.So see the scenario here.

API CALL Diagram

But, above system will not complete anymore because it will take time more than PHP Maximum execution time.

Then, I have decided to open a new process in Linux with shell script and assign the next API calls there. Checkout API function return after triggering that new process for the further task. The new process execute on its ways and do necessary update in database and then die by itself.

We can do that with a simple Shell call from PHP. Like:

 bash shellscript.sh  Arg1 Arg2


It’s a simple command to run a shell script from command line with command line arguments. But main problem I faced is… to make PHP Asynchronous.
We’ve lots of functions to execute command line instruction like bellow:
exec(), shell_exec(), system(), “

None of these functions will server this problem. All these functions wait until capture any response. But we have to open a new process and have to return leaving on its way.

So I have used the following example. Here we have opened a new process and close it as well:

Proc_Close(Proc_Open ("bash c2m.sh 4 1_2_3_4_5 &", Array (), $foo));


I have added an ampersand(&) that means I don’t care it’s return value.

Rest of the task is pretty simple. In Shell script we capture the command like argument with $0, $1, $2 … etc and we can execute an PHP script in command like bellow

#!/usr/bin/bash

`php myscript.php $1` 


This command run myscript.php and send a command line arguments. All command line argument saved in a PHP variable called $argv

Always use a back quote(`) to execute a php file in shell script if you want to store the output in a variable.
See the following example:

#!/usr/bin/bash

result=`php myscript.php $item_id`

echo "$result"


This is how you can pass your load in Linux to execute command line to get relief from time expire issue. 🙂

Download Example source code from here

Advertisements

8 Responses to “Shell scripting in php to balance your load”

  1. Rumana April 19, 2010 at 12:49 pm #

    Fantastic, very helpful

    Thanks, Reza vi to share this

  2. Tanveer April 19, 2010 at 12:58 pm #

    Woow!! nice article.
    😉

  3. Dream Coder April 19, 2010 at 1:02 pm #

    nice post. thanks for sharing with us.

  4. Tanveer April 19, 2010 at 1:04 pm #

    One thing if you are using two process with proc_close then you must close the second one first other wise it will hang your pc 😉

    example:
    ===========

    array(‘pipe’, ‘r’), 1 => array(‘pipe’, ‘r’)), $pipes1);
    echo(‘Opening process 2’.”\n”);
    $process2 = proc_open(‘cat’, array(0 => array(‘pipe’, ‘r’), 1 => array(‘pipe’, ‘r’)), $pipes2);

    // WORKS :

    //echo(‘Closing process 2’.”\n”);
    //fclose($pipes2[0]); fclose($pipes2[1]); proc_close($process2);
    //echo(‘Closing process 1’.”\n”);
    //fclose($pipes1[0]); fclose($pipes1[1]); proc_close($process1);

    // DOESN’T WORK :

    echo(‘Closing process 1’.”\n”);
    fclose($pipes1[0]); fclose($pipes1[1]); proc_close($process1);
    echo(‘Closing process 2’.”\n”);
    fclose($pipes2[0]); fclose($pipes2[1]); proc_close($process2);
    ?>

  5. Rubel April 19, 2010 at 1:13 pm #

    @Tanveer
    That really nice point.

    It’s a best practice for multiple process, we may use a temporary variable to store the pointer then close it in next line .

  6. kodegeek April 20, 2010 at 12:17 pm #

    Great Job Reza, it’s nice stuff to balance server load sometimes. Btw – when i hit the first script using browser, nothing happen, but if i hit the first script from shell, it works well. It happens on Mac, any idea?

    • Rubel April 21, 2010 at 2:47 am #

      @kidegeek
      Thnx for your comments.
      Ahh… As it’s already running in command line then you can check following scenario:
      Path Problem: If it’s path problem try to navigate on specific location will shell command. I faced such problem in my production server. Simple add following command at the begin of .sh shell script

      cd PHP_FILE_PATH like cd/home/site/public_html

      Permission: See if you have necessary permission to run shell command from browser.

  7. Jon Hulka September 14, 2011 at 9:15 pm #

    Exactly what I was looking for. I used this to run curl in the background.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: