php針對mysql的orm: 一個輕量級的pdo操作類

字號+ 編輯: 种花家 修訂: SyncLWT 來源: 原创 2023-09-12 我要說兩句(1)

帶簡單連貫操作方法和redis緩存功能的pdo操作類php源碼

ORM編寫目的

php換姿勢curd的老話題不斷, 本orm是基於最近流行的swoole擴展而提出的解決方案, 韓天峰的swoole帶給phper全新的編程思路, 原來php還可以常駐内存踢掉php-fpm支配環節, 甚至可以忽略nginx中間件搞起微服務。在nginx+php-fpm業務流程下, 正常的涉及php計算的用戶訪問處理流程是這樣的:

  1. nginx的master進程發現用戶訪問並將請求信息移交給worker進程

  2. worker進程路由到index.php(如果你配置寫的完全正確的情況下)

  3. location裡面會命令nginx加載到nginx所夾帶的fast-cgi模塊

  4. fast-cgi告訴nginx我要監聽本機9000耑口, 有事情就轉發到9000耑口

  5. 剛剛好php-fpm也在監聽9000耑口

  6. php-fpm拿到傳入的請求信號, 調起它自己的worker來處理

  7. php-fpm調來的worker處理完畢, 丟還給nginx

  8. nginx回傳給訪問用戶。


swoole創始團認爲, 要不要搞這麽麻煩? 干脆省下一堆, 都一次性“預熱”到内存裡面來, 也不要php-fpm來調來調去, 如此, 就産生了常駐内存的php進程(或是一組master+worker)來處理特定的數據請求, 諸如此類的微服務模式。

關於斷線重連

接著問題來了,常駐内存雖然看起來很美麗,可是Mysql的連接並不穩定, 韓天峰先生在swoole連接池、異步、斷線重連(https://wiki.swoole.com/wiki/page/350.html) 這篇文章當中就有提到過MySQL連接不穩定的幾個因素:

1、MySQL服務器一定時間内自動切斷連接;

2、那種長期無查詢佔茅坑不拉屎的TCP連接會被MySQL切斷回收;

3、主動用命令kill process殺死連接, 或者MySQL服務器重新啓動

筆者隔一段時間會捕獲到類似下面的錯誤

Error while sending STMT_PREPARE packet. PID=xxxxx
# 實際就是下方這個報錯導致的, PDOException錯誤代碼爲HY000
server has gone away

phper需要發明出一套名叫“斷線重連”的輪子, 或者想出一套路子維持連接生命周期, 來解決這個問題。有人說搞連接池來解決,還是沒有解決到點子上, 連接池裡面的連接也是一樣觸發數據庫的周期斷線機制好伐……

關於Hprose拋出異常崩掉業務流程之坑

MySQL配置文档my.cnf裡面的interactive_timeout和wait_timeout(特別是wait_timeout)選項, 改到3600, 也就是1小時, 你網站不至於連續1個小時都沒人看吧? 做個網頁爬蟲1小時之内主動爬一下你的頁面, 比如你開了2個worker, 那麽1小時以内你要連續點兩次頁面來重置訪問連接計數器, 不要改太長時間, 容易産生大量僵屍連接。

interactive_timeout和wait_timeout默認值爲8小時。

嘮叨一下報錯填坑過程:

  1. 筆者參考laravel 5最新的orm, 扒了一套方法is_break外加pdo精美的捕獲, 做了斷線重連, 但是會報Warning錯誤;

  2. 網上thinkphp5.x非正式版本也遇到過這方面問題, 運用了和laravel類似的解決方式, 同樣, 用swoole在内存中持續使用的時候, Warning隔三差五該出的還是會遇到的。

以上問題, 得出結論, 只能選擇發呆忽略。接下來的問題筆者項目用到yaf, 其定制的異常處理機制會捕獲到hprose客戶耑拋出的io異常(EXCEPTION/FATAL ERROR)錯誤, 需要設法跳開這個錯誤, 否則yaf會把業務流程引向error處理機制上

曾嘗試過在實例化pdo時將\PDO::ATTR_ERRMODE這個選項改成\PDO::ERRMODE_SILENT, 發現pdo實例調用prepare方法時, Warning會被包裹著hrpose的swoole發送到hporse客戶耑, 而客戶耑將Warning錯誤升級爲異常級別拋出, 此時:

  1. 服務耑改用捕獲pdo實例中的errorInfo方法取得數組或者errorCode方法來拿錯誤代碼判斷是否閃斷;

  2. 使用try catch捕獲異常(顯然沒門);

  3. 用@符號掩蓋掉prepare這一句的Warning錯誤

以上都會觸發Warning的前提下,在hprose調用swoole服務耑的時候隨後跟上一句修改報錯等級, 以下是實際代碼:

$server = new Server('tcp://0.0.0.0:1314');
// 將E_WARNING屏蔽
$server->setErrorTypes(E_ERROR);

實測發現加或者不加這行配置, 結果都是一樣的, 現有的Hprose還是拋異常。

以我半小時都沒人點一下的小部落格而言, 測試結果爲: swoole自帶的set方法有個提高worker數量, 可以用, 但Reactor必須等於1, 就解決報錯的問題了。本人底層學的很菜, 原因未知, 稀裡糊塗, 相關的參考文档 https://wiki.swoole.com/wiki/page/163.html

另外,仔細翻了下文档, 其中說到dns攜帶的參數裡可以指定ATTR_PERSISTENT和ATTR_TIMEOUT兩個屬性, 經過實測, 未果, 該報警告還是報警告。另外, 據某些部落格說ATTR_PERSISTENT在敺動層已經集成了連接池, 這可是個不錯的消息(實際對這個問題還是沒用)。

代碼地址

http://www.wkwkk.com/article/aee0450ce1aff796f87af84777cf8683.html

使用說明

針對該ORM的使用文档請移步地址: http://www.wkwkk.com/article/258078a0ef7a23f89655ac669a52f8a9.html

可實例化pdo操作類的基礎模型類

如此一來, 再寫一個BasicModel實例化這個pdo操作類就可以當基礎模型來用了, 這個地址 http://wkwkk.com/article/98a742396c78db8ed15c32649c70e9c4.html 是一個在Yaf中讀寫分離的代碼例子:

解決爬蟲類腳本内存不斷上升不釋放的問題

對於小内存主機來說,如果你不去切割爬蟲腳本的工作, 當然在php單任務生命周期内, 内存的升高問題是很難得到緩解的。

如果你偏偏就是不喜歡切割任務,那麽看pdo操作類裡面有一句:

PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true,

將true改爲false

關掉pdo緩沖操作來節省内存。


閲完此文,您的感想如何?
  • 有用

    1

  • 沒用

    1

  • 開心

    1

  • 憤怒

    1

  • 可憐

    1

1.如文章侵犯了您的版權,請發郵件通知本站,該文章將在24小時内刪除;
2.本站標注原創的文章,轉發時煩請注明來源;
3.交流群: 2702237 13835667

相關課文
  • mac開發接入微信公衆號接口返回報錯 cURL error 56: SSLRead() return error -9806

  • PHP的換行符是什麽

  • pecl安裝程序時報錯Array and string offset access syntax with curly braces is no longer supported

  • 由於商家傳入的H5交易參數有誤,該筆交易暫時無法完成,請聯繫商家解決

我要說說
網上賓友點評
1 樓 IP 223.20.***.26 的嘉賓 高兴地说 : 很久前
666666666