Search code examples
node.jsipcrpc

RPC, IPC or something else? A multi-process architecture in NodeJS


I am working on concepting an application that uses several smaller programs to support it. The rough image is:

  • One process (that might create a few workers) handles HTTP and WS
  • A process to handle a notification queue (send emails, push, etc.)
  • Another process to handle a chat by exposing an API either through JSON-RPC or something else.

I want to split my processes so that resources are better allocated and in case one of the processes drops out due to an error, it could be brought back up by the master process. However, there does not seem to be any library or framework that really does that - and yet, I doubt that everyone just creates one monolithic process that handles absolutely everything, especially on multi-core/-thread maschines.

While I know that I could basically use child_process to spawn sub-processes, communicate them the master's RPC port and then use JSON-RPC, I wondered if there if there is a more efficient approach to this.

Any idea? Thanks in advance!


Solution

  • This sounds a lot like a microservice architecture. While there are frameworks in js to build microservices such as moleculer a lot of microservice implementations are language agnostic. In fact, Amazon, one of the oldest success stories of microservices, does not use a single programming language or platform for the Amazon.com website. It is a mix of multiple servers in PHP, Java, Perl and even some C++.

    The core of a microservice architecture is a HTTP reverse proxy front-end. This can be Apache2 or Nginx or it can be something more specialized such as HAProxy. When a webserver is configured to proxy microservices this way they are often called "Application Gateways".

    Traditionally the architecture is to have front-end template renderers (eg. a simple PHP website) that sources data from other services that can be written in any language:

                                                               ┌───────────┐
                                                             .-│ Service 1 │
                             ┌─────────────┐                /  └───────────┘
    ┌─────────┐              │ Web Server/ │ ┌───────────┐-'   ┌───────────┐
    │ Browser │-- internet --│ Load        │-│ Front-end │-----│ Service 2 │
    └─────────┘              │ Balancer    │ └───────────┘-.   └───────────┘
                             └─────────────┘                \  ┌───────────┐
                    HTTP                                     '-│ Service 3 │
                                      HTTP/FastCGI             └───────────┘
                                                        HTTP/RPC/REST
                                                      Kafka/RabbitMQ etc.
    

    With the advent of CORS, services such as Facebook have increasingly directly exposed the multitude of backend services directly to the web page:

                                ┌───────────────────┐
    ┌─────────┐              ---│ Static web server │
    │ Browser │-- internet -'   └───────────────────┘ ┌───────────┐
    └─────────┘            \         ┌─────────────┐  │ Service 1 │ services
                            \        │ Web Server/ │--└───────────┘ on same
    React/Angular/Vue        \-------│ Load        │  ┌───────────┐ server
      front-end               \      │ Balancer    │--│ Service 2 │
                               \     └─────────────┘  └───────────┘
                                \                  HTTP
                      HTTP+CORS  \
                       (ajax)     \               ┌───────────┐ service on
                                   '--------------│ Service 3 │ separate
                                                  └───────────┘ server
    

    For this to work the communications between the web page and services are restricted to HTTP and Websocket so the back end services need to be HTTP services (REST/json-RPC/SOAP etc.).

    Service monitoring and restart is typically done using a dedicated service monitoring and restart mechanism. For node.js a popular software for crash detection and restart is PM2 or forever however there are other generic software for this such as monit. In fact, there is no requirement that all services use the same restart system (Amazon for example allow each feature to be developed by a different team and be deployed as the team see fit).

    If you carefully design your session system (sticky session, JWT token etc) you can scale your back-end by simply running more servers. For example if chat takes up a lot of resources simply run 3 or 4 chat servers while running only one front-end server.