Wildly Inaccurate http://wildlyinaccurate.com Web Development, Beer, and General Geekiness Tue, 21 May 2013 08:12:36 +0000 en-US hourly 1 Blazing fast WordPress with Nginx and Memcached http://wildlyinaccurate.com/blazing-fast-wordpress-with-nginx-and-memcached http://wildlyinaccurate.com/blazing-fast-wordpress-with-nginx-and-memcached#comments Mon, 20 May 2013 13:18:09 +0000 Joseph http://wildlyinaccurate.com/?p=727 Inspired by Eric Mann’s post on caching WordPress with Redis, I thought I’d experiment with a similar setup using Memcached. Any memory caching system should work just as well, but I’ve chosen Memcached because it’s already running on my server and because PHP already has a built-in libmemcached API.

My current setup is Nginx and PHP-FPM, with WP Super Cache. The cache is saved to the filesystem, allowing Nginx to serve static files (which it is very good at) without needing to pass any requests to PHP. This setup has worked very well, so I’ll be using it as a baseline.

To use Memcached, every request needs to be passed to PHP. My gut feeling was that this would be slower than serving static files with Nginx due to the overhead of spinning up a PHP process for each request.

Benchmarks

To find out which of the two setups was faster, I measured the following metrics using WebPagetest and Blitz:

Nginx + WPSC

TTFB            0.244 seconds
Response Time   310 ms
Hit Rate        89 hits/second

Nginx + WPSC

Nginx + PHP-FPM + Memcached

TTFB            0.126 seconds
Response Time   241 ms
Hit Rate        94 hits/second

Nginx + PHP-FPM + Memcached

Conclusions

While the difference between the two setups isn’t huge, the Memcached setup still came out noticeably faster with nearly half the TTFB and a 70ms faster response time. It also managed to serve 5 hits/second more than the WPSC setup.

The Setup

If you want to try out this setup for yourself, it’s relatively simple to get running.

First you’ll need to create the PHP script that handles the caching. I’ve called mine index-cached.php. The script below will cache pages with the key fullpage:your.domain.com/the/page/uri for 1 day. It will also append a comment to the end of the response, specifying whether the page was served from cache or generated dynamically and how long the execution took.

<?php

$start = microtime(true);

$memcached = new Memcached;
$memcached->addServer('127.0.0.1', 11211);

// Cache time in seconds (1 day)
$cacheTime = 60 * 60 * 24 * 1;
$cacheKey = "fullpage:{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}";

$debugMessage = 'Page retrieved from cache in %f seconds';
$html = $memcached->get($cacheKey);

if ( ! $html) {
    $debugMessage = 'Page generated in %f seconds';

    ob_start();

    require 'index.php';
    $html = ob_get_contents();

    $memcached->set($cacheKey, $html, $cacheTime);

    ob_end_clean();
}

$finish = microtime(true);

echo $html;
echo '<!-- ' . sprintf($debugMessage, $finish - $start) . ' -->';
exit;

You also need to modify your Nginx site configuration to use this new script instead of the usual index.php. The configuration below is an example of how to do this. It is not a fully-working site configuration.

The important things to notice are:

  • If we determine that the current request can be cached, we set index to index-cached.php.
  • The cache isn’t used if the request is from a mobile browser, if any login cookies are found, or if there are any query arguments.
  • The cache isn’t used for the admin panel (/wp-admin).
