PHP的異步Web服務器+異步Redis客戶端

PHP的異步並行swoole擴展在1.7.7中內置了一個Http服務器,利用swoole_http_server能夠輕鬆實現一個PHP的異步Web服務器,性能比php-fpm/Apache等同步阻塞的服務器高出數倍。php

swoole官方還提供了redis-async,一個異步IO+鏈接池的Redis客戶端。這2個功能結合起來就能夠打造一個併發請求數萬的Web應用。nginx

使用方法

1. 下載安裝swoole擴展

能夠使用pecl安裝或者從github下載swoole最新的stable版本。git

pecl install swoole

修改php.ini加入extension=swoole.sogithub

二、下載redis-async代碼

git clone https://github.com/swoole/redis-async.git

三、編寫服務器代碼server.php

$http = new swoole_http_server("127.0.0.1", 9501);
$http->set(['worker_num' => 8]);
require __DIR__.'/src/Swoole/Async/RedisClient.php';
$redis = new Swoole\Async\RedisClient('127.0.0.1');

$http->on('request', function ($request, $response) use ($redis) {
    $redis->get('key1', function($result) use($response) {
        $response->end("<h1>Hello Swoole. value=".$result."</h1>");
    });
});

$http->start();

運行server.php程序,這裏一共啓動了8個進程。注意因爲是異步非阻塞的服務器程序,因此不須要像Apache/PHP-fpm那樣開啓數百的進程。這裏徹底是沒有等待的,所有是事件驅動。當請求到來發起redis請求,redis-server響應後會觸發對應的事件,再渲染頁面,將HTML頁面經過$response->end接口發送給瀏覽器。redis

php server.php

Http服務器啓動監聽了9501端口,瀏覽器中能夠打開 http://127.0.0.1:9501 訪問頁面。本程序的邏輯很簡單,只是從redis中取一個數據,並渲染頁面。shell

四、使用ab工具進行壓力測試

ab -c 200 -n 100000 -k http://127.0.0.1:9501/

機器環境是:Inter CoreI5 4核CPU+8G內存,Ubuntu 14.04瀏覽器

壓測結果:服務器

Server Software:        swoole-http-server
Server Hostname:        127.0.0.1
Server Port:            9501

Document Path:          /
Document Length:        40 bytes

Concurrency Level:      200
Time taken for tests:   2.853 seconds
Complete requests:      100000
Failed requests:        0
Keep-Alive requests:    100000
Total transferred:      16800000 bytes
HTML transferred:       4000000 bytes
Requests per second:    35049.02 [#/sec] (mean)
Time per request:       5.706 [ms] (mean)
Time per request:       0.029 [ms] (mean, across all concurrent requests)
Transfer rate:          5750.23 [Kbytes/sec] received

能夠達到3.5萬QPS,性能驚人,僅僅使用一臺普通的PC機器,硬件性能通常。若是是在服務器硬件環境中,性能能夠更好。swoole

五、與Nginx+PHP-fpm結果對比

PHP-fpm已開啓OpCache,採用phpredis擴展,已啓用pconnect長鏈接,測試啓動80進程。測試代碼以下:
併發

$redis = new redis;
$redis->pconnect('127.0.0.1');
$result = $redis->get('key1');
echo "<h1>Hello Swoole. value=".$result."</h1>";

測試結果:

Server Software:        nginx/1.4.6
Server Hostname:        127.0.0.1
Server Port:            80

Document Path:          /redis.php
Document Length:        40 bytes

Concurrency Level:      200
Time taken for tests:   15.605 seconds
Complete requests:      100000
Failed requests:        0
Keep-Alive requests:    0
Total transferred:      21000000 bytes
HTML transferred:       4000000 bytes
Requests per second:    6408.33 [#/sec] (mean)
Time per request:       31.209 [ms] (mean)
Time per request:       0.156 [ms] (mean, across all concurrent requests)
Transfer rate:          1314.21 [Kbytes/sec] received
相關文章
相關標籤/搜索