Zero Downtime Deployment with Nginx and Docker + Rest API load Testing with Apache JMeter

I would like to share some of the things I did last few weeks that might be helpful for some of us in the future.

Introduction

Software availability is one of the important criteria considered for the success of any software. It is important as well to make sure that the business is not impacted during the software deployment phase. for instance, the users aren't forced to log out every time there is an update to the server. Thus, I will first discuss how I implement the zero-downtime deployment on the marketplace server before I introduce the Apache JMeter.

Some of the important concepts that would help facilitate further reading:

1. docker containers
2. load balancing
3. Linux file system
4. CI/CD

Multiple Containers + load Balancing

The load balancer is required to distribute the traffic equally among all the Containers. Since our application is deployed by docker. We can run 2 identical containers with a different port number from the same images.

  1. Build the application's image from dockerfile

sudo docker build ./marketplace -t marketplace

  1. Run both containers from the same base image
sudo docker run -d --name xaimarketplace -p 8000:80 -v ~/actions-runner/_work/xai-marketplace/xai-marketplace/marketplace:/var/www/html/ marketplace 

sudo docker run -d --name xaimarketplace_2 -p 8001:80 -v ~/xai-marketplace/xai-marketplace/marketplace:/var/www/html/ marketplace 

Please be noted that the xaimarketplace can be accessed on http://localhost:8000/ while xaimarketplace _2 is on port 8001. Knowing the whereabouts of our application Is really important for us in the next step.

Nginx as Load Balancer

Load balancing across multiple applications is a commonly used technique to optimize resources utilization, maximize throughput, reducing latency and ensuring fault-tolerant configurations.

To get started, navigate to the sites-available directory (/etc/nginx/sites-available), first you need to define the group with the upstream directive. The directive is placed in the HTTP context.

upstream backend { ip_hash; server localhost:8000; server localhost:8001; }

IP Hash – The server to which a request is sent is determined from the client IP address. In this case, either the first three octets of the IPv4 address or the whole IPv6 address are used to calculate the hash value. The method guarantees that requests from the same address get to the same server unless it is not available.

To sum up, all the request to our server will be redirected to either localhost port 8000 or port 8001 and if one of them is down, the server will redirect the request to the application in another port.

Congratulations, you've now implemented a web application with zero downtime during deployment.

Preserve the session data

For continuous delivery, we are employing Github Action. The way Github action's local runner update our application on the server is by removing all the files on the destination before installing the latest version available on our Github repository to the server.

Thus, the session data would be deleted during the deployment process as well. One of the easiest solutions for this issue is to find out where did your framework store all the session data and mount the session data folder between both containers.

- name: Stop the Docker container 
  run: sudo docker stop xaimarketplace
  

- name: umount
  run: sudo umount -l /home/sekfook97/actions-runner/_work/xai-marketplace/xai-marketplace/marketplace/writable/session

- uses: actions/[email protected]


- name: bind the folder
  run: sudo mount --bind  /home/sekfook97/xai-marketplace/xai-marketplace/marketplace/writable/session  /home/sekfook97/actions-runner/_work/xai-marketplace/xai-marketplace/marketplace/writable/session

- name: Start the first container
  run: sudo docker start xaimarketplace  

For the CI/CD pipeline, first, stop the container which you would like to update, all the request to the server will be redirected to the second container by the load balancer. Unmount the session folder so that when the session data folder in the first container is removed, another session data folder would not be affected. mount both folders again after the update is done, the session data are now shared between both containers.

RestApI load Testing with Apache JMeter

Load testing is defined as a type of software testing that determines a system's performance under real-life load conditions. Since most of the application now involved the development of Rest API, Apache JMeter is a good tool to simulate loads of various scenarios and output performance data in several ways.

Apache JMeter can be installed here, please make sure you have java 8 and above in your local environment.

jmeter1


Number of Threads (users): The number of users that JMeter will attempt to simulate.
Ramp-Up Period (in seconds): The duration of time that JMeter will distribute the start of the threads over.
Loop Count: The number of times to execute the test.

jmeter3

Insert the server name and path.

JMETER4

The summary of the result.

reference: https://medium.com/@chamikakasun/rest-api-load-testing-with-apache-jmeter-a4d25ea2b7b6