server {
    server_name yourdomain.com;
    root /var/www/yourdomain;
    error_page 404 = /index.php;

    set $cache_flags "";

    # Is this a mobile browser?
    if ($http_user_agent ~* "(2.0 MMP|240x320|400X240|AvantGo|BlackBerry|Blazer|Cellphone|Danger|DoCoMo|Elaine/3.0|EudoraWeb|Googlebot-Mobile|hiptop|IEMobile|KYOCERA/WX310K|LG/U990|MIDP-2.|MMEF20|MOT-V|NetFront|Newt|Nintendo Wii|Nitro|Nokia|Opera Mini|Palm|PlayStation Portable|portalmmm|Proxinet|ProxiNet|SHARP-TQ-GX10|SHG-i900|Small|SonyEricsson|Symbian OS|SymbianOS|TS21i-10|UP.Browser|UP.Link|webOS|Windows CE|WinWAP|YahooSeeker/M1A1-R2D2|NF-Browser|iPhone|iPod|Mobile|BlackBerry9530|G-TU915 Obigo|LGE VX|webOS|Nokia5800)" ) {
        set $cache_flags "{$cache_flags}M";
    }

    # Is the user logged in?
    if ($http_cookie ~* "(comment_author_|wordpress_logged_in_|wp-postpass_)" ) {
        set $cache_flags "${cache_flags}C";
    }

    # Do we have query arguments?
    if ($is_args) {
        set $cache_flags "${cache_flags}Q";
    }

    # If none of the rules above were matched, we can use the cache
    if ($cache_flags = "") {
        set $index_file /index-cached.php;
    }

    # Otherwise we'll just use index.php
    if ($cache_flags != "") {
        set $index_file /index.php;
    }

    location / {
        index $index_file index.html;
        try_files $uri $uri/ $index_file?$args;
    }

    # Force /wp-admin requests to always use index.php
    location /wp-admin/ {
        index index.php;
        try_files $uri $uri/ /index.php?$args;
    }

    # Pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    location ~ \.php$ {
        try_files $uri =404;
        include fastcgi_params;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass 127.0.0.1:9000;
    }
}

Future Plans

This setup is inherently flawed in that it won’t be able to stand up to a large traffic spike. This is because every single request needs to go through PHP-FPM. With enough traffic, PHP-FPM will eventually be unable to spawn enough processes to handle every request.

The next step in caching would be to put a reverse-proxy like Varnish in front of Nginx. This (in theory) should allow the server to handle massive spikes in traffic because none of the requests would have to go through PHP-FPM.

Another option would be to use a content delivery network like CloudFlare, which would be able to offload the majority of traffic to the site.

Update: I’ve run the benchmarks with CloudFlare. Here are the results:

TTFB            0.188 seconds
Response Time   131 ms
Hit Rate        101 hits/second

CloudFlare

The numbers seem impressive, but the graphs generated by Blitz show that the response times vary quite dramatically. I’ve also used CloudFlare in the past and found that the TTFB isn’t always as low as this. This is part of the reason I stopped using CloudFlare; while synthetic benchmarks make it look fast, I found that average load actually times went up …But that’s a story for another blog post.

]]>
http://wildlyinaccurate.com/blazing-fast-wordpress-with-nginx-and-memcached/feed 2
Increasing the size of the LISH console http://wildlyinaccurate.com/increasing-the-size-of-the-lish-console http://wildlyinaccurate.com/increasing-the-size-of-the-lish-console#comments Mon, 20 May 2013 08:01:25 +0000 Joseph http://wildlyinaccurate.com/?p=734 If you’ve used Linode’s LISH console to get remote access to your server, you’re probably familiar with the way the console wraps everything to 60×20 (columns x rows) – even when you’re connected via ssh in a much larger terminal.

LISH Wrapping

Everything looks fine until…

LISH Wrapping

… The terminal wraps on itself

Luckily, the fix is easy. The LISH console is essentially emulating a raw serial port connected to the server. The serial port itself has no natural size, so the terminal gives it a default safe size (60×20). We can tell the terminal to change this size, using the stty command:

stty cols 200 rows 75

It’s as simple as that. Just set the cols and rows values to whatever size suits you.

If you’re having to do this a lot, you might consider putting this into your ~/.bashrc so that it runs each time you open a connection.

]]>
http://wildlyinaccurate.com/increasing-the-size-of-the-lish-console/feed 0
Understanding JavaScript: Inheritance and the prototype chain http://wildlyinaccurate.com/understanding-javascript-inheritance-and-the-prototype-chain http://wildlyinaccurate.com/understanding-javascript-inheritance-and-the-prototype-chain#comments Thu, 09 May 2013 21:43:39 +0000 Joseph http://wildlyinaccurate.com/?p=631 This is the first post in a series on JavaScript. In this post I’m going to explain how JavaScript’s prototype chain works, and how you can use it to achieve inheritance.

