what is nodejs - why should you care

31
NODEJS WHAT IS IT AND WHY YOU SHOULD CARE Who here as used Node before? Who here feels like they don’t understand why its so cool, or don't see the big deal?

Upload: gjj391

Post on 24-May-2015

758 views

Category:

Technology


7 download

DESCRIPTION

My introduction to non-blocking io and nodejs at NCDevCon.

TRANSCRIPT

Page 1: What is NodeJS - Why Should You Care

NODEJS

WHAT IS IT AND

WHY YOU SHOULD CARE

Who here as used Node before?Who here feels like they don’t understand why its so cool, or don't see the big deal?

Page 2: What is NodeJS - Why Should You Care

Garrett JohnsonCharlotte, NCRed Ventures

Developer

Page 3: What is NodeJS - Why Should You Care

NON-BLOCKING IONODE<?>

TOOLS

if you have heard about node, you probably have heard about this non-blocking io craze..... we will spend a good bit of time grasping this...

It is very important to understand how a PURELY evented system works whether; your just using frameworks and even more so if you want to get involved and build libraries.

once we get all that down, we will look into what the world node is.... yes the lack of “.JS” is intentional... you will see...

we will wrap up looking at tools to make building apps a little more comfy for us.

Page 4: What is NodeJS - Why Should You Care

result = lib.select('from network')

“IO needs to be done differently, we are doing it wrong.”-Ryan Dahl

ryan dahl, the creator of node... he is very opinionated about how nonblocking io should.

lets break down that snippet.... its very familar to us all....

but think about it, what is our cpu doing while the query is processing across the network....

its just ignoring everyone else; waisting precious cpu cycles... thats pretty dumb huh?

yes, we have “ways” around it, which I will dig into next... but why is this such a big deal? Your response times are quick enough right?

well.... the web is changing... there is no arguing this.... gone are the days of request/response.... and ajax will slowly follow it.

we already have rich flash/flex clients, mobile apps, and modern browsers able to keep persistence connections open.

does your app have 10,000 yours? can your server keep 10,000 concurrent connections PERSISTED.

this is definitely something you need to be thinking about.....

Page 5: What is NodeJS - Why Should You Care

THE RESTAURANT

I can’t remember where I first heard the example of an event loop as an doctors office, but thank you... this is inspired by that.

So lets take a look at why your server might be holding you up from building that real time app you want!

I have seen couple very educational intros for this same topic, i can’t remember where I saw them, but thank you and here is my own twist on it....

Lets think about your web stack as a unique little restaurant setup... You have a kitchen (your data store), waiters/waitresses (your web server) and of course customers (web requests).

Page 6: What is NodeJS - Why Should You Care

BLOCKING - PROCESSES

KITCHEN

CUSTOMERS

WAITER

1. 2. 3.

WAIT

This is where we started a while back, a single process serving requests. In our restaurant world; that is like a waiter serving a single customer at a time until they completely finish eating and leave before moving on to the next customer; They just sit there and WAIT!

Well that sucks!

In order to for our restaurant to make it, paralyze this model... So we buy a waiter per customer.... However, obviously this will only go so far until ran out of operational resources.

This directly correlates to the cpu world. Processes are expensive operations and you can only spawn so many until your server is out of resources.

Page 7: What is NodeJS - Why Should You Care

UH OH.

Yeah... that doesn’t work very well.... Unless you are okay with declining requests to your application. :-)

So let’s look at the next solutions....

Page 8: What is NodeJS - Why Should You Care

BLOCKING - THREADS

KITCHEN

CUSTOMERS

MANAGER RUNNER PER CUSTOMER

STAND BY

WAIT WAITWAIT

So our restaurant is about to tank due to resources constraint, we fired the last person with their crazy waiter per customer concept and hired a new one who promises that he can serve many more customers. They plan to accomplish by employing many waiters who are not to experienced, so that they cost less. He will be keeping one experienced employee to direct them around. However each waiter will still be dedicated to a customer, but since they are cheap it will work out okay.

You might have guessed this is the concept threads. (give or take)

So we stick with this for a while and are happy; It works pretty decent.... but after growing a bit it was not too long till the complaints started piling up about customers getting receiving incorrect food, bills, drinks, etc.

Hmm... It appears our pool of inexperienced waiters are getting all out of sync... On top of that we are running out of resources to keep adding more of them; they might be cheap, but they add up!

Page 9: What is NodeJS - Why Should You Care

UH OH!

So back to cpu world... you might have also guessed the problem here is that we didn’t properly design our system with the correct synchronization and locking algorithms that are required in a multi-threaded environment. Also, yes threads are light weight, but what your cpu has to do to maintain them as far as managing all the call stacks and context switches is very expensive and error prone. I will not argue that you cannot build a scalable system this way, the biggest applications in the world run this way; However, unless you are an expert in this area, your system will be buggy and will not scale as you hoped. We need something simple; something that will allow “less than expert programmers to create scalable systems.”

Page 10: What is NodeJS - Why Should You Care

