Press enter to see results or esc to cancel.

Setting up a NodeJS platform for multiplayer games/realtime application (Ubuntu+Nodejs+Varnish+Monit)

If you are reading this you already know that nodejs is a powerful engine for your realtime application or multiplayer game. But it's not easy to setup an up and running platform, which is self monitored. by self monitored here I mean that the platform will automatically detect a nodejs crash/stop and will restart the service. The platform should also support load, and for this we'll use Varnish to optimize static content delivery.

Prerequisites

This tutorial suppose that you are already familiar with linux (I'll use Ubuntu here) : know how to install/remove package from package manager and sources, and how to edit configuration files. obviously, some programming and networking skills are preferable, but not required.  

Used tools

  • nodejs
  • Varnish cache
  • Monit
  • upstart
 

Notes

I'll suppose that you already own a dedicated server/VM for your node application That no service is running on port 80 if you want your node server to run there. that helloapp.nodeserver.com point to the server ip And that you want your node application to run on helloapp.nodeserver.com Let's start

Setting up the environment

the first step is to install the tools we'll need to build our platform  

Nodejs

nodejs can be installed using the package manager (apt-get, yum ...etc) but I'd recommande to install it from sources to get the latest version. here is how you setup nodejs from sources :  

Monit

monit is a little daemon which monitor services and restart them when a configured condition is met. to setup monit    

Varnish cache

Varnish is an HTTP cache proxy, it'll accelerate the delivery of static content by caching them while reducing nodejs server load. installing vernish is straightforward, here are the instruction from official web site :   We'll also need some python mainly to be able to correctly log our nodejs server activity   all needed tools are now installed, let's start the server configuration    

Setting up the platform

Before starting, it's very important to think of a structured organization of your platform, this will make teamwork easier because most of the time, you'll not be alone on projects requiring such platforms. event if you are alone, be sure that some months later, you'll forget how you made things if they are not well structured and documented ... so here is the structure I use, you don't have to follow the exact same structure, It's here to give you an idea:
  1. I use a sub domain for each application,it also make migration easy (here we use helloapp.nodeserver.com)
  2. each application resides in /opt/nodeapps/<subdomain name>/, (here we'll use /opt/nodeapps/helloapp.nodeserver.com
  3. when a service require special configuration file for the application, I use the subdomain name as configuration file name (see bellow the upstart job and monit configurations)
  4. when a variable designate my application in a script I use something like mysubdomain_mydomain_com
the rest of this article will illustrate how I follow this structure. now we can start the configuration.

"hello world" server

For testing purpose, I'll create a minimal nodejs http server which represent your real-time nodejs app or you multiplayer game server. I recommand to put all nodejs apps in a separate directory. here we'll use /opt/nodeapps/ our hello world http server create file /opt/nodeapps/helloapp.nodeserver.com/server.js  

Creating upstart job

now we'll write the upstart job that'll be responsible of launching our helloapp server. this will allow you if you want, to schedule the nodejs startup in a system runlevel as any other system service (but it's not needed since we'll use monit), the upstart will also send helloapp server output to a logfile so we can inspect what's hapening, investigate crashes ...etc for logging, I'm using a little python script that you can download here. this script will pipe the logs to logfiles and ensure that they are not locked. you can just pipe stdout/strerr directly to logfiles but then you'll have some troubles (and headache) if you want to make rotating logs. bellow I suppose that the script is in /opt/nodeapps/scripts/log.py create/edit file /etc/init/helloapp.nodeserver.com.conf
you can use this same upstart script to create multiple applications upstart jobs, if you respect the same structure as mine, all you have to do is to change APPNAME variable
  testing the upstart job   go to your browser and type : http://helloapp.nodeserver.com:10000/ note at this step, the server is accessible throught 10000 port, but this will change with Varnish Cache.  

Configuring varnish cache

by default, varnish run on port 6081 if you want your application to be accessible from default HTTP port (or some other port different from 6081) you have to edit /etc/default/varnish and change to for port 80 next we need to configure varnish this is a little tricky here is my varnish config which is compatible with nodejs, and handle websockets correctly (since websockets are mandatory for the application/game server we are making πŸ˜‰ ) the "section 1" declare a backend, the "section 2" identifies requests hostname which will be handled by our backend.   now start varnish and go to http://helloapp.nodeserver.com/ (if you used a different port than 80 you have to specify it) your hello server should respond. we are almost done ! now what if the server crash or stop ? let's simulate a server stop   now when you go to helloapp.nodeserver.com the you get a varnish error page (btw, you can use it to show a message to your users πŸ˜‰ )

Monit to the rescue

global monit configuration create/edit file /etc/monit/conf.d/helloapp.nodeserver.com.conf   what this script do is to tell monit to check the presence of helloapp.nodeserver.com process that is listening to local port 10000, if no response within 30 seconds restart the server. save the file and start monit   now go to to http://helloapp.nodeserver.com/ and you'll see that the server is responding. try to stop it : stop helloapp.nodeserver.com refresh the page .... and he's here again πŸ™‚ but wait, our nodejs application depend on both nodejs server AND varnish cash let's monitor varnish create/edit file /etc/monit/conf.d/varnish.conf   here the check condition is different, we actually check varnish presence using a special request we configured in varnish config. restart monit   now if everything is up and running, just make sure that monit is starting on system boot : update-rc.d monit enable  

Final step : configur log rotation

log are very important in such applications, and linux provide an efficient tool to handle log rotations to prevent infinite growing log files. to configure log rotation for all our nodejs applications create/edit /etc/logrotate.d/nodeapps  

Live example

want to see a live example ? here is doyazan prototype : http://demo.ezelia.com/ which is a proof of concept for a multiplayer HTML5 isometric game πŸ™‚ open the url, enter a random login and click start under the desirez avatar.  

Multiple node apps on the same server

Now thatΒ  you have a working platform, you can easily add other nodejs applications. for this you have three steps :
  1. Create the upstart job
  2. Configure varnish (declare a new backend and define the request hostname to use)
  3. Create a monit configuration file to monitor the application
You can automate those operations using a python or perl script, but beware, you should make sure that your script are properly tested, a misconfiguration in varnish can make all your node apps unreachable.  

Your turn !

this article explained the basics to obtain a self monitored nodejs server for your application. one important thing that has not been adressed here is security, since it's a BIG topic... but you can add some security to your current server with a little more work. First, a good practive would be to drop all incomming connexions to port different from 80, since all your node applications should be accessible throught this port now. For hack attempts, or bad behaviours, what I usually do, is to let the nodejs application log every suspect activity. those activities are tagged with some keywords (you can prefix suspect activities log with somthing like [SECURITY-WARN]) then I use fail2ban with a custom rule to detect and ban IPs generating a lot of those security warnings this can be a good exercice to enhance the platform πŸ™‚