Search code examples
amazon-web-servicesexpressdockermicroservicesamazon-ecs

How to change express.js microservice application for ecs auto scaling


This is my containerized micro-service application and workflow.

  1. Travis pull code from git, build docker image and push to ECR.
  2. Updates ECS task and service with new image tag using aws cli on successful travis build.
  3. I have one instance per dev and staging cluster.
  4. I can have more than one instance for prod cluster but no more than 1 instance per dev and staging clusters.
  5. The solution has about 10 micro services, rabbitmq and mysql. (gateway, api, etc..)

Scenario: If my webapp or any other container is highly used, I want to scale up that by automatically creating multiple containers in same ec2 instance. (instance has enough ram and memory).

Currently I hardcoded the port for webapp as 3000. How my express.js code should change for the following?

  1. Dynamically binding port for webapp and api.
  2. Load balance within them.
  3. Configure autoscalling to make them happen automatically.

Additionally: Can this be achieved using Ansible? How? I need to scale containers, not clusters or instances.


Solution

  • Dynamically binding port for webapp and api. Load balance within them.

    The NodeJS/Express app just binds to a static port of the container. In your task definition you only specify the container port, that way the host port will be assigned at random. You have to use a loadbalancer at this point because there's multiple containers running. If you use an Application Load Balancer you can set ECS up in such a way that a target group automatically gets new ports registered and deregistered. Have a look at the docs for details.

    In resume: don't change your express.js code.

    Configure autoscalling to make them happen automatically.

    You can now setup 'Service Auto scaling' when you configure a service in ECS. This works in response to Cloudwatch alarms. You can e.g. monitor the number of requests on your loadbalancer in relation to the number of services, or the memory usage of your tasks.

    Additionally: Can this be achieved using Ansible? How?

    I would suggest to use a scripted infrastructure tool (like Cloudformation or Terraform) instead of Ansible because ultimately you setup a certain state, and the cluster/AWS will take care of the scaling. You don't want to intervene at runtime in your AWS ECS cluster, the whole point of ECS is that it will manage itself after you give it parameters/strategies.

    I need to scale containers, not clusters or instances.

    Not sure why you would not want to scale instances. If you don't scale instances, why not just always run the maximum number of containers? If you do want to scale instances, this is possible using an Auto Scaling Group, also in combination with Cloudwatch alarms.