class Lock extends Object{ private boolean m_bLocked = false;

public synchronized void lock() { // if some other thread locked this object then we need to wait // until they release the lock if( m_bLocked ) { do { try { // this releases the synchronized that we are in // then waits for a notify to be called in this object // then does a synchronized again before continuing wait(); } catch( InterruptedException e ) { e.printStackTrace(); } catch( Exception e ) { e.printStackTrace(); } } while( m_bLocked ); // we can't leave until we got the lock, which // we may not have got if an exception occured }

m_bLocked = true; }

public synchronized boolean lock( long milliSeconds ) { if( m_bLocked ) { try { wait( milliSeconds ); } catch( InterruptedException e ) { e.printStackTrace(); }

if( m_bLocked ) { return false; } }

m_bLocked = true; return true; }

public synchronized boolean lock( long milliSeconds, int nanoSeconds ) { if( m_bLocked ) { try { wait( milliSeconds, nanoSeconds ); } catch( InterruptedException e ) { e.printStackTrace(); }

if( m_bLocked ) { return false; } }

m_bLocked = true; return true; }

public synchronized void releaseLock() { if( m_bLocked ) { m_bLocked = false; notify(); } }

public synchronized boolean isLocked() { return m_bLocked; }}

import Lock;

public class CriticalResourceUsingSynchronizedAndLocks{ private Integer m_readLock = new Integer(0); private int m_reading = 0; private Lock m_writeLock = new Lock();

public int read() { int readData = 0; // lock readers synchronized( m_readLock ) { // if we are the first reader lock writers

if( m_reading == 0 ) // lock the writers m_writeLock.lock();

// increment semephore m_reading++;

} // unlock readers

// do read (may take significant time...)

// lock readers synchronized( m_readLock ) { // decrement semaphore m_reading--;

if( m_reading == 0 ) // release the writers m_writeLock.releaseLock();

}// unlock readers // return read value return readData; }

public void write( int x ) { // lock writers m_writeLock.lock();

// do writing

// release writers m_writeLock.releaseLock(); }}

public interface Executor {void execute(Runnable command);}int NTHREADS = 100;Executor exec = Executors.newFixedThreadPool(NTHREADS);while (true) {request = acceptRequest();Runnable requestHandler = new Runnable() { public void run() { handleRequest(request); } };exec.execute(requestHandler);}List<Runnable> shutdownNow();

boolean isShutdown();

boolean isTerminated();

boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException;

<T> Future<T> submit(Callable<T> task);

<T> Future<T> submit(Runnable task, T result);

Future<?> submit(Runnable task);

<T> List<Future<T>> invokeAll(Collection<Callable<T>> tasks) throws InterruptedException;

<T> List<Future<T>> invokeAll(Collection<Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException;

<T> T invokeAny(Collection<Callable<T>> tasks) throws InterruptedException, ExecutionException;

<T> T invokeAny(Collection<Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;

}doWork() {ExecutorService exec = ...;while (!exec.isShutdown()) {try { Request request = acceptRequest(); exec.execute(new Runnable() { public void run() { handleRequest(conn); } });} catch (RejectedExecutionException e) { e.printStackTrace();}}}

public void stop() { exec.shutdown(); }

void handleRequest(Request request) {if (isShutdownRequest(req))stop();elsehandle(req);}Uhhhhhhhhhhhhhhhh?!?!?!?!

Page 11: What is NodeJS - Why Should You Care

NO THANKS! :-)

Page 12: What is NodeJS - Why Should You Care

NON-BLOCKING

KITCHEN

CUSTOMERS

WAITER

READY

RUNNER

ORDER

So we fired the last guy (we got scared after he started rambling on about syncs, locks and executors)...

Now we have found someone new that says he can solve our problem with 2 smart waiters. Hmm... this sounds a little to familiar that customer to waiter deal... But hey what the hell!

So whats the grand idea?

We put one waiter up front, he is quick and does not wait with each customer after taking the order. He just take the order, passes it off the a friend in the middle and moves on. On top of that, after he has quickly processed all the customers, he clocks out because he has no more works to. In fact he takes a nap!

So the friend in the middle is bit mysterious, we don’t know how he works.. nor do we really care... We just know that he notifies the customer level waiter whenever food is ready. He also clocks out when there are no more orders to process.

So wow, our restaurant is serving 10x customers with 25% of the operating cost. Even though we are running fine, since we have all this extra space by not having so many of those unexpiranced waiters sitting around, we could actually duplicate this operation and serve even more within the same space!

Page 13: What is NodeJS - Why Should You Care

YAY! WIN!

AWESOME!

This is how nonblocking IO works. Our application takes in requests and passes off a callback of some sorts to an event loop which will be fired when its ready; mean while our application just keeps taking in requests, even though the one before him is not done yet.

The side number about the waiters going to sleep has merit too; within the nonblocking paradigm, if there are no more requests to be served, but the callbacks are still pending, our cpu idles out. This is a good thing.

Last but not least, our application, while quick, it cannot be at two tables at the EXACT same moment in time... since there is only one of them, there is no getting resources out of sync. Yes, that means there is no need for synchronizing, locks, etc. It’s completely race condition safe.

So wow, this is simple and it scales... This is a dream.

Page 14: What is NodeJS - Why Should You Care

NON-BLOCKING IONODE <?>

TOOLS

Now we have nonblocking IO down, we are experts! However we need a platform right?

Page 15: What is NodeJS - Why Should You Care

<YOUR PLATFORM HERE?> = WRONG!

Python? Ruby? Lua? Etc???

The issue is while you can certainly build an event loop in another language, your platform as a whole will not blend well with the event loop. For example, lets say you are taking in web requests in a nonblocking manner, for each request you now need: 1) check the cache server, if its there stop here of course. 2) check the database server. 3) cache the result to our cache servers. 4) log all this to the logging server.

