paint-brush
Autoscaling Node.js Image Transformations Using Sharp and Expressby@lucierj
1,029 reads
1,029 reads

Autoscaling Node.js Image Transformations Using Sharp and Express

by Lucie Rybickova JavorskaOctober 18th, 2022
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

This example shows how you can use autoscaling of image transformations in Zerops, a PaaS-based app platform. The code is fairly simple. It uses Express and Sharp to perform the actual work. The example code is not meant to have production code quality. The purpose is to demonstrate the scaling feature of Zerops' scaling feature. It will perform vertical and horizontal scaling automatically. Vertical scaling means simply adjusting the amount of resources in your container whereas horizontal scaling adjusts the number of containers. You can read more about it [here]

Company Mentioned

Mention Thumbnail
featured image - Autoscaling Node.js Image Transformations Using Sharp and Express
Lucie Rybickova Javorska HackerNoon profile picture



Automation of application scaling is one of the key benefits of PaaS. The following example shows how you can use this ability in Zerops, a developer-first app platform – specifically when transforming images by scaling or rotating them using Node.js.


Note: Please be aware that the example code is not meant to have production code quality. The purpose is to demonstrate the scaling feature of Zerops. In the following, we assume that you have a Zerops account and an installed zcli (Zerops command line tool) available.


Writing your code

The code is fairly simple. It uses Express and Sharp to perform the actual work. Thus please execute the following in a folder of your choice:


npm i express sharp


This will install all dependencies in a folder node_modules and more importantly, create files package.json and package-lock.json.


Then please create the file index.js and insert the following code:


const sharp = require("sharp")
const express = require('express')
const expressServer = express()

expressServer.get('/image', (request, response) => {

  const requestedWidth = request.query.width ? parseInt(request.query.width) : 300;
  const requestedHeight = request.query.height ? parseInt(request.query.height) : 300;
  const requestedAngle = request.query.angle ? parseInt(request.query.angle) : 0;
  const format = 'jpg';

  console.log(`Handling image: size to ${requestedWidth}x${requestedHeight} and rotation to ${requestedAngle}`)

  sharp('example.jpg')
    .resize(requestedWidth, requestedHeight, {
      fit: sharp.fit.inside,
    })
    .rotate(requestedAngle)
    .toFormat(format)
    .toBuffer()
    .then(function (outputBuffer) {
      response.type(format);
      response.end(outputBuffer)
    });
})

expressServer.listen(3000, () => {
  console.log(`Listening on port 3000.`)
})


You can use any jpg image as example.jpg. Please put one in that folder. That's it. Just regular code (and an image).


Setting up the project in Zerops

Once you have the code ready, you need to create a project in Zerops. For that purpose, please:

  1. Login to Zerops
  2. Create a project by clicking on Add new project
  3. Specify a project name e.g. image
  4. Choose Node.js as service to be added
  5. Click Set to high availability?
  6. Click add


This sets your Node.js runtime to high availability meaning it will perform vertical and horizontal scaling automatically. Vertical scaling means simply adjusting the amount of resources in your container whereas horizontal scaling adjusts the number of containers. You can read more about it here.


Build and deploy on Zerops

The following steps describe how you can build and deploy the example as a Zerops application.

  • For Zerops to know which files to use please also create a zerops.yml file next to the other files:

    nodejs0: build: base: [ nodejs@16 ] build: - npm ci cache: [ node_modules ] deploy: [ index.js, example.jpg, node_modules ] run: start: node index.js


  • Simply deploy your file

    zcli push "image" nodejs0


  • Enable Zerops subdomain access via Public access & internal ports on the nodejs0 service and invoke the pre-generated URL in your browser.


Autoscaling in action

So far we deployed the code only without seeing the autoscaling in action. For that purpose, we will use k6 to generate some load.


No worries, Zerops won't scale to infinity without keeping your expenses under control. You can adjust the maximum and minimum resources for both vertical and horizontal scaling easily every time you see fit. Zerops will do the rest.


Here is the script to generate some load k6.js:


import http from 'k6/http';
import { check } from 'k6';

export default function () {
  const baseUrl = "https://<your-generated-subdomain>.usc1.contabozerops.com"
  const width = 300 + Math.random() * 1000
  const height = 300 + Math.random() * 1000
  const angle = Math.random() * 360
  const res = http.get(`${baseUrl}/image?width=${width}&height=${height}&angle=${angle}`)
  check(res, {
    'is status 200': (r) => r.status === 200,
  });
}


And then run it by invoking


k6 run --vus 100 --duration 120s k6.js


This will simulate 100 users requesting the image service as fast as possible for 120 seconds.


Our example is mainly a CPU-intensive task so you will see the number of vCPUs (virtual CPUs) rise -- vertical scaling -- and after a short time also see more containers being created -- horizontal scaling. Please refer to the following screenshot where you see many vCPUs and 4 containers.


Zerops Scaling up -- vertically and horizontally

After the k6 script finished generating the load, Zerops will wait for a moment to make sure the demand has really gone down. Then you'll first see the vertical autoscaling taking action by reducing vCPUs (due to the nature of our example). The number of vCPUs has dramatically decreased.


Zerops Scaling -- vertical cool down

After a while, Zerops will perform the horizontal autoscaling as well. As the k6 script finished generating load and we don't have any more coming, the starting point with two containers will be reached as shown in the screenshot.


Zerops Scaling -- horizontal cool down

Summary

Zerops is performing both vertical and horizontal autoscaling out of the box with a single click. Just like shown in the example above. No need to have a special code or knowledge. It both saves money and gives you more power when required.


For a deeper dive into what’s happening behind the scenes of Zerops autoscaling, check out my previous article.



Also published here.