First, it’s important to understand that while JavaScript is an object-oriented language, it is prototype-based and does not implement a traditional class system. Keep in mind that when I mention a class in this post, I am simply referring to JavaScript objects and the prototype chain – more on this in a bit.

Almost everything in JavaScript is an object, which you can think of as sort of like associative arrays – objects contain named properties which can be accessed with obj.propName or obj['propName']. Each object has an internal property called prototype, which links to another object. The prototype object has a prototype object of its own, and so on – this is referred to as the prototype chain. If you follow an object’s prototype chain, you will eventually reach the core Object prototype whose prototype is null, signalling the end of the chain.

So what is the prototype chain used for? When you request a property which the object does not contain, JavaScript will look down the prototype chain until it either finds the requested property, or until it reaches the end of the chain. This behaviour is what allows us to create “classes”, and implement inheritance.

Don’t worry if this doesn’t make sense yet. To see prototypes in action, let’s take a look at the simplest example of a “class” within JavaScript, which is created with a function object:

function Animal() {}

var animal = new Animal();

We can add properties to the Animal class in two ways: either by setting them as instance properties, or by adding them to the Animal prototype.

function Animal(name) {
    // Instance properties can be set on each instance of the class
    this.name = name;
}

// Prototype properties are shared across all instances of the class
Animal.prototype.speak = function() {
    console.log("I'm a " + this.name);
};

var animal = new Animal('Cat');
animal.speak(); // I'm a Cat

The structure of the Animal object becomes clear when we inspect it in the console. We can see that the name property belongs to the object itself, while speak is part of the Animal prototype.

Animal Prototype

Now let’s look at how we can extend the Animal class to create a Cat class:

function Cat(name) {
    this.name = name;
}

Cat.prototype = new Animal();

cat = new Cat('Cat');
cat.speak(); // I'm a Cat

What we are doing here is setting Cat‘s prototype to an instance of the Animal object, so that Cat inherits all of Animal's properties. Let’s take a look at the Cat object to get a better view of what’s going on.

Cat Prototype
The Cat object has its own name instance property, like we expected. When we look at the object’s prototype we see that it has also inherited Animal‘s name instance property as well as the speak prototype property. This is where the prototype chain comes in – when we request cat.name, JavaScript finds the name instance property and doesn’t bother going down the prototype chain. However when we request cat.speak, JavaScript has to travel down the prototype chain until it finds the speak property inherited from Animal.

At this point I would recommend going through a few slides of John Resig’s JavaScript Ninja as they go into more detail about how JavaScript prototypes work, and provide some good interactive examples.

]]>
http://wildlyinaccurate.com/understanding-javascript-inheritance-and-the-prototype-chain/feed 0
Stop posting jobs for “hackers” http://wildlyinaccurate.com/stop-posting-jobs-for-hackers http://wildlyinaccurate.com/stop-posting-jobs-for-hackers#comments Sat, 16 Mar 2013 15:19:15 +0000 Joseph http://wildlyinaccurate.com/?p=690 I understand what people mean when they say that they want to hire a hacker. It means that they want to hire a developer; probably one who is enthusiastic and good at solving problems. The thing is, to me, the term hacker is no different from terms like rock star or ninja. When I see these terms in a job advertisement, a few red flags are raised in my mind:

You’re probably a start-up

This isn’t necessarily a bad thing, but it often means that whoever posted the job advertisement has a lack of technical knowledge, which probably also means…

You don’t actually know what kind of developer you want

Hacker, rock star, ninja – these don’t actually mean anything in the context of programming. Do you want a front-end web developer who can make complex JavaScript apps, or a Ruby developer with a working knowledge in system administration, or do you just want an all-rounder? If the title of your job advertisement has no context, I (and many other people) will simply ignore it.

The job requires more than one person

You really need 2 or 3 people for this job, but budgeting concerns have forced you to go for a single super-developer instead. This also leads me to believe that the job will have ill-defined requirements, and that I’m likely to be over-worked and under-paid.

