Posts Tagged ‘Nginx’

29
Jan
2013

Thread-based or Event-based?

by Stuart Harris

http://www.flickr.com/photos/jdhancock/4617759902/

Q: What do our 3 favorite open source projects (node, redis and nginx) have in common?  Apart from being uber-cool?

A: They are all single threaded.  

But aren’t they all really fast and highly scalable?  Yep.  So how does that work?

Nginx, redis and node are all event-based.  They have an event loop that will listen for an event saying that an asynchronous operation (IO) has completed and then execute the callback that was registered when the async operation started.  Rinse, then repeat.  It never waits for anything, which means that the single thread can go hell-for-leather just running code.  Which makes it really fast.

In days gone by, when we were Microsoft slaves, we used to wrestle with multithreading as a way of dividing up work.  In web apps every request started a new thread.  We’d also use the Task Parallel Library (TPL) which was not an easy abstraction.  And combine that with some event processing library like Reactive Extensions (Rx).  Now you’re asking for a lot of trouble.  The new await keyword in C# helps out alot, but either way you have to think about thread safety all the time.  And all kinds of locking strategies to deal with concurrent access to the same data.  And even with all that, it isn’t as fast.

The difference between the two worlds lies in the way that pieces of work are orchestrated.

Event-based applications divide work up using callbacks, an event loop and a queue.  The unit of work, or task, is a callback.  Simple.  Only one callback is ever executing at a time.  There are no locking issues.  You can write code like you’re the only kid on the block.  You decide when you’re done and then effectively yield control to someone else.  Everyone is really polite so it just works.

Thread-based applications essentially divide work up in hardware.  Because each piece of work has its own thread, and will block if it needs to (like when it’s waiting for IO), the CPU will suspend that thread and start running another that is waiting.  Every time that happens there is quite a hefty context  switch, including moving about 2MB of data around.  In effect the hardware decides when to yield control and you don’t get much of a say.

Who’d have thought that a single thread, dealing with everything, could be faster than multiple threads each dealing with just one thing?  Well, on a single core, that may be true.  On multiple cores it actually may also be true.  That’s because you’ve probably got nginx and node and redis all running on the same machine – simplistically, on a quad core, that’s one core each and still one left over :-)

But isn’t writing synchronous code for a multithreaded environment a lot easier than writing asynchronous code for a single threaded environment?  Well, maybe, a little.  But some great patterns have emerged within the node community that really help.  

The simplest continuation-passing style (CPS) is the callback.  Which actually is not at all hard when you get used to it.  And it happens to be a great way to encapsulate and really easy to modularise.  The pattern for async functions is that the last argument is always the callback, and the pattern for callbacks is that errors are always the first argument (with results after that).  This standardisation makes composition really easy.

There are a ton of npm modules that can often help reduce complexity.  The best, in my opinion, is still Caolan’s async.  It’s still the most popular and follows the node conventions.  And there are also a few CPS compilers that allow you to code in a more synchronous style.  I wouldn’t have recommended these in the past, but there are a few, such as tamejs and Iced CoffeeScript, that use an “await, defer” pattern that is quite nice.  We’re using CoffeeScript more and more these days, and this “icing” is very tempting (seeing as we’re compiling anyway), but we haven’t strayed that way yet.

We’ve been writing big apps in node since October 2011 and have learnt a lot about how to separate concerns and modularise our code.  It’s a lot different to the object-oriented class-based separation we were used to, but after your head is reprogrammed to use a functional style it becomes second nature and actually much easier to structure.  Caolan’s post on programming style for node sums it up nicely.  If you hear anyone say that node is no good for big projects, tell them that all you have to do is follow a few simple rules and then it becomes perfect.  And fast.

29
Jun
2012

Inside red-badger.com

by Jon Sharratt

Here at our (currently) sunny workshop in Clerkenwell, myself and the fellow badgers have being busy carefully crafting this, the new red-badger.com website and blog.

