Technologies

Speed up your web API with Laravel and Swoole using Docker

php,swoole,laravel,high-performance,docker
php,swoole,laravel,high-performance,docker

About a year ago, I read an article about an asynchronous framework which speeds up significantly scripts written in PHP. And I mean...Swoole.


Swoole is an asynchronous programming framework for PHP, which makes PHP as fast as Node.js (or even faster). In my article, I'll explain to you how thanks to this framework, we can speed up our application developed with Laravel and how to do it.


What is Swoole?


As I've written before, Swoole is a framework, you should also know that it is written using C language. It allows PHP developers to write high-performance, scalable, concurrent TCP, UDP, Unix socket, HTTP, Websocket services in PHP. Moreover, Swoole is a coroutine framework (such as Kotlin Coroutine or Python Coroutine). It means that it allows you to write asynchronous code without using callbacks, i.e. sequentially. But this is a subject on the other article, especially that, I figure PHP developers have not used this solution too often yet.



How to install Swoole?


In my case, I'll use Docker as a work environment for my application. Before we start, you can check out my article about working with Docker (I use Laradock).

I assume that you've installed Laradock and we can go further. Firstly open your .env file and enable Swoole in your workspace and php-fpm containers.

cd laradock
vim .env
WORKSPACE_INSTALL_SWOOLE=true
PHP_FPM_INSTALL_SWOOLE=true

Swoole works on port 1251, so we must expose this port in our workspace.

cd laradock
vim workspace/Dockerfile

Add EXPOSE command to the end of your workspace' configuration file.

EXPOSE 1251

Now, we can configure nginx.

cd laradock
vim nginx/sites/api-swoole.conf
upstream swoole-http {
    server workspace:1215;
}

map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

server {
    listen 80;
    # listen [::]:80;

    root /var/www/api-swoole/public;
    index index.php index.html;

    server_name api-swoole.test;

    location = /index.php {
        # Ensure that there is no such file named "not_exists"
        # in your "public" directory.
        try_files /not_exists @swoole;
    }

    location / {
        try_files $uri $uri/ @swoole;
    }

    location @swoole {
        set $suffix "";

        if ($uri = /index.php) {
            set $suffix ?$query_string;
        }
        proxy_set_header Host $http_host;
        proxy_set_header Scheme $scheme;
        proxy_set_header SERVER_PORT $server_port;
        proxy_set_header REMOTE_ADDR $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;

        # IF https
        # proxy_set_header HTTPS "on";

        charset utf-8;

        proxy_pass http://swoole-http$suffix;
    }
	
    error_log /var/log/nginx/laravel_error.log;
    access_log /var/log/nginx/laravel_access.log; 
}

It is an appropriate moment to rebuild and restart containers.

cd laradock
docker-compose build workspace nginx php-fpm
#if containers are running
docker-compose restart workspace nginx php-fom
#if containers are not running
docker-compose up -d workspace nginx php-fpm

We have run Docker and installed Swoole. Move to your workspace container and run below command.

docker-compose exec --user=laradock workspace bash

Now, we can install a laravel-swoole package, which allows Laravel to cooperate with Swoole.

cd api-swoole
composer require swooletw/laravel-swoole

Add two variables to Laravel .env file. If you want to know more about configuration, you should follow this link.

vim .env

SWOOLE_HTTP_HOST=workspace
SWOOLE_HTTP_DAEMONIZE=true

Now, you can start Swoole HTTP server, which will work as a daemon.

php artisan swoole:http start

If everything has gone well, you should get this message.

Starting swoole http server...
Swoole http server started

At the moment your application works via Swoole HTTP server!

Remember that if you change anything in your code, you must reload server using a command bellow:

php artisan swoole:http restart


Summary


Swoole makes your application more efficient and stable. It allows for handling much more requests than usually is possible using nginx+php-fpm. Below you can find my benchmark which proves that you can speed up your project event 5-6 times.

Below you can also find a code of my benchmark and results (16 GiB RAM, Intel® Core™ i7-8550U CPU @ 1.80GHz × 8, 250 GB SSD, Linux/Ubuntu 18.04).

Swoole is an asynchronous programming framework for PHP


Swoole is an asynchronous programming framework for PHP


Swoole is an asynchronous programming framework for PHP


Swoole gives you the possibility to create awesome web API or Websocket service without the resignation of Laravel abilities. It's a great tool which can help PHP developers write a complex and high-performance application, however, in my opinion, you should not use any framework with Swoole if you expect very heavy traffic and server load.


Do you need a technology partner involved in your success? Contact us/

Marek Tenus
CTO, Full-stack Engineer | Laravel & AWS fan | Nativescript & ML enthusiast

What do you need?

Website

IT system

Mobile app

Graphic design

Technical support

Chatbot

The preferred form of contact

Please provide contact details

The personal data administrator is HighSolutions sp. z o.o. (hereinafter the "Company") with headquarters in Tarnowo Podgórne, ul. Szkolna 21/1, 62-080 Tarnowo Podgórne, e-mail adress kontakt@highsolutions.pl. Detailed information on the processing of personal data can be found in the privacy policy.

Thank you!

We will get back to you soon