swoole-foundation / yii2-swoole-extension

running yii2 app on swoole
MIT License
41 stars 5 forks source link

Replace web.php to swoole.php in server.php #3

Closed RicardoSette closed 3 years ago

RicardoSette commented 4 years ago

Before I start, congratulations on the beautiful job of integrating Yii2 with Swoole.

When executing the step by step I found errors, simple to be corrected, but that can generate discomfort in those who are trying to test Swoole with Yii2.

In the server.php file we have:

// config/server.php
<?php

return [
    'host' => 'localhost',
    'port' => 9501,
    'mode' => SWOOLE_PROCESS,
    'sockType' => SWOOLE_SOCK_TCP,
    'app' => require __DIR__ . '/web.php', // your original web.php
    'options' => [// options for swoole server
        'pid_file' => __DIR__ . '/../runtime/swoole.pid',
        'worker_num' => 2,
        'daemonize' => 0,
        'task_worker_num' => 2,
    ]
];

but the recommendation thing for a basic application with swoole would be:

// config/server.php
<?php

return [
    'host' => 'localhost',
    'port' => 9501,
    'mode' => SWOOLE_PROCESS,
    'sockType' => SWOOLE_SOCK_TCP,
    'app' => require __DIR__ . '/swoole.php', // your original web.php
    'options' => [// options for swoole server
        'pid_file' => __DIR__ . '/../runtime/swoole.pid',
        'worker_num' => 2,
        'daemonize' => 0,
        'task_worker_num' => 2,
    ]
];

and file swoole.php is:

// config/swoole.php
<?php

$config = require __DIR__ . '/web.php';

$config['components']['response']['class'] = swoole\foundation\web\Response::class;
$config['components']['request']['class'] = swoole\foundation\web\Request::class;
$config['components']['errorHandler']['class'] = swoole\foundation\web\ErrorHandler::class;

return $config;

This is because the default in web.php uses yii\web\Response, yii\web\Request and yii\web\ErrorHandler, making it incompatible with Swoole way of working.

Benchmark on the machine comparing Yii2 with Swoole and Yii2 with PHP-FPM, both below NGINX:

example NGINX file:

http {
     ...
     ...
    upstream swoole{
        server 127.0.0.1:9503;
    }
     ...
     ...
    server {
        ...
        ... 
    location /apiswoole {
            try_files $uri $uri/ @swoole;
        }
        location @swoole {
            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_pass http://127.0.0.1:9503;
        }
        ... 
        ... 
        location ~ \.php$ {
            fastcgi_pass 127.0.0.1:65090;
            fastcgi_index index.php;
            include /usr/local/etc/nginx/fastcgi_params;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_param REMOTE_USER $remote_user;
            fastcgi_buffers 16 256k;
            fastcgi_buffer_size 256k;
            fastcgi_hide_header X-Powered-By;
            fastcgi_hide_header Server;
        }
        ... 
        ... 
    }
}
# curl -i http://127.0.0.1/api/hello
HTTP/1.1 200 OK
Date: Wed, 11 Mar 2020 15:14:46 GMT
Content-Type: application/json; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Keep-Alive: timeout=20
Vary: Accept
Strict-Transport-Security: max-age=15768000; includeSubdomains; preload;

{
    "return": "world"
}
# curl -i http://127.0.0.1/apiswoole/hello
HTTP/1.1 200 OK
Date: Wed, 11 Mar 2020 15:14:30 GMT
Content-Type: application/json; charset=UTF-8
Content-Length: 25
Connection: keep-alive
Keep-Alive: timeout=20
Vary: Accept
Strict-Transport-Security: max-age=15768000; includeSubdomains; preload;

{
    "return": "world"
}
# wrk -t1 -c100 -d10s http://127.0.0.1/api/hello
Running 10s test @ http://127.0.0.1/api/hello
  1 threads and 100 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     1.18s   642.93ms   2.00s    51.39%
    Req/Sec    41.00     19.71    89.00     66.67%
  348 requests in 10.04s, 108.75KB read
  Socket errors: connect 0, read 0, write 0, timeout 276
Requests/sec:     34.68
Transfer/sec:     10.84KB
# wrk -t1 -c100 -d10s http://127.0.0.1/apiswoole/hello
Running 10s test @ http://127.0.0.1/apiswoole/hello
  1 threads and 100 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   295.84ms  488.32ms   1.97s    84.43%
    Req/Sec     1.77k   813.94     3.34k    62.07%
  10652 requests in 10.07s, 3.06MB read
Requests/sec:   1058.10
Transfer/sec:    310.83KB

As the test machine is a virtual machine, see that PHP-FPM answered several requests with timeout, so I lowered the number of connections from 100 to 10, see now:

# wrk -t1 -c10 -d10s http://127.0.0.1/api/hello
Running 10s test @ http://127.0.0.1/api/hello
  1 threads and 10 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   304.32ms  341.21ms   1.84s    89.21%
    Req/Sec    51.24     18.84    90.00     65.48%
  446 requests in 10.08s, 139.38KB read
Requests/sec:     44.27
Transfer/sec:     13.83KB
# wrk -t1 -c10 -d10s http://127.0.0.1/apiswoole/hello
Running 10s test @ http://127.0.0.1/apiswoole/hello
  1 threads and 10 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   137.86ms  283.97ms   1.79s    87.00%
    Req/Sec     1.41k   832.86     3.12k    65.52%
  12826 requests in 10.13s, 3.68MB read
Requests/sec:   1266.31
Transfer/sec:    371.88KB

So what we have:

+- 400 requests in 10 seconds for 12000 requests or +- 40 req/s to 1200 req/s

With that we can say that Swoole is the great solution for PHP to fight Go and Node

xialeistudio commented 4 years ago

Thanks for your advice, I was thinking that I just need to provide some components with swoole, you can odify by yourself. But on this issue, I think I should provide a default options for users. I'll changed soon.

xialeistudio commented 3 years ago

Thanks for your good idea! It already has been done.