You will probably use an existing driver for all 4 of those operations. This driver is blocking.... it was not designed for nonblocking. We just put at best 1 blocking call and at worst 4 blocking network calls. This will completely circumvent any benefit gained from the nonblocking requests.

Page 16: What is NodeJS - Why Should You Care

UH OH!

It will not work. We need a completely new platform with no “extra baggage” per say.

Page 17: What is NodeJS - Why Should You Care

FUNCTIONALCALLBACKS

ASYNCEVENTS

We need a language with the following features in order to fit will into the event loop layer.

Hmmm.... sounds familiar, No?

Page 18: What is NodeJS - Why Should You Care

$(document).ready(function() { $('#foo').bind('click', function(event) { $.get('/resource/', function(data) { }); }); });

We all know this right? This is completely nonblocking.

Page 19: What is NodeJS - Why Should You Care

NON-BLOCKING IONODEJSTOOLS

nonblocking systems and javascript are a match made in heaven.

1) JS has the concept of events, callbacks, etc baked INTO the language.2) JS has no “extra baggage” on the server.

This is what node is! Its a server side JS platform with a complete set of system level bindings that do all its IO operations within the event loop. The event loop is a language level construct now, not some add on. We can accomplish amazing performance this way.

Page 20: What is NodeJS - Why Should You Care

EVENTSSTREAMS

FSUNIX SOCKETS

HTTPTCPUDPDNS

...

A complete library for all system level programming. Its everything you see in your normal language, plus tons of goodies for creating servers because node is geared towards network programming.

Page 21: What is NodeJS - Why Should You Care

EVENTS BUILT INTO THE LANGUAGE, YOU HAVE TO WORK HARD TO BLOCK THE PROCESS.

NO HISTORY = AN ENTIRE NONBLOCKING PLATFORM.

Nothing blocks.

Page 22: What is NodeJS - Why Should You Care

OMG SHUT UP AND SHOW CODES!

Page 23: What is NodeJS - Why Should You Care

HTTP

GIST

Lets make a simple hello world http server that will make apache run scared.

Page 24: What is NodeJS - Why Should You Care

MODULES

GIST

Modules are how we organize our code... its a bit different than many scripting languages... not just an include of source code....

It returns an actual object.

Let’s wright some modules....

Page 25: What is NodeJS - Why Should You Care

NON-BLOCKING IONODEJSTOOLS

Tools.....

Page 26: What is NodeJS - Why Should You Care

NPMNODE PACKAGE MANAGER

NPM is the ecosystem, its like rpm, gems, brew, etc. It has all the tools you will need.

Let’s install some modules and build up some dependencies....

Page 27: What is NodeJS - Why Should You Care

BUILD SOMETHING

GIST

Lets build something fun....

It will: grab #ncdevcon from the twitter steam api, push it out to command line net clients over tcp and also to a web page via websockets. Easy right?

I don’t really get the twitter api, so it doesn’t grab every hash tag.. but it works for now :-)

Page 28: What is NodeJS - Why Should You Care

WINDOWS?V0.5.X - UNSTABLE

Windows is being worked on in the 0.5.x series. Its pretty much all they are focusing on, they are taking it very seriously and last I heard they were able to get a http server on windows to run just as well as linux. They are not compromising anything... which will be great for the windows crowd.

Page 29: What is NodeJS - Why Should You Care

IN CLOSING

USE STABLE - BE SMARTKEEP YOUR CODE DECOUPLED - API CHANGES

EMBRACE NPM - USE FRAMEWORKSPROCESS MONITORING

EXCEPTIONS

1) Don’t use the latest because its there. Use stable branch. Right now that means v0.4.x2) Things change in node from time to time, not so much as it used to, but make sure your code is maintainable and can handle change. (not that you shouldn’t be doing that anyways!)3) Embrace NPM. You don’t need to write http servers by hand. Use a framework.4) Use a process monitor to kick your app back up if it dies. (forever, monit, upstart)5) Exceptions suck... A side effect of the effect loop is no huge stack, therefore no huge stacktrace for debugging. Might be better in v0.6.x

Page 31: What is NodeJS - Why Should You Care

QUESTIONS?

THANKS FOR LISTENING!

TWITTER: GJOHNSON391

Thanks!