<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Justin Carmony &#187; Tips and Tricks</title>
	<atom:link href="http://www.justincarmony.com/blog/tag/tips-and-tricks/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.justincarmony.com/blog</link>
	<description>Web Designer &#38; Software Engineer</description>
	<lastBuildDate>Wed, 01 Feb 2012 04:30:16 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Debugging Nginx Configuration Trick</title>
		<link>http://www.justincarmony.com/blog/2012/01/13/debugging-nginx-configuration-trick/</link>
		<comments>http://www.justincarmony.com/blog/2012/01/13/debugging-nginx-configuration-trick/#comments</comments>
		<pubDate>Sat, 14 Jan 2012 02:24:49 +0000</pubDate>
		<dc:creator>Justin Carmony</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[syste]]></category>
		<category><![CDATA[Tips and Tricks]]></category>

		<guid isPermaLink="false">http://www.justincarmony.com/blog/?p=1081</guid>
		<description><![CDATA[Today I had an issue where I was trying to debug a problem with an nginx configuration, I came up with a simple trick. One of the hardest parts of nginx configurations, especially with rewrites, is you might not know which &#8220;location&#8221; directive is not working as expected. In PHP, sometimes you would just add ...


Related posts:<ol><li><a href='http://www.justincarmony.com/blog/2011/01/24/php-nginx-and-output-flushing/' rel='bookmark' title='PHP, Nginx, and Output Flushing'>PHP, Nginx, and Output Flushing</a></li>
<li><a href='http://www.justincarmony.com/blog/2011/10/24/setting-up-nginx-php-fpm-on-ubuntu-10-04/' rel='bookmark' title='Setting Up Nginx &amp; PHP-FPM on Ubuntu 10.04'>Setting Up Nginx &#038; PHP-FPM on Ubuntu 10.04</a></li>
<li><a href='http://www.justincarmony.com/blog/2011/05/31/simple-trick-history-command/' rel='bookmark' title='Simple Trick: History Command'>Simple Trick: History Command</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Today I had an issue where I was trying to debug a problem with an <a href="http://nginx.org/">nginx</a> configuration, I came up with a simple trick. One of the hardest parts of nginx configurations, especially with rewrites, is you might not know which &#8220;location&#8221; directive is not working as expected.</p>
<p>In PHP, sometimes you would just add something like this:</p>
<pre class="brush: php; title: ; notranslate">
echo &quot;I'm here!&quot;;
exit();
</pre>
<p>However, in Nginx configuration files, it isn&#8217;t as easy&#8230;</p>
<p>&#8230; or is it?</p>
<p>One thing that works well is the rewrite directive. You can append variables to the URL to be rewritten. Another great thing is a rewrite statement can go just about anywhere. So lets say we were trying to debug this location statement:</p>
<code class="code">location ~ /api/.*\.php$ {
    include /etc/nginx/fastcgi_params;
    fastcgi_pass  127.0.0.1:9000;
    fastcgi_index index.php;
    fastcgi_param  SCRIPT_FILENAME  /path/to/www/$fastcgi_script_name;
}</code>
<p>Now lets say its returning a 404, and I&#8217;m not 100% sure what the actual value of $fastcgi_script_name is. I can add this to it:</p>
<code class="code">location ~ /api/.*\.php$ {
    ## ADD HERE
    redirect ^ http://www.google.com/?q=$fastcgi_script_name last; break;
    include /etc/nginx/fastcgi_params;
    fastcgi_pass  127.0.0.1:9000;
    fastcgi_index index.php;
    fastcgi_param  SCRIPT_FILENAME  /path/to/www/$fastcgi_script_name;
}</code>
<p>This will redirect your HTTP request to Google.com and put the value in the query textfield. Bingo, I can easily see the actual value! Pretty helpful when you have a large, complex server definition.</p>


<p>Related posts:<ol><li><a href='http://www.justincarmony.com/blog/2011/01/24/php-nginx-and-output-flushing/' rel='bookmark' title='PHP, Nginx, and Output Flushing'>PHP, Nginx, and Output Flushing</a></li>
<li><a href='http://www.justincarmony.com/blog/2011/10/24/setting-up-nginx-php-fpm-on-ubuntu-10-04/' rel='bookmark' title='Setting Up Nginx &amp; PHP-FPM on Ubuntu 10.04'>Setting Up Nginx &#038; PHP-FPM on Ubuntu 10.04</a></li>
<li><a href='http://www.justincarmony.com/blog/2011/05/31/simple-trick-history-command/' rel='bookmark' title='Simple Trick: History Command'>Simple Trick: History Command</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.justincarmony.com/blog/2012/01/13/debugging-nginx-configuration-trick/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP Workers with Redis &amp; Solo</title>
		<link>http://www.justincarmony.com/blog/2012/01/10/php-workers-with-redis-solo/</link>
		<comments>http://www.justincarmony.com/blog/2012/01/10/php-workers-with-redis-solo/#comments</comments>
		<pubDate>Tue, 10 Jan 2012 18:20:10 +0000</pubDate>
		<dc:creator>Justin Carmony</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Videos]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[redis]]></category>
		<category><![CDATA[solo]]></category>
		<category><![CDATA[Tips and Tricks]]></category>
		<category><![CDATA[workers]]></category>

		<guid isPermaLink="false">http://www.justincarmony.com/blog/?p=1072</guid>
		<description><![CDATA[I&#8217;ve come across an awesome combination of tools for managing PHP Workers, and thought I&#8217;d share. Why Workers? Sometimes there are situations when you want to parallel process things. Other times you might have a list of tasks to accomplish, and you don&#8217;t want to make the user wait after pressing a button. This is ...


Related posts:<ol><li><a href='http://www.justincarmony.com/blog/2011/05/23/mysql-redis-and-a-billion-rows-a-love-story/' rel='bookmark' title='MySQL, Redis, and a Billion Rows &#8211; A Love Story'>MySQL, Redis, and a Billion Rows &#8211; A Love Story</a></li>
<li><a href='http://www.justincarmony.com/blog/2011/01/07/creating-chatroom-walls-with-redis-and-php/' rel='bookmark' title='Creating Chatroom / Walls with Redis &amp; PHP'>Creating Chatroom / Walls with Redis &#038; PHP</a></li>
<li><a href='http://www.justincarmony.com/blog/2011/01/10/debugging-with-php-stack-traces-and-redis/' rel='bookmark' title='Debuging with PHP, Stack Traces, and Redis'>Debuging with PHP, Stack Traces, and Redis</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve come across an awesome combination of tools for managing PHP Workers, and thought I&#8217;d share.</p>
<h3>Why Workers?</h3>
<p>Sometimes there are situations when you want to parallel process things. Other times you might have a list of tasks to accomplish, and you don&#8217;t want to make the user wait after pressing a button. This is where &#8220;Workers&#8221; can come in. They are independent scripts that run along side of your application, performing tasks, or &#8220;jobs.&#8221; </p>
<p>An example is with Dating DNA and our score system. We generate scores between users to show how compatible they are with each other. When a user signs up, or makes a significant change to their profile questionnaire, we need to run a job to query our database, build a list of potential users, and generate scores. This takes 10-20 seconds, and while it is pretty fast, we don&#8217;t want to make the user wait for that. So we queue up a job for the user, divide up the work among several workers, and process the work.</p>
<h3>General Concept</h3>
<p>For this post, we&#8217;ll use the example of generating reports. Lets say on your internal website there is a button that you can click and it will email the user a report, and the report takes 2-3 minutes to generate. When the button is clicked, your code will insert the job into the queue. Meanwhile, workers are monitoring the queue. A worker script will pull the job off the queue, process the report, and send the email when its done.</p>
<p>For the queue management, we&#8217;ll use Redis. To let PHP read and write data to Redis, we&#8217;ll use the PHP Library <a href="https://github.com/nrk/predis">predis</a>. In our examples we&#8217;ll use PHP 5.3, however predis has a PHP 5.2 backport if you are not running 5.3.</p>
<h3>Adding Jobs</h3>
<p>To add jobs, we&#8217;ll need to connect to our Redis server:</p>
<pre class="brush: php; title: ; notranslate">
/*
 * Connecting to Redis
 */

const REDIS_HOST = '127.0.0.1';
const REDIS_PORT = 6379;

$predis = new Predis\Client(array(
    'scheme' =&gt; 'tcp',
    'host'   =&gt; REDIS_HOST,
    'port'   =&gt; REDIS_PORT,
));
</pre>
<p>We&#8217;ll assume in all of our examples that we&#8217;ve done the following above &#038; connected to Redis. <span id="more-1072"></span></p>
<p>Now, to manage our queues we&#8217;ll use the Redis Datatype LIST. Whats awesome about lists is that regardless of size, adding or removing at the start or end of a list is extremely fast. So if your queue has 10 items, or 10,000,000 items, Redis wil be able to push and pop entries quickly.</p>
<p>We&#8217;ll have three queues, one for each priority: high, normal, and low. For the Redis key names, we&#8217;ll use queue.priority.high, queue.priority.normal, etc. When interacting with lists, you work with the ends, one called right, the other called left. So we&#8217;ll add items on the right with the RPUSH (Right Push) command, and we&#8217;ll pull items off the left with the BLPOP (Blocking Left Pop) command. We won&#8217;t worry about the pulling items just yet.</p>
<p>You store strings as the values for the list. My personal preference is to store JSON objects so you can easily pass variables needed to perform the job.</p>
<pre class="brush: php; title: ; notranslate">
/*
 * Adding items to the queue
 */

$job = new stdClass();
$job-&gt;id = 1;
$job-&gt;report = 'general';
$job-&gt;email = 'test@example.com';

// Add the job to the high priority queue
$predis-&gt;rpush('queue.priority.high', json_encode($job));

// Or, you could add it to the normal or low priority queue.
$predis-&gt;rpush('queue.priority.normal', json_encode($job));
$predis-&gt;rpush('queue.priority.low', json_encode($job));
</pre>
<p>Simple enough! Having different queue priorities is very beneficial in managing which jobs should get done first. For example, you might have an Executive&#8217;s request go into the high priority queue so they get the report quickly. You might also have a weekly cron that queues up reports to be sent automatically, so those can go in the low priority as to not disrupt people trying to get a manual report.</p>
<p>Now, on to the worker&#8217;s code.</p>
<h3>Processing Jobs</h3>
<p>For now, lets say we have a script running in the PHP CLI (Command Line Interface) that you started by running this command on the server:</p>
<code class="code">php /path/to/worker.php</code>
<p>First thing is we want this worker to work continuously, so we can do a while loop:</p>
<pre class="brush: php; title: ; notranslate">
/*
 * Simple Continuous While Loop
 */

// Always True
while(1)
{
	/* ... perform tasks here ...  */
}
</pre>
<p>We&#8217;ll worry about making them more intelligent later. Now, let&#8217;s have our worker check the queue. You can do so with the BLPOP command:</p>
<pre class="brush: php; title: ; notranslate">
/*
 * Checking the Queue
 */
$job = $predis-&gt;blpop('queue.priority.high'
						, 'queue.priority.normal'
						, 'queue.priority.low'
						, 10);
</pre>
<p>What we&#8217;re telling PHP to do is to check each queue in order of priority: high, normal, and then low. If it finds an item, it will immediately return an array with the name of the queue it came from, and the string of data that was pulled.</p>
<p>The B in BLPOP is &#8220;blocking.&#8221; What that means is that Redis will wait until either an item enters one of the queues, or the timeout is reached. In this case, the timeout is 10 seconds. So instead of polling (checking every few seconds in a loop), we check and wait, and after 10 seconds it will return null and we can check again.</p>
<p>What this gives us is near instantaneous queues. As soon as something is available, it is passed to the workers that are listening. You can also have multiple workers, and it will pass jobs to the first listening worker, and the next job to the next worker, so you don&#8217;t have to worry about multiple workers getting the same queued item.</p>
<p>After $predis->blpop() returns, if it has an array, it returned an item. If not, the timeout had been reached. We can check to see if a Job was returned, and if so to process the job:</p>
<pre class="brush: php; title: ; notranslate">
/*
 * Checking to see if a Job was returned
 */

if($job)
{
	// Index 0 of the array holds which queue was returned
	$queue_name = $job[0];
	// Index 1 of the array holds the string value of the job.
	// Since we are passing it JSON, we'll decode it:
	$details = json_decode($job[1]);

	/* ... do job work ... */
}
</pre>
<p>Now we can have multiple workers listening to the same queues and scale our workload. Redis is very fast &#038; efficient, and you could have hundreds or even thousands of workers listening to a single redis server.</p>
<h3>Continuously Running Workers</h3>
<p>There are a lot of options when it comes to deploying these workers. You can use a framework like Gearman, but for simple things, I like very simple solutions. I came across a <a href="http://josephscott.org/archives/2011/09/solo/">blog post by Joseph Scott</a> about a little 10 line perl script called <a href="http://timkay.com/solo/solo">solo</a>. What it does is it will run a command, and to ensure that no one else is running that same exact command, it will lock a configurable port. This is awesome because the you don&#8217;t have to work about lock files or filesystem tricks, the kernel handles it all. </p>
<p>So what you can do is create a cronjob using solo to execute your script. First copy solo somewhere, I put it in my /usr/local/bin on my linux server. Then add this to your cron job using the command &#8220;crontab -e -u (which user to use)&#8221;:</p>
<code class="code">* * * * * /usr/local/bin/solo -port=5001 php /path/to/worker.php</code>
<p>What this will do is try to run this command every minute. Solo will check to see if the port is already in use, and if it is, it will exit. Otherwise, it will lock the port and then execute the command. The port will stay locked as long as the command is executing. Once the command terminates, the port will unlock.</p>
<p>Now, PHP is a great language, but it has been known to have some memory leaks while running a long time in a single instance. So we can have our scripts exit periodically to be restarted by our cron job. So lets make our &#8220;while(1)&#8221; statement a little smarter:</p>
<pre class="brush: php; title: ; notranslate">
/*
 * A Smarter While Statement
 */

// Set the time limit for php to 0 seconds
set_time_limit(0);

/*
 * We'll set our base time, which is one hour (in seconds).
 * Once we have our base time, we'll add anywhere between 0
 * to 10 minutes randomly, so all workers won't quick at the
 * same time.
 */
$time_limit = 60 * 60 * 1; // Minimum of 1 hour
$time_limit += rand(0, 60 * 10); // Adding additional time

// Set the start time
$start_time = time();

// Continue looping as long as we don't go past the time limit
while(time() &lt; $start_time + $time_limit)
{
	/* ... perorm BLPOP command ... */
	/* ... process jobs when received ... */
}

/* ... will quit once the time limit has been reached ... */
</pre>
<p>One key thing to note is randomly shifting the time limit for the script. I like to do this because you don&#8217;t want your workers all stopping and starting at the same time. So if I have 8 workers, one might, but the 7 will continue until the 8th starts back up again via the cron job.</p>
<h3>Bells &#038; Whistles</h3>
<p>After using workers for awhile, here are a couple of ideas to enhance your workers &#038; system managing them. First off, you can add some monitoring for your queues. Using Redis a HASH, you can use them to store the state of your workers. </p>
<pre class="brush: php; title: ; notranslate">
/*
 * Assigning Worker IDs &amp; Monitoring
 *
 * Usage: php worker.php 1
 */

// Gets the worker ID from the command line argument
$worker_id = $argv[1];

// Setting the Worker's Status
$predis-&gt;hset('worker.status', $worker_id, 'Started');

// Set the last time this worker checked in, use this to
// help determine when scripts die
$predis-&gt;hset('worker.status.last_time', $worker_id, time());
</pre>
<p>Another problem with workers that run for a long time (several hours) is when you make a change to their code, they won&#8217;t reload that change until they exit. What I&#8217;ve found to successfully restart them is having a &#8220;version&#8221; number set in Redis that is checked at the end of every loop:</p>
<pre class="brush: php; title: ; notranslate">
/*
 * Using Versions to Check for Reloads
 */

$version = $predis-&gt;get('worker.version'); // i.e. number: 6

while(time() &lt; $start_time + $time_limit)
{
	/* ... check for jobs and process them ... */

	/* ... then, at the very end of the while ... */
	if($predis-&gt;get('worker.version') != $version)
	{
		echo &quot;New Version Detected... \n&quot;;
		echo &quot;Reloading... \n&quot;;
		exit();
	}
}
</pre>
<p>You would simply INCR (increment) worker.version and after finishing their last job, the worker would exit, and solo would start it up again.</p>
<p>You can also kill specific threads by having them check for their value in a hash:</p>
<pre class="brush: php; title: ; notranslate">
/*
 * Using Kill Switches to Check for Reloads
 */

while(time() &lt; $start_time + $time_limit)
{
	/* ... check for jobs and process them ... */

	/* ... then, at the very end of the while ... */
	// Check to see if a kill has been set.
	if($predis-&gt;hget('worker.kill', $worker_id))
	{
		// Make sure to unset the kill request before exiting, or
		// your worker will just keep restarting.
		$predis-&gt;hdel('worker.kill', $worker_id);

		echo &quot;Kill Request Detected... \n&quot;;
		echo &quot;Reloading... \n&quot;;
		exit();
	}
}
</pre>
<h3>Tweak to Solo &#038; Logging </h3>
<p>I made one small tweak in my version of solo, and that was to help it enable logging. Lets say I had three workers in my crontab:</p>
<code class="code"># crontab for user to run workers
* * * * * /usr/local/bin/solo -port=5001 php /path/to/worker.php 1 &gt;&gt; /tmp/worker.log.1
* * * * * /usr/local/bin/solo -port=5002 php /path/to/worker.php 2 &gt;&gt; /tmp/worker.log.2
* * * * * /usr/local/bin/solo -port=5003 php /path/to/worker.php 3 &gt;&gt; /tmp/worker.log.3</code>
<p>The &#8220;>> /tmp/worker.log.1&#8243; tells solo I want to log it&#8217;s output to a tmp file that I can tail and monitor their progress. This is great for debugging problems. However, when I did this, solo would write to the tmp file, and not the output from my script. To overcome this I changed the last line of solo:</p>
<pre class="brush: perl; title: ; notranslate">
# old
exec @ARGV;
# new
exec &quot;@ARGV&quot;;
</pre>
<p>This would ensure my script wrote out to the tmp file, and not just solo.</p>
<h3>Examples</h3>
<p>I&#8217;ve created an <a href="https://github.com/JustinCarmony/PHP-Workers-with-Redis-Solo-Examples">example on GitHub</a> that you can clone on your own machine. All you will need is PHP 5.3 and Redis installed.</p>
<p>To install redis, simple run these commands on your unix based system:</p>
<code class="code">wget http://redis.googlecode.com/files/redis-2.4.5.tar.gz
tar -xzvf redis-2.4.5.tar.gz
cd redis-2.4.5
make
make install</code>
<p>It will copy the redis binaries to /usr/local/bin.</p>
<p>To get a copy of the code, you can <a href="https://github.com/JustinCarmony/PHP-Workers-with-Redis-Solo-Examples/zipball/master">download them here</a>. <strong>HOWEVER, it doesn&#8217;t include predis! You&#8217;ll have to download and copy predis inside there via this link.</strong> It is much easier to clone it as so:</p>
<code class="code">git clone git://github.com/JustinCarmony/PHP-Workers-with-Redis-Solo-Examples.git php_example/
cd php_example
git submodule init
git submodule update</code>
<p>Then, using different terminal windows (or using screen), you can run different worker.php instances, use creator.php to insert jobs, and monitor.php to watch the progress. This is all done from the command line.</p>
<p>If you&#8217;re using windows, I suggest installed a VM of Ubuntu and using that. If you really want to use Redis on windows, there are some Windows Binaries you can google and download. Good luck!</p>
<p>Here is a video where I demo the example:</p>
<p><iframe width="640" height="480" src="http://www.youtube.com/embed/jhgGhBgY14U?hd=1" frameborder="0" allowfullscreen></iframe></p>
<p>(sorry for the poor mic quality)</p>
<h3>Final Thoughts</h3>
<p>I&#8217;ll post here shortly about how to run Redis in production with the init.d scripts and configuration files. One caveat to using solo is if your server has an application that randomly selects ports to use (i.e. VoIP, FTP), it might select one of your worker&#8217;s ports. But on a production server, you should have a good feel for which ports are available for locking.</p>
<p>If you want to learn more about Redis, <a href="http://redis.io/">check out their website</a>.  </p>
<p>Hopefully this will be helpful for anyone looking to use PHP Workers in an easy, simple way.</p>


<p>Related posts:<ol><li><a href='http://www.justincarmony.com/blog/2011/05/23/mysql-redis-and-a-billion-rows-a-love-story/' rel='bookmark' title='MySQL, Redis, and a Billion Rows &#8211; A Love Story'>MySQL, Redis, and a Billion Rows &#8211; A Love Story</a></li>
<li><a href='http://www.justincarmony.com/blog/2011/01/07/creating-chatroom-walls-with-redis-and-php/' rel='bookmark' title='Creating Chatroom / Walls with Redis &amp; PHP'>Creating Chatroom / Walls with Redis &#038; PHP</a></li>
<li><a href='http://www.justincarmony.com/blog/2011/01/10/debugging-with-php-stack-traces-and-redis/' rel='bookmark' title='Debuging with PHP, Stack Traces, and Redis'>Debuging with PHP, Stack Traces, and Redis</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.justincarmony.com/blog/2012/01/10/php-workers-with-redis-solo/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Siege with User Authentication</title>
		<link>http://www.justincarmony.com/blog/2011/11/03/siege-with-user-login/</link>
		<comments>http://www.justincarmony.com/blog/2011/11/03/siege-with-user-login/#comments</comments>
		<pubDate>Thu, 03 Nov 2011 16:33:02 +0000</pubDate>
		<dc:creator>Justin Carmony</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[OS X]]></category>
		<category><![CDATA[siege]]></category>
		<category><![CDATA[Tips and Tricks]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[unix]]></category>

		<guid isPermaLink="false">http://www.justincarmony.com/blog/?p=1043</guid>
		<description><![CDATA[If you want to stress test your application, the quickest and best way to do so is with siege. From the siege website: Siege is an http load testing and benchmarking utility. It was designed to let web developers measure their code under duress, to see how it will stand up to load on the ...


Related posts:<ol><li><a href='http://www.justincarmony.com/blog/2010/07/14/setting-up-ssh-key-authentication-between-servers/' rel='bookmark' title='Setting up SSH Key Authentication Between Servers'>Setting up SSH Key Authentication Between Servers</a></li>
<li><a href='http://www.justincarmony.com/blog/2008/10/10/local-lamp-developement-user-content/' rel='bookmark' title='Local LAMP Developement &amp; User Content'>Local LAMP Developement &#038; User Content</a></li>
<li><a href='http://www.justincarmony.com/blog/2009/11/27/my-php-user-group-experience/' rel='bookmark' title='My PHP User Group Experience'>My PHP User Group Experience</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>If you want to stress test your application, the quickest and best way to do so is with <a href="http://www.joedog.org/index/siege-home">siege</a>. From the siege website:</p>
<blockquote><p>Siege is an http load testing and benchmarking utility. It was designed to let web developers measure their code under duress, to see how it will stand up to load on the internet. Siege supports basic authentication, cookies, HTTP and HTTPS protocols. It lets its user hit a web server with a configurable number of simulated web browsers. Those browsers place the server &#8220;under siege.&#8221;</p></blockquote>
<p>On Linux, you can install it easily via yum or apt. On OS X, you can install it easily via <a href="http://mxcl.github.com/homebrew/">homebrew</a> or <a href="http://www.macports.org/">macports</a>. I personally prefer homebrew. In your terminal just type:</p>
<code class="code">brew install siege</code>
<p>Now you can stress test a given app by simply using the siege command:</p>
<code class="code">siege -c 10 -n 10 http://www.example.com/</code>
<p>You can read the <a href="http://www.joedog.org/index/siege-manual">documentation</a> and <a href="http://www.joedog.org/index/siege-faq">faq</a> on their site to learn more. However, there is one question I get a lot when talking about siege: &#8220;How can I use siege to test users who are logged in?&#8221;</p>
<p>I would always recommend that they send a session header in the config, but today I learned there is an even easier way (although undocumented), thanks to <a href="http://serverfault.com/questions/292679/stress-login-area-with-siege">this question in Server Fault</a>. In your siege&#8217;s configuration you can add the login-url directive:</p>
<code class="code"># Login URL. This is the first URL to be hit by every siege
# client. This feature was designed to allow you to login to 
# a server and establish a session. It will only be hit once
# so if you need to hit this URL more then once, make sure it
# also appears in your urls.txt file.
#
# ex: login-url = http://eos.haha.com/login.jsp POST name=jeff&amp;pass=foo
#
# login-url =</code>
<p>Awesome! Now each connection will authenticate before continuing their siege. A very handy tool, especially if your load is generated by user account pages and such.</p>


<p>Related posts:<ol><li><a href='http://www.justincarmony.com/blog/2010/07/14/setting-up-ssh-key-authentication-between-servers/' rel='bookmark' title='Setting up SSH Key Authentication Between Servers'>Setting up SSH Key Authentication Between Servers</a></li>
<li><a href='http://www.justincarmony.com/blog/2008/10/10/local-lamp-developement-user-content/' rel='bookmark' title='Local LAMP Developement &amp; User Content'>Local LAMP Developement &#038; User Content</a></li>
<li><a href='http://www.justincarmony.com/blog/2009/11/27/my-php-user-group-experience/' rel='bookmark' title='My PHP User Group Experience'>My PHP User Group Experience</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.justincarmony.com/blog/2011/11/03/siege-with-user-login/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Simple Trick: History Command</title>
		<link>http://www.justincarmony.com/blog/2011/05/31/simple-trick-history-command/</link>
		<comments>http://www.justincarmony.com/blog/2011/05/31/simple-trick-history-command/#comments</comments>
		<pubDate>Tue, 31 May 2011 21:05:08 +0000</pubDate>
		<dc:creator>Justin Carmony</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[shell]]></category>
		<category><![CDATA[Tips and Tricks]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://www.justincarmony.com/blog/?p=932</guid>
		<description><![CDATA[So today I quickly installed Redis on a server, and I wanted to keep a copy of all the commands I had used to do so. I knew there was a better way than hitting the up arrow each time to copy and paste each command in reverse order. So after some Googling, I found ...


Related posts:<ol><li><a href='http://www.justincarmony.com/blog/2008/06/30/soapui-a-simple-and-raw-java-soap-client/' rel='bookmark' title='SoapUI &#8211; a simple and raw Java SOAP Client'>SoapUI &#8211; a simple and raw Java SOAP Client</a></li>
<li><a href='http://www.justincarmony.com/blog/2009/05/20/memcached-simple-effective-and-powerful/' rel='bookmark' title='Memcached: Simple, Effective, and Powerful'>Memcached: Simple, Effective, and Powerful</a></li>
<li><a href='http://www.justincarmony.com/blog/2008/02/11/asp-net-ajax-straight-forward-and-simple-the-way-it-should-be/' rel='bookmark' title='ASP .NET Ajax &#8211; Straight forward and simple, the way it should be.'>ASP .NET Ajax &#8211; Straight forward and simple, the way it should be.</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>So today I quickly installed Redis on a server, and I wanted to keep a copy of all the commands I had used to do so. I knew there was a better way than hitting the up arrow each time to copy and paste each command in reverse order. So after some Googling, I found out about the history command. So I was able to type the command &#8220;history&#8221; and it showed me the last two thousand or so commands I had used. I was able to copy and paste that into a wiki, and was good to go. You could also search your history by piping the history command to grep. Cool stuff I don&#8217;t want to forget.</p>


<p>Related posts:<ol><li><a href='http://www.justincarmony.com/blog/2008/06/30/soapui-a-simple-and-raw-java-soap-client/' rel='bookmark' title='SoapUI &#8211; a simple and raw Java SOAP Client'>SoapUI &#8211; a simple and raw Java SOAP Client</a></li>
<li><a href='http://www.justincarmony.com/blog/2009/05/20/memcached-simple-effective-and-powerful/' rel='bookmark' title='Memcached: Simple, Effective, and Powerful'>Memcached: Simple, Effective, and Powerful</a></li>
<li><a href='http://www.justincarmony.com/blog/2008/02/11/asp-net-ajax-straight-forward-and-simple-the-way-it-should-be/' rel='bookmark' title='ASP .NET Ajax &#8211; Straight forward and simple, the way it should be.'>ASP .NET Ajax &#8211; Straight forward and simple, the way it should be.</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.justincarmony.com/blog/2011/05/31/simple-trick-history-command/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Restoring Large MySQL Dump &#8211; 900 Million Rows</title>
		<link>http://www.justincarmony.com/blog/2011/04/06/restoring-large-mysql-dump-900-million-rows/</link>
		<comments>http://www.justincarmony.com/blog/2011/04/06/restoring-large-mysql-dump-900-million-rows/#comments</comments>
		<pubDate>Thu, 07 Apr 2011 03:05:12 +0000</pubDate>
		<dc:creator>Justin Carmony</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[system administration]]></category>
		<category><![CDATA[Tips and Tricks]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://www.justincarmony.com/blog/?p=811</guid>
		<description><![CDATA[This last weekend I had a fun opportunity of restoring roughly 912 Million Rows to a database. 902 Million belonged to one single table (902,966,645 rows, to be exact). To give an idea of growth, the last time I blogged about this database we had about 40 million rows. This giant table, the &#8220;Scores&#8221; table, ...


Related posts:<ol><li><a href='http://www.justincarmony.com/blog/2009/01/12/mysql-40-million-rows-myisam-innodb/' rel='bookmark' title='MySQL, 40 Million Rows, MyISAM to InnoDB, 45 Minutes'>MySQL, 40 Million Rows, MyISAM to InnoDB, 45 Minutes</a></li>
<li><a href='http://www.justincarmony.com/blog/2010/10/15/large-mysql-conversion-innodb/' rel='bookmark' title='Large MySQL Conversion &amp; InnoDB'>Large MySQL Conversion &#038; InnoDB</a></li>
<li><a href='http://www.justincarmony.com/blog/2008/07/01/mysql-php-sql_calc_found_rows-an-easy-way-to-get-the-total-number-of-rows-regardless-of-limit/' rel='bookmark' title='MySQL &amp; PHP  – SQL_CALC_FOUND_ROWS – An easy way to get the total number of rows regardless of LIMIT'>MySQL &#038; PHP  – SQL_CALC_FOUND_ROWS – An easy way to get the total number of rows regardless of LIMIT</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><a href="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/04/mysql-logo2.png"><img src="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/04/mysql-logo2.png" alt="" title="mysql-logo2" width="200" height="103" class="alignright size-full wp-image-813" /></a>This last weekend I had a fun opportunity of restoring roughly 912 Million Rows to a database. 902 Million belonged to one single table (902,966,645 rows, to be exact). To give an idea of growth, <a href="http://www.justincarmony.com/blog/2009/01/12/mysql-40-million-rows-myisam-innodb/">the last time I blogged</a> about this database we had about 40 million rows. This giant table, the &#8220;Scores&#8221; table, is has a very small schema: two ints, a tiny int, and a DECIMAL(5,2).</p>
<h3>Problem</h3>
<p>Our current backup system uses mysqldump. It dumps a 25 GB sql dump file, which compresses to about 2.5GB using gzip. The last time we needed to restore a backup it was only about 9GB, and it took several hours.</p>
<p>This time, I created the database, and from the mysql prompt I issued the following command:</p>
<code class="code">\. /path/to/backup/database_dump.sql</code>
<p>It would run great until it got to about 10% of the way through the scores table. However, it would start to slow down. Because the rows were so small in our scores table, each INSERT statement had about 45,000-50,000 records. So each line had roughly 1MB of data.</p>
<p>At first it would insert a set of 50,000 in half a second or so. However, after a few million records, it would slow down to three second, and got to about 10 seconds per INSERT statement. This was a huge problem, given that I had roughly 18,000 INSERT statements, and at 10 seconds per INSERT, it would take <strong>50 hours</strong> to restore. Our website was down during this restore, since it was our primary database. So being down for over two days was <strong>not</strong> an option.</p>
<p>While trying to diagnose the problem I noticed something. While using the MySQL command &#8220;show processlist&#8221; the thread for the Database Restore would be in the sleep state for 9-10 seconds, and then the query would execute in under 0.2 seconds. So it wasn&#8217;t a problem with MySQL storing the data, but a problem with reading the data from such a large database dump file.</p>
<p>So I tried from the server&#8217;s command line &#8220;mysql -u user_name -p database_name < /path/to/backup/database_dump.sql" with the same result. The longer into the file I got, the longer it was taking for MySQL to read the query. </p>
<h3>Solution</h3>
<p>So, after some thinking late at night at 3 AM, I came up with an idea. Why not split up the database sql dump into multiple files. So I used the linux &#8220;split&#8221; command like this:</p>
<code class="code">cd /path/to/backup/
mkdir splits
split -n 200 database_backup.sql splits/sql_</code>
<p>This produced several dozen files in order, and it took about 10 minutes. The -n option told split to split each file up into 200 lines each. So the files were then named sql_aa, sql_ab, sql_ac all the way to sql_fg. Then, I did the following command using cat to pipe the files to mysql:</p>
<code class="code">cd splits
cat sql_* | mysql -u root -p database_name</code>
<p>The only problem with this method is you don&#8217;t see a status report for each query executed, it just runs until you hit an error, displaying the error. If no errors occur, it will just return you to the prompt. So to monitor the progress I would execute a &#8220;show processlist;&#8221; command on mysql to see how far we were.</p>
<p>4 1/2 hours later, the entire database was restored. A few things to note, I didn&#8217;t try just using cat on the original file to see if it would read the file differently than the was mysql was trying. But the important thing is I got the database restored in a relatively timely manner.</p>
<p>Hopefully, in the very near future, we will have moved to a new score system that doesn&#8217;t have almost a billion rows in it. </p>


<p>Related posts:<ol><li><a href='http://www.justincarmony.com/blog/2009/01/12/mysql-40-million-rows-myisam-innodb/' rel='bookmark' title='MySQL, 40 Million Rows, MyISAM to InnoDB, 45 Minutes'>MySQL, 40 Million Rows, MyISAM to InnoDB, 45 Minutes</a></li>
<li><a href='http://www.justincarmony.com/blog/2010/10/15/large-mysql-conversion-innodb/' rel='bookmark' title='Large MySQL Conversion &amp; InnoDB'>Large MySQL Conversion &#038; InnoDB</a></li>
<li><a href='http://www.justincarmony.com/blog/2008/07/01/mysql-php-sql_calc_found_rows-an-easy-way-to-get-the-total-number-of-rows-regardless-of-limit/' rel='bookmark' title='MySQL &amp; PHP  – SQL_CALC_FOUND_ROWS – An easy way to get the total number of rows regardless of LIMIT'>MySQL &#038; PHP  – SQL_CALC_FOUND_ROWS – An easy way to get the total number of rows regardless of LIMIT</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.justincarmony.com/blog/2011/04/06/restoring-large-mysql-dump-900-million-rows/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>PHP, Nginx, and Output Flushing</title>
		<link>http://www.justincarmony.com/blog/2011/01/24/php-nginx-and-output-flushing/</link>
		<comments>http://www.justincarmony.com/blog/2011/01/24/php-nginx-and-output-flushing/#comments</comments>
		<pubDate>Tue, 25 Jan 2011 04:01:00 +0000</pubDate>
		<dc:creator>Justin Carmony</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Tips and Tricks]]></category>

		<guid isPermaLink="false">http://www.justincarmony.com/blog/?p=726</guid>
		<description><![CDATA[Alright, so one of the few hangups I&#8217;ve ran into with moving from Apache to Nginx was output buffering. Now, we have a few administrative tools we use to perform large operations on our library and data. These scripts can take normally 3-5 minutes to run, and they output their progress and what step they ...


Related posts:<ol><li><a href='http://www.justincarmony.com/blog/2008/06/23/php-practices-buffering-your-autoload/' rel='bookmark' title='PHP Practices: Buffering your autoload'>PHP Practices: Buffering your autoload</a></li>
<li><a href='http://www.justincarmony.com/blog/2009/09/21/swiftmailer-sending-mail-in-php-with-ease/' rel='bookmark' title='SwiftMailer &#8211; Sending Mail in PHP With Ease'>SwiftMailer &#8211; Sending Mail in PHP With Ease</a></li>
<li><a href='http://www.justincarmony.com/blog/2008/10/10/local-lamp-developement-user-content/' rel='bookmark' title='Local LAMP Developement &amp; User Content'>Local LAMP Developement &#038; User Content</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><a href="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/01/nginx-logo.png"><img src="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2011/01/nginx-logo-300x77.png" alt="" title="nginx-logo" width="300" height="77" class="alignright size-medium wp-image-728" /></a>Alright, so one of the few hangups I&#8217;ve ran into with moving from <a href="http://httpd.apache.org/">Apache</a> to <a href="http://nginx.org/">Nginx</a> was output buffering. Now, we have a few administrative tools we use to perform large operations on our library and data. These scripts can take normally 3-5 minutes to run, and they output their progress and what step they are on as they run. The way they do this is after ever step in PHP I issue the same two commands:</p>
<pre class="brush: php; title: ; notranslate">
ob_flush(); // Flush anything that might be in the header output buffer
flush(); // Send contents so far to the browser
</pre>
<p>Well, with Nginx, it will wait for an entire response from the PHP-FPM instance before sending data to the browser. This is because traditionally the time to generate the response is less than the time to send the response to the browser, so Nginx will let the CGI instance finish as quick as possible to free it up for other requests. Well, even if I called ob_flush() and flush(), Nginx would wait for the entire response before sending it to the client&#8217;s browser. So, for our staff panel, I had to disable this buffering. It took a lot of scouring the web, but I finally figured it out:</p>
<h3>Nginx Configuration</h3>
<p>You need to set a few variables. I couldn&#8217;t actually figure out how to disable the buffer for Nginx, but I could set it very low on a per location configuration. </p>
<p>So I have the following location configurations:</p>
<code class="code">location ~ \.php$ {
        include /etc/nginx/fastcgi_params;
        fastcgi_pass  127.0.0.1:9000;
        fastcgi_index index.php;
        fastcgi_param  SCRIPT_FILENAME  /path/to/public_html/$fastcgi_script_name;
        fastcgi_read_timeout 600;
        fastcgi_buffer_size   1k;                              
        fastcgi_buffers       128 1k;  # up to 4k + 128 * 4k
        fastcgi_max_temp_file_size 0;
        gzip off;
    }</code>
<p>The important configurations are:</p>
<code class="code">fastcgi_buffer_size   1k;                              
fastcgi_buffers       128 1k;  # up to 1k + 128 * 1k
fastcgi_max_temp_file_size 0;
gzip off;</code>
<p>So I set the fastcgi_buffer_size and buffers to 1k. Then, you need to set the max temp file size to 0. Nginx by default will start to buffer on the disk. By setting it to 0 it will send it to the browser. The last piece of the puzzle I missed was turning gzip off, because it would try to buffer, even if it exceeded 1k, to compress the response. </p>
<p>Now, to get it to work, in my php script I echo out 1k worth of html commented out text to ensure everything else after it gets sent to the browser.</p>
<p>Now, I don&#8217;t recommend these settings for busy productions servers. However, only 3 people use this staff panel, so the performance differences are extremely low. </p>


<p>Related posts:<ol><li><a href='http://www.justincarmony.com/blog/2008/06/23/php-practices-buffering-your-autoload/' rel='bookmark' title='PHP Practices: Buffering your autoload'>PHP Practices: Buffering your autoload</a></li>
<li><a href='http://www.justincarmony.com/blog/2009/09/21/swiftmailer-sending-mail-in-php-with-ease/' rel='bookmark' title='SwiftMailer &#8211; Sending Mail in PHP With Ease'>SwiftMailer &#8211; Sending Mail in PHP With Ease</a></li>
<li><a href='http://www.justincarmony.com/blog/2008/10/10/local-lamp-developement-user-content/' rel='bookmark' title='Local LAMP Developement &amp; User Content'>Local LAMP Developement &#038; User Content</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.justincarmony.com/blog/2011/01/24/php-nginx-and-output-flushing/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>jQuery UI &#8211; Disable Title On Dialog</title>
		<link>http://www.justincarmony.com/blog/2010/09/15/jquery-ui-disable-title-on-dialog/</link>
		<comments>http://www.justincarmony.com/blog/2010/09/15/jquery-ui-disable-title-on-dialog/#comments</comments>
		<pubDate>Thu, 16 Sep 2010 05:56:35 +0000</pubDate>
		<dc:creator>Justin Carmony</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Web Design]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[jQuery UI]]></category>
		<category><![CDATA[Tips and Tricks]]></category>

		<guid isPermaLink="false">http://www.justincarmony.com/blog/?p=580</guid>
		<description><![CDATA[For some reason, this was turning out to be kind of hard to accomplish, and everyone on the internet wanted to do it with JavaScript hacks. My issue was if the JavaScript hack didn&#8217;t execute fast enough, causing the title to flash for just a second, so I&#8217;d much rather do it with CSS. Unfortunately, ...


Related posts:<ol><li><a href='http://www.justincarmony.com/blog/2009/09/15/jquery-tip-better-toggle/' rel='bookmark' title='jQuery Tip: Better Toggle'>jQuery Tip: Better Toggle</a></li>
<li><a href='http://www.justincarmony.com/blog/2008/10/24/empowering-javascript-through-jquery/' rel='bookmark' title='Empowering JavaScript Through jQuery'>Empowering JavaScript Through jQuery</a></li>
<li><a href='http://www.justincarmony.com/blog/2008/10/03/css-id-vs-class/' rel='bookmark' title='CSS – ID vs Class'>CSS – ID vs Class</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><a href="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2010/09/jquery-ui-logo.png"><img src="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2010/09/jquery-ui-logo.png" alt="" title="jquery-ui-logo" width="200" height="200" class="alignright size-full wp-image-583" /></a>For some reason, this was turning out to be kind of hard to accomplish, and everyone on the internet wanted to do it with JavaScript hacks. My issue was if the JavaScript hack didn&#8217;t execute fast enough, causing the title to flash for just a second, so I&#8217;d much rather do it with CSS. Unfortunately, there are no built in ways to hide it in jQuery. However, there is an option you can pass in the <strong>.dialog()</strong> method: <strong>dialogClass</strong>. This places a custom class in the main div element, allowing you to do something like this:</p>
<pre class="brush: jscript; title: ; notranslate">
function selectLocation()
{
	$('#modalSelectLocation').dialog({
			modal: true,
			dialogClass: 'modalSelectLocation'
			,buttons: {
				Cancel: function(){
					$(this).dialog('close');
				}
				,Continue: function() {
					alert('goto-buy');
				}

			}
		});
}
</pre>
<p>with the css of:</p>
<pre class="brush: css; title: ; notranslate">
.modalSelectLocation .ui-dialog-titlebar { display:none; }
</pre>
<p>Tada! No more Title Bar. However, make sure to have some form of cancel button.</p>


<p>Related posts:<ol><li><a href='http://www.justincarmony.com/blog/2009/09/15/jquery-tip-better-toggle/' rel='bookmark' title='jQuery Tip: Better Toggle'>jQuery Tip: Better Toggle</a></li>
<li><a href='http://www.justincarmony.com/blog/2008/10/24/empowering-javascript-through-jquery/' rel='bookmark' title='Empowering JavaScript Through jQuery'>Empowering JavaScript Through jQuery</a></li>
<li><a href='http://www.justincarmony.com/blog/2008/10/03/css-id-vs-class/' rel='bookmark' title='CSS – ID vs Class'>CSS – ID vs Class</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.justincarmony.com/blog/2010/09/15/jquery-ui-disable-title-on-dialog/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>VirtualBox Networking Setup</title>
		<link>http://www.justincarmony.com/blog/2010/03/22/virtualbox-networking-setup/</link>
		<comments>http://www.justincarmony.com/blog/2010/03/22/virtualbox-networking-setup/#comments</comments>
		<pubDate>Mon, 22 Mar 2010 06:32:43 +0000</pubDate>
		<dc:creator>Justin Carmony</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[networking]]></category>
		<category><![CDATA[Servers]]></category>
		<category><![CDATA[solutions]]></category>
		<category><![CDATA[sys]]></category>
		<category><![CDATA[system administration]]></category>
		<category><![CDATA[Tips and Tricks]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[virtual]]></category>
		<category><![CDATA[virtualbox]]></category>
		<category><![CDATA[virtualization]]></category>

		<guid isPermaLink="false">http://www.justincarmony.com/blog/?p=548</guid>
		<description><![CDATA[Every time I go to set up VirtualBox and several VMs I always forget how I setup the networking for them. Once again, I went through the pain of trying to figure it all out, so I might as well document it for future use. The Problem When creating virtual machines, especially virtual linux servers, ...


Related posts:<ol><li><a href='http://www.justincarmony.com/blog/2008/07/03/my-computer-setup/' rel='bookmark' title='My Computer Setup'>My Computer Setup</a></li>
<li><a href='http://www.justincarmony.com/blog/2008/03/08/brother-hl-2070n-sharing-an-vista-printer-to-a-xp-machine/' rel='bookmark' title='Brother HL-2070N &#8211; Sharing an Vista Printer to a XP Machine'>Brother HL-2070N &#8211; Sharing an Vista Printer to a XP Machine</a></li>
<li><a href='http://www.justincarmony.com/blog/2008/10/10/local-lamp-developement-user-content/' rel='bookmark' title='Local LAMP Developement &amp; User Content'>Local LAMP Developement &#038; User Content</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Every time I go to set up VirtualBox and several VMs I always forget how I setup the networking for them. Once again, I went through the pain of trying to figure it all out, so I might as well document it for future use.</p>
<h3>The Problem</h3>
<p>When creating virtual machines, especially virtual linux servers, I want them to be able to do the following things:</p>
<ol>
<li>Connect to the Internet</li>
<li>Connect over SSH from my Host Machine to the Guest Machine</li>
<li>Have the servers connect to each other on a private internal network</li>
</ol>
<p>Out of the box, a VM is configured for #1, however it cannot do #2 and #3. There are some solutions that do some <a href="http://mydebian.blogdns.org/?p=148">archaic port forwarding</a> by issuing special commands from the Terminal. This is just painful, and if you just want <strong><em>one</em></strong> port to work, that&#8217;s manageable, but what if you want ssh, ftp, myql, http, https, etc? Any on multiple VMs? What a nightmare! What is painful is when googling for a solution, almost <strong><em>every</em></strong> &#8220;answer&#8221; is this crazy port forwarding method. There is a much cleaner, better way!</p>
<h3>Solution &#8211; Host to Guest Connectivity</h3>
<p><a href="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2010/03/Screen-shot-2010-03-22-at-12.15.38-AM.png"><img src="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2010/03/Screen-shot-2010-03-22-at-12.15.38-AM-300x208.png" alt="Screen shot 2010-03-22 at 12.15.38 AM" title="Screen shot 2010-03-22 at 12.15.38 AM" width="300" height="208" class="alignnone size-medium wp-image-549" /></a></p>
<p>Go into your VM&#8217;s settings and go to &#8220;Network&#8221;, it will list options for 4 different adapters. Instead of hacking one adapter to do all the work, just setup more adapters for your configuration. For adapter #2, set it to Host-only. This enables an IP range for communicating from the Host to the Guest and vice versa. Start up your VM, and if you are using something like Ubuntu, edit your /etc/network/interfaces file so it looks like this:</p>
<code class="code"># This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
auto eth0
iface eth0 inet dhcp

### ADD THESE LINES
auto eth1
iface eth1 inet dhcp</code>
<p>After adding these lines, run the command:</p>
<code class="code">sudo /etc/init.d/networking restart</code>
<p>Now VirtualBox is configured to host this traffic over the 192.168.56.x IP range (I&#8217;m not sure if/where you can change this). So do an ifconfig on your guest machine, and it should show you the IP it has been assigned. If you want, you can change your /etc/network/interfaces so it can be statically assigned. You should now be able to SSH into your box on it&#8217;s IP:</p>
<code class="code">ssh -l justin 192.168.56.101</code>
<h3>Solution &#8211; Guest to Guest Communication</h3>
<p>Now, what if I have a Cassandra server, a Web Server, and a MySQL server each on their own VMs. What you do is create a third adapter set to &#8220;Internal Network&#8221;. Then in your /etc/network/interfaces file you set eth2 to a static IP of your choosing. I typically use the 10.0.0.x range. So each server is respectively 10.0.0.10, 10.0.0.20, and 10.0.0.30. However, over the 10.0.0.x range there is no DHCP, no Gateway, no nothing, just direct communications over these IPs.</p>
<h3>Conclusion</h3>
<p>So please, for the love of everything good, don&#8217;t resort to crazy port forwarding, complicated XML file editing, solutions for VirtualBox. Just use each type of interface configuration for what you need. Thank you!</p>


<p>Related posts:<ol><li><a href='http://www.justincarmony.com/blog/2008/07/03/my-computer-setup/' rel='bookmark' title='My Computer Setup'>My Computer Setup</a></li>
<li><a href='http://www.justincarmony.com/blog/2008/03/08/brother-hl-2070n-sharing-an-vista-printer-to-a-xp-machine/' rel='bookmark' title='Brother HL-2070N &#8211; Sharing an Vista Printer to a XP Machine'>Brother HL-2070N &#8211; Sharing an Vista Printer to a XP Machine</a></li>
<li><a href='http://www.justincarmony.com/blog/2008/10/10/local-lamp-developement-user-content/' rel='bookmark' title='Local LAMP Developement &amp; User Content'>Local LAMP Developement &#038; User Content</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.justincarmony.com/blog/2010/03/22/virtualbox-networking-setup/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Presentation: Real Life Scaling</title>
		<link>http://www.justincarmony.com/blog/2009/10/11/presentation-real-life-scaling/</link>
		<comments>http://www.justincarmony.com/blog/2009/10/11/presentation-real-life-scaling/#comments</comments>
		<pubDate>Sun, 11 Oct 2009 18:39:44 +0000</pubDate>
		<dc:creator>Justin Carmony</dc:creator>
				<category><![CDATA[Presentations]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Databases]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Presentation]]></category>
		<category><![CDATA[scaling]]></category>
		<category><![CDATA[Tips and Tricks]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://www.justincarmony.com/blog/?p=500</guid>
		<description><![CDATA[Here are my slides for the presentation that I gave at the Utah Open Source Conference on Friday. It was an awesome conference, and I am glad that I was able to be involved. Real Life Scaling: A Tale of Two Websites View more presentations from Justin Carmony. If you have any questions or comments, ...


Related posts:<ol><li><a href='http://www.justincarmony.com/blog/2009/05/27/steamlined-web-development-presentation-video/' rel='bookmark' title='Steamlined Web Development Presentation Video'>Steamlined Web Development Presentation Video</a></li>
<li><a href='http://www.justincarmony.com/blog/2008/12/06/100th-blog-entry-first-year-of-real-blogging/' rel='bookmark' title='100th Blog Entry &#8211; First Year of Real Blogging'>100th Blog Entry &#8211; First Year of Real Blogging</a></li>
<li><a href='http://www.justincarmony.com/blog/2008/05/14/a-new-stage-in-life-my-macbook-pro/' rel='bookmark' title='A New Stage in Life: My MacBook Pro'>A New Stage in Life: My MacBook Pro</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Here are my slides for the presentation that I gave at the Utah Open Source Conference on Friday. It was an awesome conference, and I am glad that I was able to be involved.</p>
<div style="width:425px;text-align:left" id="__ss_2184608"><a style="font:14px Helvetica,Arial,Sans-serif;display:block;margin:12px 0 3px 0;text-decoration:underline;" href="http://www.slideshare.net/JustinCarmony/real-life-scaling-a-tale-of-two-websites" title="Real Life Scaling: A Tale of Two Websites">Real Life Scaling: A Tale of Two Websites</a><object style="margin:0px" width="425" height="355"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=reallifescaling-ataleoftwowebsites-small-091010143045-phpapp02&#038;stripped_title=real-life-scaling-a-tale-of-two-websites" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=reallifescaling-ataleoftwowebsites-small-091010143045-phpapp02&#038;stripped_title=real-life-scaling-a-tale-of-two-websites" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object>
<div style="font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;">View more <a style="text-decoration:underline;" href="http://www.slideshare.net/">presentations</a> from <a style="text-decoration:underline;" href="http://www.slideshare.net/JustinCarmony">Justin Carmony</a>.</div>
</div>
<p>If you have any questions or comments, please feel free to leave them below.</p>


<p>Related posts:<ol><li><a href='http://www.justincarmony.com/blog/2009/05/27/steamlined-web-development-presentation-video/' rel='bookmark' title='Steamlined Web Development Presentation Video'>Steamlined Web Development Presentation Video</a></li>
<li><a href='http://www.justincarmony.com/blog/2008/12/06/100th-blog-entry-first-year-of-real-blogging/' rel='bookmark' title='100th Blog Entry &#8211; First Year of Real Blogging'>100th Blog Entry &#8211; First Year of Real Blogging</a></li>
<li><a href='http://www.justincarmony.com/blog/2008/05/14/a-new-stage-in-life-my-macbook-pro/' rel='bookmark' title='A New Stage in Life: My MacBook Pro'>A New Stage in Life: My MacBook Pro</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.justincarmony.com/blog/2009/10/11/presentation-real-life-scaling/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>My New External Hard Drive: Blacx + 1TB Drive</title>
		<link>http://www.justincarmony.com/blog/2009/09/26/my-new-external-hard-drive-blacx-1tb-drive/</link>
		<comments>http://www.justincarmony.com/blog/2009/09/26/my-new-external-hard-drive-blacx-1tb-drive/#comments</comments>
		<pubDate>Sat, 26 Sep 2009 18:03:10 +0000</pubDate>
		<dc:creator>Justin Carmony</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[blacx]]></category>
		<category><![CDATA[external hard drive]]></category>
		<category><![CDATA[Tips and Tricks]]></category>

		<guid isPermaLink="false">http://www.justincarmony.com/blog/?p=485</guid>
		<description><![CDATA[These last few weeks I&#8217;ve been dealing with larger and larger sets of data that I would need to download to my PC to work on. When working with multiple copies of data that are 10-20 GBs each, it started to fill up my two HDDs very quickly. I decided I need to go buy ...


No related posts.]]></description>
			<content:encoded><![CDATA[<p><img class="alignright size-medium wp-image-491" title="blacx" src="http://c747925.r25.cf2.rackcdn.com/blog/wp-content/uploads/2009/09/blacx-300x236.jpg" alt="blacx" width="144" height="113" />These last few weeks I&#8217;ve been dealing with larger and larger sets of data that I would need to download to my PC to work on. When working with multiple copies of data that are 10-20 GBs each, it started to fill up my two HDDs very quickly. I decided I need to go buy a new hard drive to give me plenty of room. The question was &#8220;internal&#8221; or &#8220;external&#8221; and how big.</p>
<p>I decided to go with a 1 TB drive. Then I had to decide if I wanted to put it inside my PC (I can fit 4 HDDs, so no problem) or get an external. The biggest thing I <em><strong>loathe </strong></em>about external hard drives is the slow transfer speed over USB. I like the convenience of smaller external drives that don&#8217;t require an external power source. I own a few smaller external hard drives, but they aren&#8217;t good for my 60GB backups.</p>
<p>This is where my new toy comes in: <a href="http://www.thermaltakeusa.com/Product.aspx?S=1268&amp;ID=1642" target="_blank">the Thermaltake BlacX</a>. Its basically a docking station for any 2.5&#8243; or 3.5&#8243; SATA hard drive. So now instead of swapping around cords and such, I have my docking station hooked up via an eSATA connection. So I can hot swap archive hard drives, keep a 300Gb/s transfer speed, and have the convenience of no swapping cables.</p>
<p>So far it as been really great. It also supports a USB 2.0 connection if your PC doesn&#8217;t support eSATA. I highly recommend it to anyone looking to be able store and archive data on multiple hard drives.</p>


<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://www.justincarmony.com/blog/2009/09/26/my-new-external-hard-drive-blacx-1tb-drive/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Page Caching using memcached
Database Caching 37/131 queries in 0.047 seconds using memcached
Content Delivery Network via Rackspace Cloud Files: c747925.r25.cf2.rackcdn.com

Served from: www.justincarmony.com @ 2012-02-07 23:46:22 -->
