Where is Laravel slow?

  • The initialization framework requires loading 208+ files to be loaded
  • Each file needs to be parsed and compiled
  • The compiled results are destroyed at the end of each request
  • The defaultsessionDrivers are also file-based
  • Laravel itself is a full-stack, component framework

Laradock installation Swoole

In the local environment, Laradock is used as an example. Set the following two values to true in the. Env directory of Laradock

. WORKSPACE_INSTALL_SWOOLE=true. PHP_FPM_INSTALL_SWOOLE=true.Copy the code

Then run rebuild Docker container

$ docker-compose build php-fpm workspace
Copy the code

After the build is complete, restart the two containers, enter the workspace container, and run PHP-m to check whether Swoole is successfully installed. If the extended list contains Swoole, the installation is successful.

$ php -m | grep swoole

swoole
Copy the code

Tips: Extra Tips

Remove the mirror

docker rmi $(docker images --filter "dangling=true" -q --no-trunc)
Copy the code

Deleting All Mirrors

docker image prune -a -f
Copy the code

Clear the Container and Image

docker system prune
Copy the code

Recompiling the image

$ cd ~/laradock

$ docker-compose build php-fpm workspace mysql redis
Copy the code

Differences between workspace and PHP-FPM

Env contains two similar configurations: workspace and php-fpm, which correspond to two different containers: FPM and CLI. Whether you install plug-ins or modify configurations, keep these changes separate.

Create a Laravel development environment using Laradock

CentOS compiles and installs Swoole

In the server, clone the source code

$ git clone https://gitee.com/swoole/swoole
Copy the code

Go to the Swoole directory and compile and install


$ cd swoole

$ phpize 
Configuring for:
PHP Api Version:         20170718
Zend Module Api No:      20170718
Zend Extension Api No:   320170718

$ ./configure
checking for grep that handles long lines and -e... /usr/bin/grep
checking for egrep... /usr/bin/grep -E
checking for a sed that does not truncate output... /usr/bin/sed
checking for cc... cc
checking whether the C compiler works... yes
checking for C compiler default output fi. configure: creating ./config.status config.status: creating config.h config.status: executing libtool commands $ make && make install ... Build complete. Don't forget to run 'make test'. Installing shared extensions: /usr/lib64/php/modules/ Installing header files: /usr/include/php/Copy the code

configure: error: in `/root/swoole’: configure: error: C++ preprocessor “/lib/cpp” fails sanity check

Encounter the above problems

$ yum install  -y glibc-headers 

$ yum install -y gcc-c++
Copy the code

Verify that the swoole extension is installed

$ php -m|grep swoole
Copy the code

If it does not load successfully, modify php.ini and add the extension. Use PHP –ini to check the php.ini file location to find out how to add extensions, such as installing extensions in my CentOS 7 as follows:

$ cd /etc/php.d

$ vi swoole.ini

; Enable zip extension module
extension=swoole.so
Copy the code

Restart PHP – FPM

$ systemctl restart php-fpm
Copy the code

Check whether the installation is successful

$ php -m | grep swoole

swoole
Copy the code

Contrast larave-s with LaravelTW extensions

  • The two are neck and neck in Github activity /Star/fork
  • Laravel-s: features, QQ group communication fast, active update
  • Swooletw: Taiwanese community maintenance, support socket.io
  • Laravel-s returns 500 with an error when handling an exception, which is not suitable for JSON return scenarios
  • Laravetw is differentiated from WebSocket in HTTP by Route, which is more in line with Laravel specification

In summary, the LaravelTW extension is recommended.

Install LaravelS

Install the latest version of Composer

composer require "Hhxsv5 / laravel -s: ~ 3.5.0." " -vvv
Copy the code

Release configuration

php artisan laravels publish
Copy the code

Enabling the HTTP Service

[root@iz8vbh3xuahhi5gqllg1u1z current]# php bin/laravels startThere comes / _ _ _____ | | | | | | | __ _ _ __ __ _____ _____ | | (___ | | / _ ` |'__/ _` \ \ / / _ \ |\___ \ | |___| (_| | | | (_| |\ V / __/ |____) | |______\__,_|_| \__,_| \_/ \___|_|_____/ Speed up your Laravel/Lumen >>> Components +-------------------------+--------------+ | Component | Version | + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - + -- -- -- -- -- -- -- -- -- -- -- -- -- -- + | | PHP 7.2.22 | | Swoole | 4.4.13 - alpha | | LaravelS | 3.5.14 | | Laravel Framework (dev) | 6.4.1 | + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - + -- -- -- -- -- -- -- -- -- -- -- -- -- -- + > > > separate Protocols +-----------+--------+-------------------+----------------+ | Protocol | Status | Handler | Listen At | + -- -- -- -- -- -- -- -- -- -- - + + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + | | the Main HTTP On | Laravel Framework | 127.0.0.1:5200 | +-----------+--------+-------------------+----------------+ >>> Feedback: https://github.com/hhxsv5/laravel-s [2019-11-13 09:14:52] [TRACE] Swoole is running, press Ctrl+C to quit.Copy the code

