摘要:概述這是關(guān)于入門學(xué)習(xí)的第八篇文章連接池的實(shí)現(xiàn)。開始今天的文章,這篇文章實(shí)現(xiàn)了連接池,代碼是在的實(shí)現(xiàn)文章的基礎(chǔ)上進(jìn)行開發(fā)的。
概述
這是關(guān)于 Swoole 入門學(xué)習(xí)的第八篇文章:Swoole MySQL 連接池的實(shí)現(xiàn)。
第七篇:Swoole RPC 的實(shí)現(xiàn)
第六篇:Swoole 整合成一個(gè)小框架
第五篇:Swoole 多協(xié)議 多端口 的應(yīng)用
第四篇:Swoole HTTP 的應(yīng)用
第三篇:Swoole WebSocket 的應(yīng)用
第二篇:Swoole Task 的應(yīng)用
第一篇:Swoole Timer 的應(yīng)用
收到讀者的咨詢,這情況大家可能也會(huì)有,所以就在這說說:
“亮哥,我今年30歲了,有點(diǎn)中年危機(jī),最近有點(diǎn)焦慮,發(fā)現(xiàn)工作雖然很忙,但是沒感覺能力有所提升,整天都有寫不完的業(yè)務(wù)代碼,時(shí)間緊有時(shí)代碼質(zhì)量也不怎么樣,知道還有很多改進(jìn)空間,但一直沒時(shí)間改,主要是后面項(xiàng)目壓著,馬上又要進(jìn)入開發(fā)了,這種情況怎么辦?”
首先,我是菜雞,觀點(diǎn)不喜勿噴,那我就說下自己的看法:
上面的描述比較主觀,人呀有時(shí)候發(fā)現(xiàn)不了自己的能力很正常,有時(shí)候有能力了并不是馬上就能顯現(xiàn)的,而是到了某個(gè)階段后突然發(fā)現(xiàn),哇塞,原來自己這么厲害。
當(dāng)然能力也分很多種,比如專業(yè)能力,快速學(xué)習(xí)能力,進(jìn)度把控能力,還有自信也是一種能力,不要臉是一種能力,堅(jiān)持不要臉更是一種能力。
其實(shí)能力提升最快的還是靠工作實(shí)踐,悄悄問問自己加入了很多大牛的微信群,能力提升了嗎?看書自學(xué)不實(shí)踐是不是吸收的也不多。
如果非要給一個(gè)具體的方案,那就是在團(tuán)隊(duì)內(nèi)多分享吧,因?yàn)樵诜窒砬澳銜?huì)做充分的準(zhǔn)備來避免分享時(shí)出丑,即使有時(shí)候自己知道,當(dāng)講出來的時(shí)候就不是那么回事了。
前期分享可以是看稿,后期練習(xí)無稿分享。
然后,再多說一點(diǎn),30了給自己一個(gè)目標(biāo),不要盲目每天就是學(xué)學(xué)學(xué),比如目標(biāo)是技術(shù)專家,目標(biāo)是業(yè)務(wù)專家,都很好呀,當(dāng)然目標(biāo)與自己性格有關(guān)也不是一成不變的。
圍繞著目標(biāo)設(shè)置一些計(jì)劃,不要以為每天的學(xué)學(xué)學(xué),就覺得其他的一切就自然而來,其中還有很多機(jī)遇和人脈的因素。
最后,如果實(shí)在感覺壓得喘不過氣,就換個(gè)環(huán)境吧,別和自己過不去。
開始今天的文章,這篇文章實(shí)現(xiàn)了 Swoole MySQL 連接池,代碼是在《Swoole RPC 的實(shí)現(xiàn)》文章的基礎(chǔ)上進(jìn)行開發(fā)的。
先回顧上篇文章的內(nèi)容:
實(shí)現(xiàn)了 HTTP / TCP 請(qǐng)求
實(shí)現(xiàn)了 同步 / 異步 請(qǐng)求
分享了 OnRequest.php、OnReceive.php 源碼
業(yè)務(wù)邏輯 Order.php 中返回的是假數(shù)據(jù)
本篇文章主要的功能點(diǎn):
業(yè)務(wù)邏輯 Order.php 中返回 MySQL 數(shù)據(jù)庫中的數(shù)據(jù)。
Task 啟用了協(xié)程
支持 主/從 數(shù)據(jù)庫配置
實(shí)現(xiàn)數(shù)據(jù)庫連接池
實(shí)現(xiàn)數(shù)據(jù)庫 CURD
代碼 Order.phpmysql = $pool->get(); $this->table = "order"; } public function add($code = "", $name = "") { //TODO 驗(yàn)證 return $this->mysql->insert($this->table, ["code" => $code, "name" => $name]); } public function edit($id = 0, $name="") { //TODO 驗(yàn)證 return $this->mysql->update($this->table, ["name" => $name], ["id" => $id]); } public function del($id = 0) { //TODO 驗(yàn)證 return $this->mysql->delete($this->table, ["id" => $id]); } public function info($code = "") { //TODO 驗(yàn)證 return $this->mysql->select($this->table, ["code" => $code]); } }Task 啟用協(xié)程
一、需要新增兩項(xiàng)配置:
enable_coroutine = true task_enable_coroutine = true
二、回調(diào)參數(shù)發(fā)生改變
$serv->on("Task", function ($serv, $task_id, $src_worker_id, $data) { ... }); 修改成: $serv->on("Task", function ($serv, $task) { $task->worker_id; //來自哪個(gè)`Worker`進(jìn)程 $task->id; //任務(wù)的編號(hào) $task->data; //任務(wù)的數(shù)據(jù) });數(shù)據(jù)庫 主/從 配置
Mysql.php
數(shù)據(jù)庫連接池MysqlPool.php
pool)) { $this->config = $config; $this->pool = new chan($config["master"]["pool_size"]); for ($i = 0; $i < $config["master"]["pool_size"]; $i++) { go(function() use ($config) { $mysql = new MysqlDB(); $res = $mysql->connect($config); if ($res === false) { throw new RuntimeException("Failed to connect mysql server"); } else { $this->pool->push($mysql); } }); } } } public function get() { if ($this->pool->length() > 0) { $mysql = $this->pool->pop($this->config["master"]["pool_get_timeout"]); if (false === $mysql) { throw new RuntimeException("Pop mysql timeout"); } defer(function () use ($mysql) { //釋放 $this->pool->push($mysql); }); return $mysql; } else { throw new RuntimeException("Pool length <= 0"); } } }數(shù)據(jù)庫 CURDMysqlDB.php
_execute($arguments[0]); } } public function connect($config) { //主庫 $master = new SwooleCoroutineMySQL(); $res = $master->connect($config["master"]); if ($res === false) { throw new RuntimeException($master->connect_error, $master->errno); } else { $this->master = $master; } //從庫 $slave = new SwooleCoroutineMySQL(); $res = $slave->connect($config["slave"]); if ($res === false) { throw new RuntimeException($slave->connect_error, $slave->errno); } else { $this->slave = $slave; } $this->config = $config; return $res; } public function insert($table = "", $data = []) { $fields = ""; $values = ""; $keys = array_keys($data); foreach ($keys as $k) { $fields .= "`".addslashes($k)."`, "; $values .= """.addslashes($data[$k])."", "; } $fields = substr($fields, 0, -2); $values = substr($values, 0, -2); $sql = "INSERT INTO `{$table}` ({$fields}) VALUES ({$values})"; return $this->_execute($sql); } public function update($table = "", $set = [], $where = []) { $arr_set = []; foreach ($set as $k => $v) { $arr_set[] = "`".$k . "` = " . $this->_escape($v); } $set = implode(", ", $arr_set); $where = $this->_where($where); $sql = "UPDATE `{$table}` SET {$set} {$where}"; return $this->_execute($sql); } public function delete($table = "", $where = []) { $where = $this->_where($where); $sql = "DELETE FROM `{$table}` {$where}"; return $this->_execute($sql); } public function select($table = "",$where = []) { $where = $this->_where($where); $sql = "SELECT * FROM `{$table}` {$where}"; return $this->_execute($sql); } private function _where($where = []) { $str_where = ""; foreach ($where as $k => $v) { $str_where .= " AND `{$k}` = ".$this->_escape($v); } return "WHERE 1 ".$str_where; } private function _escape($str) { if (is_string($str)) { $str = """.$str."""; } elseif (is_bool($str)) { $str = ($str === FALSE) ? 0 : 1; } elseif (is_null($str)) { $str = "NULL"; } return $str; } private function _execute($sql) { if (strtolower(substr($sql, 0, 6)) == "select") { $db = $this->_get_usable_db("slave"); } else { $db = $this->_get_usable_db("master"); } $result = $db->query($sql); if ($result === true) { return [ "affected_rows" => $db->affected_rows, "insert_id" => $db->insert_id, ]; } return $result; } private function _get_usable_db($type) { if ($type == "master") { if (!$this->master->connected) { $master = new SwooleCoroutineMySQL(); $res = $master->connect($this->config["master"]); if ($res === false) { throw new RuntimeException($master->connect_error, $master->errno); } else { $this->master = $master; } } return $this->master; } elseif ($type == "slave") { if (!$this->slave->connected) { $slave = new SwooleCoroutineMySQL(); $res = $slave->connect($this->config["slave"]); if ($res === false) { throw new RuntimeException($slave->connect_error, $slave->errno); } else { $this->slave = $slave; } } return $this->slave; } } }OnWorkerStart 中調(diào)用try { MysqlPool::getInstance(get_config("mysql")); } catch (Exception $e) { $serv->shutdown(); } catch (Throwable $throwable) { $serv->shutdown(); }客戶端發(fā)送請(qǐng)求"SW", "token" => "Bb1R3YLipbkTp5p0", "param" => [ "class" => "Order", "method" => "add", "param" => [ "code" => "C".mt_rand(1000,9999), "name" => "訂單-".mt_rand(1000,9999), ], ], ]; //編輯 $demo = [ "type" => "SW", "token" => "Bb1R3YLipbkTp5p0", "param" => [ "class" => "Order", "method" => "edit", "param" => [ "id" => "4", "name" => "訂單-".mt_rand(1000,9999), ], ], ]; //刪除 $demo = [ "type" => "SW", "token" => "Bb1R3YLipbkTp5p0", "param" => [ "class" => "Order", "method" => "del", "param" => [ "id" => "1", ], ], ]; //查詢 $demo = [ "type" => "SW", "token" => "Bb1R3YLipbkTp5p0", "param" => [ "class" => "Order", "method" => "info", "param" => [ "code" => "C4649" ], ], ]; $ch = curl_init(); $options = [ CURLOPT_URL => "http://10.211.55.4:9509/", CURLOPT_POST => 1, CURLOPT_POSTFIELDS => json_encode($demo), ]; curl_setopt_array($ch, $options); curl_exec($ch); curl_close($ch);擴(kuò)展官方協(xié)程 MySQL 客戶端手冊(cè):
https://wiki.swoole.com/wiki/...
大家可以嘗試使用官方提供的其他方法。
小結(jié)Demo 代碼僅供參考,里面有很多不嚴(yán)謹(jǐn)?shù)牡胤健?/p>
根據(jù)自己的需要進(jìn)行修改,比如業(yè)務(wù)代碼相關(guān)驗(yàn)證,CURD 方法封裝 ...
推薦一個(gè)完善的產(chǎn)品,Swoole 開發(fā)的 MySQL 數(shù)據(jù)庫連接池(SMProxy):
https://github.com/louislivi/...
上面的 Demo 需要源碼的,加我微信。(菜單-> 加我微信-> 掃我)
推薦閱讀系統(tǒng)的講解 - SSO 單點(diǎn)登錄
系統(tǒng)的講解 - PHP WEB 安全防御
系統(tǒng)的講解 - PHP 緩存技術(shù)
系統(tǒng)的講解 - PHP 接口簽名驗(yàn)證
系統(tǒng)的講解 - PHP 浮點(diǎn)數(shù)高精度運(yùn)算
本文歡迎轉(zhuǎn)發(fā),轉(zhuǎn)發(fā)請(qǐng)注明作者和出處,謝謝!
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/31577.html
摘要:基于擴(kuò)展實(shí)現(xiàn)真正的數(shù)據(jù)庫連接池這種方案中,項(xiàng)目占用的連接數(shù)僅僅為。一種是連接暫時(shí)不再使用,其占用狀態(tài)解除,可以從使用者手中交回到空閑隊(duì)列中這種我們稱為連接的歸隊(duì)。源碼剖析系列目錄 作者:bromine鏈接:https://www.jianshu.com/p/1a7...來源:簡書著作權(quán)歸作者所有,本文已獲得作者授權(quán)轉(zhuǎn)載,并對(duì)原文進(jìn)行了重新的排版。Swoft Github: https:...
摘要:一個(gè)基于協(xié)議,開發(fā)的數(shù)據(jù)庫連接池。也可以通過其自身的管理機(jī)制來監(jiān)視數(shù)據(jù)庫連接的數(shù)量使用情況等。超出最大連接數(shù)會(huì)采用協(xié)程掛起,等到有連接關(guān)閉再恢復(fù)協(xié)程繼續(xù)操作。 SMProxy GITHUB:https://github.com/louislivi/... Swoole MySQL Proxy 一個(gè)基于 MySQL 協(xié)議,Swoole 開發(fā)的MySQL數(shù)據(jù)庫連接池。 原理 將數(shù)據(jù)庫連接作...
閱讀 3339·2022-01-04 14:20
閱讀 3109·2021-09-22 15:08
閱讀 2188·2021-09-03 10:44
閱讀 2316·2019-08-30 15:44
閱讀 1491·2019-08-29 18:40
閱讀 2655·2019-08-29 17:09
閱讀 2989·2019-08-26 13:53
閱讀 3222·2019-08-26 13:37