搭建一個基於swoole的http框架來跑跑curd用作效能測試

Latent發表於2021-04-15

基於swoole搭建的一個高效能的HTTP伺服器

目錄結構

├── README.md
├── bin
│   ├── Client.php
│   ├── Command.php
│   ├── HttpServer.php
│   ├── Log.php
│   ├── Route.php
│   ├── ServerQueue.php
│   ├── controller
│   │   ├── Controller.php
│   │   ├── IndexController.php
│   │   └── Response.php
│   ├── exception
│   │   └── HttpException.php
│   ├── pool
│   │   ├── DB.php
│   │   ├── DbPool.php
│   │   ├── Mysql.php
│   │   ├── Mysqli.php
│   │   ├── PDO.php
│   │   └── RedisPool.php
│   ├── queue
│   │   └── Queue.php
│   ├── static
│   │   └── favicon.ico
│   └── utility
├── composer.json
├── composer.lock
├── config
│   ├── database.php
│   ├── email.php
│   ├── log.php
│   ├── route.php
│   └── server.php
├── docs
├── helpers.php
├── http.php
├── tcp.php
├── test
├── test.php
└── view
 ├── 404.html ├── echarts.html └── log_list.html```

#### 功能簡潔
 * 使用大量單例 避免使用 `static`屬性 PHP全域性變數產生記憶體洩漏問題
 * 支援簡單的路由分發\控制 簡潔的控制器
 * 支援redis、mysql連線池 實現了curd 以及事務操作

#### 要求

 * php版本>=7.3
 * swoole4

#### 安裝使用

get clone github.com/pl1998/swoole_http.git
php http.php


#### 全域性輔助函式檔案 `helpers.php 通過`composer.json`檔案 中`autoload` 實現了自動載入
 * 主要實現一些全域性函式 讀取檢視函式 view()  讀取配置函式 config()```json
 ... "autoload": { "psr-4": { "app\\": "bin" //主目錄自動載入 對映名稱空間 }, "files": [ "helpers.php" ] } ...```

#### 配置檔案
```shell script
├── config
│   ├── database.php //資料庫配置
│   ├── email.php    //郵件配置
│   ├── log.php      //日誌驅動
│   ├── route.php    //路由檔案
│   └── server.php  //tcp http 配置以及埠

新增路由 router.php

/**
 * 路由配置 */return [
 'GET'  => [ '/favicon.ico'=>false,
 //訪問路徑 => 例項控制器 方法名      '/api/test'=>[\app\controller\TestController::init(),'test'],
 ], 'POST' => [
 ], 'PUT'  => [
 ], 'DELETE' => [
 ]];

控制器

namespace app\controller;

use app\pool\DbPool;

class TestController
{

 //每個控制器都應該有的單例 protected static $init;

 public static function init()
 { if(is_null(static::$init)) {
 echo "載入控制器單例"."\n";  static::$init = new self();
 } return static::$init;
 }     //拿到請求和響應
 public function test(object $request,object $response)
 { //業務邏輯 $db = new DbPool();           
                  $id = $db->table('users')->insert([
 'name'=>'latent', 'password'=>'', 'avatar'=>'', 'email'=>'pltruenine@163.com', 'created_at'=>date('Y-m-d H:i:s'),
 'updated_at'=>date('Y-m-d H:i:s'),
 'uid'=>'56895', 'age'=>22, ]);  $response->header('Content-Type','application/json');
  $response->end(success([
 'id'=>$id ],'插入成功'));
 }}

啟動伺服器

php http.php---------------
$ php http.php0.0.0.0:9501

瀏覽器訪問0.0.0.0:9501 嘗試多請求幾次

命令列

$ php http.php0.0.0.0:9501
當前使用記憶體:1489312
載入路由單例
載入Index控制器單例
載入Test控制器單例
當前使用記憶體:1584304
當前使用記憶體:1584304
當前使用記憶體:1584304
當前使用記憶體:1584304
當前使用記憶體:1584304
當前使用記憶體:1584304
當前使用記憶體:1584304

開始測試

wrk -t4 -c50 -d30 http://127.0.0.1:9501/api/test```

![](https://cdn.learnku.com/uploads/images/202104/15/32593/DLgVnd1GPp.png!large)

![](https://cdn.learnku.com/uploads/images/202104/15/32593/1CltL8VTLa.jpeg!large)

#### 此時已經插入了3萬多條資料了

![](https://cdn.learnku.com/uploads/images/202104/15/32593/I7tzRy1a3t.png!large)

#### 感覺不太行 可能是連線池的問題

```php

return [
 'mysql' =>[ 'host'=>'127.0.0.1', 'port'=>3306, 'coding'=>'utf8mb4', 'dbname'=>'swoole', 'username'=>'root', 'password'=>'root', 'size'=>15, //預設只給連線池15個連線 ]];

我們來跑hello world


 public function test(object $request,object $response)
 {  $response->header('Content-Type', 'text/html');
  $response->end("hello world!");
 }

這效能只比gRPC(3萬多)差一萬多

連線池調大繼續測試

結論

Latency引數明顯高了 但Requests/sec 只提高了40個的樣子.

這樣才能繼續提高效能?️

最好可以幫我點個star

本作品採用《CC 協議》,轉載必須註明作者和本文連結
不成大牛,不改個簽

相關文章