For the most part, I think that if you find yourself posting an ad for a hacker, rock star, or ninja, you should take it as a sign that you need to re-think your hiring requirements. Take a little extra time to figure out what kind of developer you really want to hire, and write the advertisement accordingly.

]]>
http://wildlyinaccurate.com/stop-posting-jobs-for-hackers/feed 1
Setting up your editor http://wildlyinaccurate.com/setting-up-your-editor http://wildlyinaccurate.com/setting-up-your-editor#comments Wed, 14 Nov 2012 11:50:37 +0000 Joseph http://wildlyinaccurate.com/?p=600 Setting up your editor correctly can make working with other developers much less painful (for everybody). Below are some things that I believe every developer should do when editing source code. Any good IDE or editor should have settings to do these things automatically – the points below are paired with their Sublime Text 2 setting.

  • Trim trailing whitespace – "trim_trailing_white_space_on_save": true
  • Always use Unix line endings (LF) - "default_line_ending": "unix"
  • Ensure files end with a new line – "ensure_newline_at_eof_on_save": true
  • Automatically detect indentation style – "detect_indentation": true
  • Or, failing the above, have a way to quickly switch between indentation styles.
]]>
http://wildlyinaccurate.com/setting-up-your-editor/feed 1
Non-tech books I should read http://wildlyinaccurate.com/non-tech-books-i-should-read http://wildlyinaccurate.com/non-tech-books-i-should-read#comments Fri, 12 Oct 2012 15:12:40 +0000 Joseph http://wildlyinaccurate.com/?p=592 This post is to help me keep track of non-tech books that I would like to read.

Breakfast of Champions by Kurt Vonnegut
Slaughterhouse-Five by Kurt Vonnegut
Cat’s Cradle by Kurt Vonnegut

Do Androids Dream Of Electric Sleep by Philip K Dick

Neuromancer by William Gibson

Ham on Rye by Charles Bukowski

]]>
http://wildlyinaccurate.com/non-tech-books-i-should-read/feed 0
Solving “502 Bad Gateway” with nginx & php-fpm http://wildlyinaccurate.com/solving-502-bad-gateway-with-nginx-php-fpm http://wildlyinaccurate.com/solving-502-bad-gateway-with-nginx-php-fpm#comments Sat, 22 Sep 2012 20:15:00 +0000 Joseph http://wildlyinaccurate.com/?p=577 After upgrading php-fpm, my PHP-based sites were returning “502 Bad Gateway” errors. Here’s how I managed to solve it.

Check to make sure that php-fpm is running with ps auxww | grep php – if you can’t see any php-fpm processes in the output, then you may need to re-install php-fpm. If php-fpm is running okay, then skip this first step.

sudo apt-get remove php5 php5-cgi php5-fpm
sudo apt-get install php5 php5-cgi php5-fpm

The thing to notice here is that the order in which you install the packages is important. In the past I have found that installing them in the wrong order causes the packages to be configured incorrectly.

Next, get php-fpm to listen on the correct host/port. In /etc/php5/fpm/pool.d/www.conf change the following line from:

listen = /var/run/php5-fpm.sock

To:

listen = 127.0.0.1:9000

Restart php-fpm with sudo /etc/init.d/php-fpm restart and everything should work normally again.

]]>
http://wildlyinaccurate.com/solving-502-bad-gateway-with-nginx-php-fpm/feed 5
Sublime Text packages for web development http://wildlyinaccurate.com/sublime-text-packages-for-web-development http://wildlyinaccurate.com/sublime-text-packages-for-web-development#comments Wed, 12 Sep 2012 13:59:17 +0000 Joseph http://wildlyinaccurate.com/?p=570 Coming from PhpStorm (a full-featured IDE), I felt that Sublime Text was missing a few useful features. Luckily, one of the great things about Sublime is that it can be easily extended with plugins and packages. Perhaps the most useful package for Sublime is Sublime Package Control, which allows you to easily install and manage packages (it can even uninstall itself – über meta).

