Time to hack our Node app again and introduce another great piece of software called zeromq. On top of having one of the coolest logos, zeromq is a high-performance, low-latency messaging system that you simply cannot afford to ignore when you need to build highly scalable apps (IMHO). Other contenders would be RabbitMQ (awesome and rock-solid, but not really lightweight) and NSQ (written by the bit.ly folks).
The basic idea will be to have our web app call a remote server through zeromq. The remote server will perform a super fancy calculation and return it back to the web app. I can feel that you're excited already, so let's get started :*)
Both our zeromq machines (the client and the server) require a little bit of setup: on top of Node.js and npm (as described in previous posts), we need to install the zeromq library. Once again, the one available in the Ubuntu repo is way too old, so let's build a fresh version:
$ wget http://download.zeromq.org/zeromq-3.2.3.tar.gz
$ make
BTW, since I guess it's time to stop mourning SCCS ;), I've created a proper Github account where you'll find all pieces of code posted on this blog. Can't say I love Git dearly, but a little progress every now and then is okay, I guess.
Nice and short, huh? Create a 'reply' socket, listen on port 3000/TCP and send back twice was we got. And yes, everything in life is an 'int', so there.
Now, let's look at the corresponding part in the client, i.e. our web app:
Just as simple. Create a 'request' socket, bind it to our remote server and, in a separate function, fire some data, read the answer and display it.
Here's the full code:
Logs (or it didn't happen, right?): display all entries and get one id twice
local0.info<134>: Aug 16 17:29:52 10.37.166.19 {"message":"*** NODE APP STARTED ***"}134>
local0.info<134>: Aug 16 17:29:52 10.37.166.19 {"message":"Connected to zeromq server"}134>
local0.info<134>: Aug 16 17:29:52 10.37.166.19 {"message":"Web server started"}134>
local0.info<134>: Aug 16 17:29:52 10.37.166.19 {"message":"Connected to memcache"}134>
local0.info<134>: Aug 16 17:29:52 10.37.166.19 {"message":"Connected to database"}134>
local0.info<134>: Aug 16 17:30:04 10.37.166.19 {"message":"Request received, id=0"}134>
local0.info<134>: Aug 16 17:30:04 10.37.166.19 {"message":"Finding all documents"}134>
local0.info<134>: Aug 16 17:30:12 10.37.166.19 {"message":"Request received, id=51e3ce08915082db3df32c08"}134>
local0.info<134>: Aug 16 17:30:12 10.37.166.19 {"message":"Cache miss, key 51e3ce08915082db3df32c08. Querying..."}134>
local0.info<134>: Aug 16 17:30:12 10.37.166.19 {"message":"Item found: {\"_id\":\"51e3ce08915082db3df32c08\",\"x\":25}"}134>
local0.info<134>: Aug 16 17:30:12 10.37.166.19 {"message":"Zeromq request: 25"}134>
local0.info<134>: Aug 16 17:30:12 10.37.166.19 {"message":"Zeromq response: 50"}134>
local0.info<134>: Aug 16 17:30:12 10.37.166.19 {"message":"Stored key=51e3ce08915082db3df32c08, value=25"}134>
local0.info<134>: Aug 16 17:30:15 10.37.166.19 {"message":"Request received, id=51e3ce08915082db3df32c08"}134>
local0.info<134>: Aug 16 17:30:15 10.37.166.19 {"message":"Cache hit, key=51e3ce08915082db3df32c08, value=25"}134>
local0.info<134>: Aug 16 17:30:15 10.37.166.19 {"message":"Zeromq request: 25"}134>
local0.info<134>: Aug 16 17:30:15 10.37.166.19 {"message":"Zeromq response: 50"}134>
Let's take a few steps back and look at what we built over the last posts:
- a simple Node.js web app...
- fetching data from an Elasticache cluster...
- fed by a MongoDB server...
- logging remotely to a syslog server...
- calling a remote server through zeromq...
- all of it open-source...
- all of it cloud-based...
- each part easily scalable, independently from the others.