📜 ⬆️ ⬇️

6 small tips to prepare NodeJS for high loads

The service with face recognition "Look-A-Like" served thousands of users simultaneously

Developing on NodeJS as a hobby is a real pleasure, but when it comes to production for many users, there are a couple of things you should know to avoid long responses and crashes.


As part of the work at MyHeritage, we developed the doppelgänger service for Eurovision 2019, with which you can find out which contestants you are most like by uploading selfies.


In addition to the face recognition logic, the application had an extremely clear requirement: it had to serve tens of thousands of simultaneous users, because Eurovision is watched by millions of people around the world.


Very quickly, we realized that the load balancer before the application, configured using Auto Scaling , is not enough for fault tolerance. The following helped us a lot:


  1. Hope for the best, but prepare for the worst: measure how many simultaneous users will be able to serve your application in time X (one instance). For example, in our case, testing showed that we could serve 200 simultaneous users in each EC2 instance for 10 seconds, so when we learned that we had to serve 10,000 simultaneous users, we just had to prepare 50 servers behind the balancer. For the test, we used a great tool called JMeter .

    And this tutorial greatly helped in preparing for the implementation of measurements.
  2. Avoid locks: blocking operations (like fs.readSync ) are tempting because the code looks cleaner, but they literally kill performance. Instead, use async / await operations, because during the execution of asynchronous operation, the CPU will also be available for other tasks (see Event loop ).

    Before: const res = fs.readSync('file.txt');
    const res = fs.readSync('file.txt');
    After: const res = await fs.readAsync('file.txt');
  3. Increase Memory Limit: Node is configured by default to a limit of 1 GB. If the server is available, say, 4 GB specifically for your application, you will have to set the maximum memory limit manually using the CLI with the following flag: - --max-old-space-size
    --max-old-space-size
    Example: node --max-old-space-size=4096 server.js
  4. Make sure you use all the processor cores: by default, Node runs in the same thread. If you did not specifically set up a configuration that would run several threads, save money by choosing a server with 1 core.
  5. Reduce the number of calls to the application: configure forced HTTPS and all redirects as high as possible (for example, at the proxy level). This will allow the application not to be distracted by the superfluous, which means that it will be more accessible for requests that are really important.
  6. Error handling: use logging, for example Logz.io/AWS CloudWatch, to track errors that may cause the application to crash. DO NOT REPORT everything to services like Slack, because messages usually go in a crowd and can easily clog the channel. We used an excellent library called Winston for logging into NodeJS.

In our case, these tips led to a ten-fold improvement in performance and helped keep the production environment clean, even when thousands of users had to be served at the same time.


Thank you for reading.


')

Source: https://habr.com/ru/post/456036/


All Articles