Below are some Sublime Text packages that I have found to be useful for web development.

  • All Autocomplete extends the Sublime Text autocompletion to find matches in all open files.
  • ApacheConf.tmLanguage provides ApacheConf syntax highlighting (for .htaccess, vhosts, etc).
  • DocBlockr simplifies and automates writing DocBlock comments in many languages including PHP and Javascript.
  • Sass and LESS both provide syntax highlighting for the Sass and LESS dynamic stylesheet languages. Compass also provides a watch/build system for Sass.
  • SideBarEnhancements provides many useful enhancements to the default Sublime Text sidebar, including Copy Path and Open With…
  • SublimeCodeIntel is a full-featured code intelligence engine that provides smart autocomplete and jump-to-symbol functionality.
  • SublimeLinter automatically runs your code through a linter and highlights lines that it deems to contain (potential) errors. SublimeLinter has built-in linters for most popular languages.
]]>
http://wildlyinaccurate.com/sublime-text-packages-for-web-development/feed 5
September 4: Looking back on the Christchurch earthquakes http://wildlyinaccurate.com/september-4-looking-back-on-the-christchurch-earthquakes http://wildlyinaccurate.com/september-4-looking-back-on-the-christchurch-earthquakes#comments Tue, 04 Sep 2012 22:55:20 +0000 Joseph http://wildlyinaccurate.com/?p=546 In the early hours of 4 September 2010, I was sound asleep in my house on Mount Pleasant hill in Christchurch, New Zealand. At 4:35am I was woken by a deep rumbling sound. Seconds later, the floor and walls began to shake as my house was rocked back and forth on its foundations. I scrambled out of bed and hid in a doorway until the shaking stopped. After checking that my family was okay, I went upstairs and stepped onto the balcony to look out over Christchurch. The city was silent save for a few car alarms, and it was in this relative quiet that I came to understand the significance of this event. I didn’t realise it then, but that earthquake would become a catalyst for change in my life.

The regular aftershocks kept everybody on edge and were a constant reminder that the ground we stood on was unstable. Still, life in Christchurch carried on almost as normal. I was surrounded by friends, had a great job, and was spending lots of time with my younger brothers. There was no reason for me to want to change anything. Then out of nowhere, in the middle of the day on 22 February 2011 a powerful quake hit Christchurch, killing 185 people.

The following months were fraught with hardships — thousands of homes were uninhabitable, roads and bridges were unusable, power outages were common, and water supplies became contaminated. People grieved.

Not long after the February quake I received news that my uncle was seriously ill. My uncle  lives in the UK along with most of my family, so I felt useless being so far away. My mother, sister and I decided that we would fly to the UK to see my uncle for a short time. While I felt guilty for leaving the rest of my family to deal with the effects of the quakes, I knew that the trip would be a welcome respite from the difficulties we faced living in a broken city. I bought a return ticket, put all of my belongings into my father’s garage and made plans to return in 6 weeks.

In the UK I watched as my uncle’s condition deteriorated. Having my family around made it somewhat easier to deal with what was happening. It also made me realise what was most important to me: family. This realisation was what prompted me to tell my dad that my things would be staying in his garage for a while longer, and to (regretfully) inform my boss that I wouldn’t be returning to my job in New Zealand.

It has now been a year and a half since I settled in London. So far I have had two great jobs and still found time to travel around Europe. I see my family more than I ever have before (it had been over 10 years since I last visited the UK). I have met some amazing people and experienced some wonderful things with them. A small part of me wishes that I had gone back to Christchurch and helped with the rebuild effort, but I don’t regret my decision to stay in the UK.

While I grieve for all that the earthquakes took away from us, I am also aware that had they not happened, I would not be where I am —or who I am— today.

Kia kaha, Christchurch. Thank you for reading.

]]>
http://wildlyinaccurate.com/september-4-looking-back-on-the-christchurch-earthquakes/feed 0
Programming Books and Resources http://wildlyinaccurate.com/programming-books-and-resources http://wildlyinaccurate.com/programming-books-and-resources#comments Tue, 28 Aug 2012 09:21:59 +0000 Joseph http://wildlyinaccurate.com/?p=536 This post is a list of programming-related books that I intend to read at some point (in no particular order).

And some other resources that aren’t books:
]]>
http://wildlyinaccurate.com/programming-books-and-resources/feed 0