NodeJS Scaling - Forking processes
As Node.js is single threaded, we've run
into the need to scale our applications much sooner that we would if we
were using another programming language.
This is actually a benefit of Node because
we get to talk about scaling much earlier in the application lifecycle because
Node applications are made to scale.
Node.js is designed to clone your application and
then run it using multiple instances simultaneously. This process is
called forking.
Let's take a look at how we can fork our advice
server. In your app.js file, So here we have an HTTP server that's serving
advice. On line four, those are the advice options. So this server's going
to randomly give you one of these options. Below code explains forking :
In App.js
const http = require('http')
const port = parseInt(process.argv[2] || '3000')
const options = [
"data",
"data2"
]
const server = http.createServer((req, res) => {
const randomIndex = Math.floor(Math.random() * options.length)
const payload = JSON.stringify({
port,
processID: process.pid,
advice: options[randomIndex]
})
res.writeHead(200, { 'Content-Type': 'application/json'})
res.end(payload)
})
server.listen(port)
console.log(`advice service running on port ${port}`)
On line 12, that's where we create the
server, and we are randomly selecting the option because of line 13
where we set the random index using Math.random. Then
we'll create a payload so that we can return the port, the ID of the
current process, and some random advice. And then we will respond with
that payload on line 21.
So another thing to notice is that on line 2, we
are setting the port from the process.argv
array. These are the arguments that are passed to this script when it
starts. We can run our server by going over to the terminal and
typing node app and then the port we'd like to use, 3001. So I just
started an advice service running on port 3001. I can come over here to
the browser. All right, and then when I hit the server using the
browser, localhost:3001, we get to see the port, the processID, and some random advice. Every time I hit refresh,
we can see that the advice changes. Now this is great, but because we
only have one instance of one process running, we're only gonna be
able to handle so much traffic. So the solution is to fork this
process.
In the index.js file we want to do is get the
fork function from the child_process
module. Here we have fork the app into three instances. Now we need
to send the port to the app to start it, so the fork function is very
similar to the spawn function and the execute function in that it will
take an array of arguments. In index.js
const { fork } = require('child_process')
const processes = [
fork('./app', ['3001']),
fork('./app', ['3002']),
fork('./app', ['3003'])
]
console.log(`forked ${processes.length} processes`)
So this first one will run on 3001. The
second app will run on 3002. And this third app will run on 3003. We have
forked processes.length. Once
you run the index file, we will actually fork our application. it will
clone it into three processes, each running on its own port. And you
can see that it says forked three processes. If I come over to the
browser, we'll notice on 3001, we have an advice server running. On
3002, we also have an advice server running. And on 3003, we have an advice
server running.