node.jsexpressnode-cluster

NodeJS Express - Send specific routes to specific cluster workers?


I have a central API server starting cluster worker instances. Each instance has a specific bigger job, and there might be manipulations I want to do on that specific instance only. This was the rough idea I had in mind:

Each instance is a separate worker process, and I was hoping I could delegate all API requests for specific worker, directly to the worker (to execute functions in that worker).

instance/:id does represent the WorkerID.

The client might request the logs where workerID = x, so GET /instances/x/logs.

The goal here is that master routes all requests for instance X to the sub-process identified as x.

This is not for load distribution across workers that are essentially clones/mirrors.

Each of my worker may be performing a variation of a long running task (days, weeks, months long). Methods are shared across all workers, but if I'm calling /instances/x/logs I only want to query that on that specific worker process. That's the goal I'm looking to figure out.

// route these to subprocess x
GET /instances/x/logs
POST /instances/x/settings

// route these to subprocess y
GET /instances/y/logs
POST /instances/y/settings

// route these to subprocess z
GET /instances/z/logs
POST /instances/z/settings

// make a new worker process, returns worker ID as reference
POST /instances/

I saw I can have multiple express listeners on the same port across different processes, but if I understood correctly, this is automatically load-balanced by express. I can't route specific requests to specific workers based on the path, can I?


Solution

  • Each instance is a separate worker process, and I was hoping I could delegate all API requests for specific worker, directly to the worker (to execute functions in that worker).

    Indeed you can do that, but unless your instance/:id represents the WorkerID, you've hit an end.

    Let's assume the following example where :id is not a worker id:

    W - Worker

    W1/instances/1/:method - has the following methods names, cities, cars

    W2/instances/2/:method - has the following methods names, fruits, stats

    The HTTP client will want to access:

    1. GET /instances/1/name, that's great, name exists in both paths. - TRUE
    2. GET /instances/2/fruits, that's great, fruits exists in this path on W2, BUT if the balancer serves you W1 with that route you'll have an error, because fruits doesn't exist on W1 - FALSE

    Final answer:

    You cannot request workers to pop-up and serve your will, best you can do is some communication between master & workers or have some methods that requires some processing, and based on the CPU usage, trigger those methods when a low worker is served. But take a look at the good part, if they die, you can fork new ones without crashing your whole app.