Manage processes using Supervisor

[program:develop-laravel-swoole-api]
command=/usr/bin/php /var/www/develop/zqz/api/current/bin/laravels start -i
numprocs=1
autostart=true
autorestart=true
startretries=3
redirect_stderr=true
stdout_logfile=/var/www/develop/zqz/api/current/storage/logs/supervisord-stdout.log
user=apache
Copy the code

NGINX configuration

map $http_upgrade $connection_upgrade { default upgrade; '' close; } upstream swoole {# connect to server 127.0.0.1:5200 weight=5 max_fails=3 fail_timeout=30s; Connect via UnixSocket Stream Put the socket file in the /dev/shm directory Can obtain better performance # server: Unix/xxxpath/laravel - s - the test/storage/laravels sock weight = 5 max_fails = 3 fail_timeout = 30 s; #server 192.168.1.1:5200 weight=3 max_fails=3 fail_timeout=30s; 5200 # server 192.168.1.2 instead: backup; keepalive 16; } server { listen 80; server_name api-dev.zqz.com; root /var/www/develop/zqz/api/current/public; access_log /var/log/nginx/api-dev.zqz.com.access.log main; gzip on; gzip_comp_level 9; gzip_buffers 4 32k; gzip_min_length 1k; gzip_types text/plain application/json application/x-javascript application/css application/xml application/xml+rss text/javascript application/x-httpd-php image/jpeg image/gif image/png image/x-ms-bmp; gzip_vary on; autoindex off; index index.html index.htm; # Nginx handles static resources (gzip is recommended) while LaravelS handles dynamic resources. location / { try_files $uri @laravels; } # Javascript: var ws = new WebSocket("ws://laravels.com/ws"); Location =/ws {proxy_http_version 1.1; # proxy_connect_timeout 60s; # proxy_send_timeout 60s; # proxy_read_timeout: If the proxied server does not respond to Nginx within 60 seconds, then Nginx will close the current connection; At the same time, Swoole's heartbeat Settings also affect connection closure # proxy_read_timeout 60s; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-PORT $remote_port; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_set_header Scheme $scheme; proxy_set_header Server-Protocol $server_protocol; proxy_set_header Server-Name $server_name; proxy_set_header Server-Addr $server_addr; proxy_set_header Server-Port $server_port; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; proxy_pass http://swoole; } location@laravels {proxy_http_version 1.1; # proxy_connect_timeout 60s; # proxy_send_timeout 60s; # proxy_read_timeout 120s; proxy_set_header Connection ""; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-PORT $remote_port; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_set_header Scheme $scheme; proxy_set_header Server-Protocol $server_protocol; proxy_set_header Server-Name $server_name; proxy_set_header Server-Addr $server_addr; proxy_set_header Server-Port $server_port; proxy_pass http://swoole; }}Copy the code

Install laraveltw/laravel – swoole

Install the latest version of Composer

composer require swooletw/laravel-swoole -vvv
Copy the code

Release configuration

php artisan vendor:publish --tag=laravel-swoole
Copy the code

Running the HTTP service

[root@iz8vbh3xuahhi5gqllg1u1z current]# php artisan swoole:http infos+-----------------+---------------------------------------------------------------------------------+ | Name | Value | +-----------------+---------------------------------------------------------------------------------+ | PHP Version | 7.2.22 | | Swoole Version | 4.4.13 - alpha | | Laravel Version | 6.4.1 | | | Listen IP 127.0.0.1 | | Listen Port 1215 | | | Server Status | Offline | | Reactor Num | 8 | | Worker Num | 8 | | Task Worker Num | 0 | | Websocket Mode | Off | | Master PID | None | | Manager PID | None | | Log Path | /var/www/develop/zqz/api/releases/05c0ab09/storage/logs/swoole_http.log | +-----------------+---------------------------------------------------------------------------------+Copy the code

Manage processes using Supervisor

[program:develop-laravel-swoole-api]
command=/usr/bin/php /var/www/develop/zqz/api/current/artisan swoole:http start
numprocs=1
autostart=true
autorestart=true
startretries=3
user=apache
Copy the code

NGINX configuration

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

server {
    listen  80;

    server_name  api-dev.zqz.com;
    root   /var/www/develop/zqz/api/current/public;
    access_log  /var/log/nginx/api-dev.zqz.com.access.log  main;


    gzip on;
    gzip_comp_level 9;
    gzip_buffers 4 32k;
    gzip_min_length  1k;
    gzip_types text/plain application/json application/x-javascript application/css application/xml application/xml+rss text/javascript application/x-httpd-php image/jpeg image/gif image/png image/x-ms-bmp;
    gzip_vary on;

    autoindex off;
    index index.html index.htm;
    location = /index.php {
        # Ensure that there is no such file named "not_exists"
        # in your "public" directory.
        try_files /not_exists @swoole;
    }
    # any php files must not be accessed
    #location ~* \.php$ {
    #    return 404;
    #}
    location / {
        try_files $uri $uri/ @swoole;
    }

    location @swoole {
        set $suffix "";

        if ($uri = /index.php) {
            set $suffix ?$query_string;
        }

        proxy_http_version 1.1;
        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";

        proxy_pass http://127.0.0.1:1215$suffix;
    }
}
Copy the code

Problem sets

  1. Solve the error:Auth guard driver [api] is not defined.
$ vi config/swoole_http.php

...

 'providers' => [
        Illuminate\Pagination\PaginationServiceProvider::class,
        //Solve the error:`Auth guard driver [api] is not defined.`
        Laravel\Passport\PassportServiceProvider::class,
    ],
...
Copy the code

Wrk-http benchmark

WRK is a modern HTTP benchmark tool that can generate significant load when run on a single multicore CPU. It combines a multi-threaded design with extensible event notification systems such as Epoll and KQueue.

Command line options

-c, --connections: total number of HTTP connections to keep open with
                   each thread handling N = connections/threads

-d, --duration:    duration of the test, e.g. 2s, 2m, 2h

-t, --threads:     total number of threads to use

-s, --script:      LuaJIT script, see SCRIPTING

-H, --header:      HTTP header to add to request, e.g. "User-Agent: wrk"

    --latency:     print detailed latency statistics

    --timeout:     record a timeout if a response is not received within
                   this amount of time.
Copy the code

wrkPressure test

  • CentOS 7.X
  • 8 CPU 16 G
Create 100 connection requests with 10 threads

$ wrk -t10 -c100 http://api-dev.zqz.com
Copy the code

Use NGINX + php-fpm

Running 10s test@http://api-dev.zqz.com 10 threads and 100 connections Thread Stats Avg Stdev Max +/- Stdev Latency 364.10ms 347.89ms 2.00s 86.97% Req/Sec 10.64 8.31 59.00 67.01% 746 requestsin10.10 s, 1.30 MBread
  Socket errors: connect 0, read0, write 0, timeout 86 non-2XX or 3XX responses: 746 Requests/ SEC: 73.86 Transfer/ SEC: 132.15KBCopy the code

Use NGINX + Swoole(laraveltw)

Running 10s test@http://api-dev.zqz.com 10 threads and 100 connections Thread Stats Avg Stdev Max +/- Stdev Latency 234.30ms 275.83ms 1.37s 81.79% Req/Sec 39.66 29.85 200.00 78.56% 3816 requestsin10.10 s, 1.18 MBread
  Socket errors: connect 0, read0, write 0, timeout 77 non-2XX or 3XX responses: 3816 Requests/ SEC: 377.69 Transfer/ SEC: 119.50KBCopy the code

Speed Up Laravel on Top of Swoole

Use Laravel-swoole to speed up your Laravel application in a Laradock environment

PHP & Swoole and Java, Go and other technology selection questions

Create a Laravel development environment using Laradock