swoole實現數據庫鏈接池

原生 PHP CURD

讓咱們來回顧一下PHP中數據庫的使用php

<?php
# curd.php

$id   = 1;

$dbh  = new PDO();
$stmt = $dbh->prepare('SELECT * FROM  `user` WHERE `id`=:id');
$stmt ->bindValue(':id', $id);
$user = $stmt->fetch();

var_dump($user);

上述代碼, 自己是沒有任何問題。這裏咱們也不是來挑出問題的,只是以一位多年PHPer的經驗與你們交流下。web

上面程序執行過程是什麼樣子的呢?數據庫

_______________________
                |                       |
    [瀏覽器請求] ==>   [mod_php/php-fpm]  |
                |           ||          |
                |           ||          |
                |           \/          |
                |       [curd.php]      |
                |           ||          |
                |           ||          |
                |           \/          |
                |    [PDO::_construct]  | <== 請求的開銷
                |           ||          |
                |           ||          |
                |           \/          |
    [Response] <==      [PDO::CURD]     |
                |           ||          |
                |           ||          |
                |           \/          |
                |       [PDO::close]    |
                |_______________________|

Swoole PHP CURD

Java應用中,你們在進行數據庫CURD的時候,會維護一個數據庫鏈接池。在PHP的世界中,要想作鏈接池挺困難的:瀏覽器

  • PHP web應用不可長駐運行swoole

  • 不可藉助第三方服務如KV轉存句柄app

而在Swoole中咱們就能夠實現鏈接池了!php-fpm

<?php
$http = new swoole_http_server('0.0.0.0', 80, SWOOLE_BASE);
$http->db->dbh = new PDO();

$http->on('request', function(swoole_http_request $req, swoole_http_response $res) use($http) {
    $id = 1;
    $stmt = $http->db->dbh->prepare('SELECT * FROM  `user` WHERE `id`=:id');
    $stmt ->bindValue(':id', $id);
    $user = $stmt->fetch();

    $res->end(var_export($user, true));
    unset($stmt);
});

執行流程測試

[php app.php]
                           ||
                           ||
                           \/
                    [PDO::__construct]
                           ||
               ____________||________________
              |            \/                |
  [瀏覽器請求] ==>   [ ->onRequest(\Closure) ] |
              |            ||                |
              |            ||                | <== 請求開銷
              |            \/                |
  [Response] <==      [PDO::CURD]            |
              |____________||________________|
                           ||
                           \/
                     [PDO::close]

分析上面流程, Swoole不用再每次請求時去創建數據庫鏈接, 既避免了給數據庫過多壓力, 也更迅速的處理核心業務邏輯. 也許你以爲這優點不明顯, 可是在c10k問題(Connections over 10,000)場景中, 優點就很是明顯了吧?固然, 上面的demo只是拋磚引玉, 沒有實現multi connections pool, 若是你們要作生產化代碼, 務必實現鏈接池, idle鏈接數按照業務須要, 好比80%的時間鏈接數200, 設置200個idle的鏈接池是最優的.fetch

PHP有了鏈接池,咱們的應用就能夠不用再在收到請求時去建立數據庫鏈接了。
試試上面的代碼,與曾經碰到過3000+數據庫鏈接的煩惱bye bye吧~spa

[本節完, 文字未校對, 程序未測試]

相關文章
相關標籤/搜索