Internal projects here are run with an ethos of allowing software engineers to learn, trial and sometimes fail (but that’s ok!) with new technologies and methodologies.  To give you some insight, my background is heavily based on developing all things on the Microsoft technology stack.  It was a welcoming surprise that we were going to be getting ourselves knee deep into a complete opposite of what many of us were used to.  From hosting environments and development tools it was a journey of discovery that ended with a great product at the end of it (of course I am biased).  As with any product built here we like to share our experiences and give an insight on how we do it, so lets begin….

Amazon EC2

Previously the Red Badger website was hosted on Rack Space but we thought we would try out Amazon EC2.  The first thing we noticed is that the speed to setup instances from start to finish was incredibly easy and quick.  A massive plus is that EC2 has a layered approach to its infrastructure setup.  Elastic IPs gave us a great benefit and flexibility when we were releasing some of the bigger changes initially.  It allowed us to efficiently spin up a clone of the production instance then release to it and switch the Elastic IP association from staging to the new clone.  Straight away Samera could test the effects of the new release, giving the green light to release to production.

Ubuntu

Ubuntu gave us a lean, fast operating system and being open source no license fees.  It has a great community and documentation for many of the tasks we required to setup.  I would say that Haro, Can and Stu had a much easier time setting up their local development environments being on Apple Macs.  It did take me a little while (running Windows 7)  to setup a Virtual Box with Ubuntu to get it up and running for development.  I used Samba to enable my Windows 7 based laptop to network share the files.  Additional to this, I setup port forwarding within Virtual Box to divert port 80 host traffic to the Ubuntu guest machine.  This meant I could work locally within my Windows 7 environment.  I would say though it took me a bit longer to get up and running because of the fact it was the first time I had ever used the Ubuntu operating system via command line.

Nginx

Initially for the project we started using Apache but the team having done some research moved on to the decision to use the lightweight webserver Nginx which is pretty much built for speed.  The main difference is the fact that Apache’s model is process and thread based where-as Nginx is event based.  This means that rather than waiting around for a response to happen before continuing and blocking a thread, callbacks in an event driven architecture allow the thread to continue executing other jobs whilst still waiting for a response to respond to.  The configuration was simple and allowed us to very easily configure reverse proxying to Node.js along with caching of pages.

Node.js

Apart from the blog section of the site the pages are rendered using Node.js.  The framework used was Express, it provides a quick and easy setup for the building blocks when building a website via Node.js web development.  The template engine is Jade which I found to be incredibly easy to use and takes a lot of the bolierplate code / html tags when writing templates for content managed websites.  The way in which we do this is to tell Nginx to reverse proxy requests and serve up the response from node.  This allows us to use WordPress as our content management system yet keeping the awesome capabilities of the blog features.

WordPress

For the management of site content and general blogging (which is very much encouraged here at Red Badger) we chose the ever so popular WordPress.  We coupled the default install with a custom theme as well as installing a couple of extra magical plugins.  These plugins are Advanced Custom Fields, JSON API and Disqus to name a few.  Advanced Custom Fields is a great plugin that allows you to specify many new custom fields for certain pages turning your WordPress blog into an easy to use content management system.  These custom fields ranged from relationships, images, WYSIWG editors and more.  The JSON API plugin allowed Node.js to get relevant content as a JSON response and simply render out our Jade templates against the data.

Twitter Bootstrap

To give us superb results viewing across all devices we went for a responsive design and layout.  To do this we implemented the Twitter Bootstrap framework giving us a grid based layout / framework along with jump starting support across browsers.  You can see what I mean if you head to http://responsive.is/red-badger.com which provides a great site to roughly test what your responsive layout looks like on different mobile devices.  Another interesting aspect when building the site with Twitter Bootstrap was that we followed the route of using LESS for CSS for stylesheets on the site.  On Windows machines I would recommend Crunch to compile them all.  LESS for CSS provided some nice features for setting global colour variables amongst other elements to allow reuse and maintainability of our styles.

So all in all that about sums up the technologies and infrastructure which powers the new red-badger.com website.  Feel free to comment with any thoughts about the site or even the technology stack we decided upon.