Handling api requests using PHP, RabbitMQ Message Broker and Supervisor in Docker container
We need to create an application that will receive between 100,000 and 1,000,0000 transactions per minute.
Every transaction is going to happen in a different request, so this means that we can receive up to 1,000,000 different requests per minute.
To get started first clone the repository from github.
git clone git@github.com:siddhesh-deshpande89/php-microservice.git
Go to terminal and start the docker container with the following command
docker compose up -d
Now you should have a docker container running
To make any changes edit the docker-composer.yml
file.
We will run CLI commands in our docker container. Go to CLI of "APP" container either from dashboard or give following command based on your container ID.
docker exec -it [container_hash] /bin/sh; exit
To get your App container hash give the following command docker ps
and you will see list of
containers. Choose the app
container id.
Please wait for composer installer service to finish installing all dependencies. Then proceed.
Once you are in the App container, go to src folder and execute migrations
cd src/
vendor/bin/phinx migrate
vendor/bin/phinx seed:run
For Database management go to localhost:8081
we are using Adminer as it is light weight and a standalone library.
Use the following credentials:
host: db
username: root
password: demo1234
database: db_mystore (optional)
Your database should look something like this now.
Provide write permissions to the storage folder
chmod 777 -R storage/
Pass the following parameters in POST request
id: (Valid UUID Eg: 73be5270-cdd5-399d-9b1c-c3381f36e59a) (Required)
sku: (Integer)(Required)
title: (String)(Required)
variant_id: (Valid UUID)(Required)
For message broker service we are using RabbitMQ message broker
Go to http://localhost:15672
and login with the following credentials.
username: siddhesh
password: demo1234
Once logged in you will see the pending transactions in queue. You can change the credentials from docker-compose.yml file.
We need to process the message queue. For this we use a process manager named Supervisor.
Edit the numprocs=1
config in docker/supervisor/config.d/supervisord.conf
file if you want to increase or decrease number of workers.
Although unnecessary, to test the worker manually, simply run php src/worker.php
in the CLI of your App docker container.
Since we will process more than 100000 transactions per minute, we must avoid querying the database as much as possible.
For this purpose, I have used custom filesystem caching. The cache file exists in src/storage/cache
The worker interacts with Cache layer rather than Database layer. In the future we can move filesystem to Redis cache as well.
All log files are in src/storage/logs
folder
For logging, I used custom Logger class which is very light weight and writes to custom channel file.
For stress testing I used Guzzle library for HTTP requests which allows asynchronous requests in PHP.
To increase concurrency and number of requests simply edit the src/worker.php
In the future I will improve this to use multithreaded approach using python script.
To run tests go to CLI of App container and type vendor/bin/phpunit tests --testdox