摘要:于是打算做一個(gè)擁有非常好用的路由和又非常簡(jiǎn)單的框架。但也有一些自己的特色,例如支持自動(dòng)化緩存自動(dòng)化讀寫刷新保持與數(shù)據(jù)庫同步,對(duì)外使用無感知。例如協(xié)議服務(wù)器地址遠(yuǎn)程的類不設(shè)置默認(rèn)為當(dāng)前類名其中類在框架里。
背景
在用過laravel框架,發(fā)現(xiàn)它的路由和數(shù)據(jù)庫ORM確實(shí)非常好用,但是整體確實(shí)有點(diǎn)慢,執(zhí)行到控制器大于需要耗時(shí)60ms左右。于是打算做一個(gè)擁有非常好用的路由和orm又非常簡(jiǎn)單的框架。所以你會(huì)發(fā)現(xiàn)one框的路由和ORM有l(wèi)aravel的影子。但也有一些自己的特色,例如ORM支持自動(dòng)化緩存(自動(dòng)化讀、寫、刷新)保持與數(shù)據(jù)庫同步,對(duì)外使用無感知。one框架也支持在fpm下運(yùn)行,在fpm下框架自身整體耗時(shí)在1ms左右。
hello world安裝
composer create-project lizhichao/one-app app cd app php App/swoole.php
測(cè)試
curl http://127.0.0.1:8081/主要功能
RESTful路由
中間件
websocket/tcp/http……任意協(xié)議路由
ORM模型
統(tǒng)一的session處理
mysql連接池
redis連接池
tcp連接池
HTTP/TCP/WEBOSCKET/UDP服務(wù)器
緩存
進(jìn)程間內(nèi)存共享
RPC(http,tcp,udp)
日志
RequestId跟蹤
路由Router::get("/", AppControllersIndexController::class . "@index"); // 帶參數(shù)路由 Router::get("/user/{id}", AppControllersIndexController::class . "@user"); // 路由分組 Router::group(["namespace"=>"AppTestWebSocket"],function (){ // websocket 路由 Router::set("ws","/a","TestController@abc"); Router::set("ws","/b","TestController@bbb"); }); // 中間件 Router::group([ "middle" => [ AppTestMixProTestMiddle::class . "@checkSession" ] ], function () { Router::get("/mix/ws", HttpController::class . "@ws"); Router::get("/mix/http", HttpController::class . "@http"); Router::post("/mix/http/loop", HttpController::class . "@httpLoop"); Router::post("/mix/http/send", HttpController::class . "@httpSend"); });orm 模型 定義模型
namespace AppModel; use OneDatabaseMysqlModel; // 模型里面不需要指定主鍵,框架會(huì)緩存數(shù)據(jù)庫結(jié)構(gòu) // 自動(dòng)匹配主鍵,自動(dòng)過濾非表結(jié)構(gòu)里的字段 class User extends Model { // 定義模型對(duì)應(yīng)的表名 CONST TABLE = "users"; // 定義關(guān)系 public function articles() { return $this->hasMany("id",Article::class,"user_id"); } // 定義事件 // 是否開啟自動(dòng)化緩存 // …… }使用模型
在fpm下數(shù)據(jù)庫連接為單列,
在swoole模式下數(shù)據(jù)庫連接自動(dòng)切換為連接池
// 查詢一條記錄 $user = User::find(1); // 關(guān)聯(lián)查詢 $user_list = User::whereIn("id",[1,2,3])->with("articles")->findAll()->toArray(); // 更新 $r = $user->update(["name" => "aaa"]); // 或者 $r = user::where("id",1)->update(["name" => "aaa"]); // $r 為影響記錄數(shù)量緩存
// 設(shè)置緩存 Cache::set("ccc",1); // 獲取 Cache::get("ccc"); // 或者 緩存ccc 過期10s 在tag1下面 Cache::get("ccc",function (){ return "緩存的信息"; },10,["tag1"]); // 刷新tag1下的所有緩存 Cache::flush("tag1");HTTP/TCP/WEBOSCKET/UDP服務(wù)器
啟動(dòng)一個(gè)websocket服務(wù)器,
添加http服務(wù)監(jiān)聽,
添加tcp服務(wù)監(jiān)聽
[ // 主服務(wù)器 "server" => [ "server_type" => OneSwooleOneServer::SWOOLE_WEBSOCKET_SERVER, "port" => 8082, // 事件回調(diào) "action" => OneSwooleServerWsServer::class, "mode" => SWOOLE_PROCESS, "sock_type" => SWOOLE_SOCK_TCP, "ip" => "0.0.0.0", // swoole 服務(wù)器設(shè)置參數(shù) "set" => [ "worker_num" => 5 ] ], // 添加監(jiān)聽 "add_listener" => [ [ "port" => 8081, // 事件回調(diào) "action" => AppServerAppHttpPort::class, "type" => SWOOLE_SOCK_TCP, "ip" => "0.0.0.0", // 給監(jiān)聽設(shè)置參數(shù) "set" => [ "open_http_protocol" => true, "open_websocket_protocol" => false ] ], [ "port" => 8083, // 打包 解包協(xié)議 "pack_protocol" => OneProtocolText::class, // 事件回調(diào) "action" => AppTestMixProTcpPort::class, "type" => SWOOLE_SOCK_TCP, "ip" => "0.0.0.0", // 給監(jiān)聽設(shè)置參數(shù) "set" => [ "open_http_protocol" => false, "open_websocket_protocol" => false ] ] ] ];RPC
像調(diào)用本項(xiàng)目的方法一樣調(diào)用遠(yuǎn)程服務(wù)器的方法??缯Z言,跨機(jī)器。
服務(wù)端啟動(dòng)rpc服務(wù),框架已經(jīng)內(nèi)置了各個(gè)協(xié)議的rpc服務(wù),添加到到上面配置文件的action即可。列如: 支持http調(diào)用,又支持tpc調(diào)用。
// http 協(xié)議 rpc服務(wù) [ "port" => 8082, "action" => AppServerRpcHttpPort::class, "type" => SWOOLE_SOCK_TCP, "ip" => "0.0.0.0", "set" => [ "open_http_protocol" => true, "open_websocket_protocol" => false ] ], // tpc 協(xié)議 rpc服務(wù) [ "port" => 8083, "action" => AppServerRpcTcpPort::class, "type" => SWOOLE_SOCK_TCP, "pack_protocol" => OneProtocolFrame::class, // tcp 打包 解包協(xié)議 "ip" => "0.0.0.0", "set" => [ "open_http_protocol" => false, "open_websocket_protocol" => false, "open_length_check" => 1, "package_length_func" => "OneProtocolFrame::length", "package_body_offset" => OneProtocolFrame::HEAD_LEN, ] ]
添加具體服務(wù)到rpc,
例如有個(gè)類Abc
class Abc { private $a; // 初始值 public function __construct($a = 0) { $this->a = $a; } // 加法 public function add($a, $b) { return $this->a + $a + $b; } public function time() { return date("Y-m-d H:i:s"); } // 重新設(shè)初始值 public function setA($a) { $this->a = $a; return $this; } }
把Abc添加到rpc服務(wù)
// 添加Abc到rpc服務(wù) RpcServer::add(Abc::class); // 如果你不希望把Abc下的所有方法都添加到rpc服務(wù),也可以指定添加。 // 未指定的方法客戶端無法調(diào)用. //RpcServer::add(Abc::class,"add"); // 分組添加 //RpcServer::group([ // // 中間件 在這里可以做 權(quán)限驗(yàn)證 數(shù)據(jù)加解密 等等 // "middle" => [ // TestMiddle::class . "@aa" // ], // // 緩存 如果設(shè)置了 當(dāng)以同樣的參數(shù)調(diào)用時(shí) 會(huì)返回緩存信息 不會(huì)真正調(diào)用 單位:秒 // "cache" => 10 //], function () { // RpcServer::add(Abc::class); // RpcServer::add(User::class); //});客戶端調(diào)用
為了方便調(diào)用我們建立一個(gè)映射類(one框架可自動(dòng)生成)
class ClientAbc extends RpcClientHttp { // rpc服務(wù)器地址 protected $_rpc_server = "http://127.0.0.1:8082/"; // 遠(yuǎn)程的類 不設(shè)置 默認(rèn)為當(dāng)前類名 protected $_remote_class_name = "Abc"; }
調(diào)用rpc服務(wù)的遠(yuǎn)程方法, 和調(diào)用本項(xiàng)目的方法一樣的。你可以想象這個(gè)方法就在你的項(xiàng)目里面。
$abc = new ClientAbc(5); // $res === 10 $res = $abc->add(2,3); // 鏈?zhǔn)秸{(diào)用 $res === 105 $res = $abc->setA(100)->add(2,3); // 如果把上面的模型的User添加到rpc // RpcServer::add(User::class); // 下面運(yùn)行結(jié)果和上面一樣 // $user_list = User::whereIn("id",[1,2,3])->with("articles")->findAll()->toArray();
上面是通過http協(xié)議調(diào)用的。你也可以通過其他協(xié)議調(diào)用。例如Tpc協(xié)議
class ClientAbc extends RpcClientTcp { // rpc服務(wù)器地址 protected $_rpc_server = "tcp://127.0.0.1:8083/"; // 遠(yuǎn)程的類 不設(shè)置 默認(rèn)為當(dāng)前類名 protected $_remote_class_name = "Abc"; }
其中類 RpcClientHttp,RpcClientTcp在框架里。
你也可以復(fù)制到任何其他地方使用。
github
QQ交流群: 731475644
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/29824.html
摘要:框架最新源代碼行數(shù)行,因此可以很容易的改造它,成為你們公司的專屬框架。也不同于其他基于的微服務(wù)框架,只聚焦于微服務(wù)治理,定位于開發(fā)的更多領(lǐng)域,覆蓋從初創(chuàng)到億元級(jí)體量的技術(shù)訴求。的授權(quán)全靠用戶自愿購買,詳情 MixPHP是什么 MixPHP 是秉承 普及 PHP 常駐內(nèi)存型解決方案,促進(jìn) PHP 往更后端發(fā)展 的理念而創(chuàng)造,采用 Swoole 擴(kuò)展作為底層引擎,圍繞常駐內(nèi)存的方式而設(shè)計(jì),...
摘要:年月日,在上海舉行的第六屆中國開發(fā)者大會(huì)上,騰訊開源項(xiàng)目首次全面發(fā)布版本,閱文集團(tuán)高級(jí)開發(fā)工程師梁晨對(duì)如何通過構(gòu)建高性能框架做了經(jīng)驗(yàn)分享。分享內(nèi)容作為騰訊開源的框架,在發(fā)布之后即受到開源領(lǐng)域的關(guān)注。閱文集團(tuán)本身也有一塊新的業(yè)務(wù)在使用。 2018年5月19日,在上海舉行的第六屆中國PHP開發(fā)者大會(huì)(PHPCon)上,騰訊開源項(xiàng)目TARS首次全面發(fā)布PHP版本,閱文集團(tuán)高級(jí)開發(fā)工程師梁晨對(duì)...
摘要:介紹是基于開發(fā)的協(xié)程開發(fā)框架,擁有常駐內(nèi)存協(xié)程異步非阻塞等優(yōu)點(diǎn)。宇潤我在年開發(fā)并發(fā)布了第一個(gè)框架,一直維護(hù)使用至今,非常穩(wěn)定,并且有文檔。于是我走上了開發(fā)的不歸路 showImg(https://segmentfault.com/img/bVbcxQH?w=340&h=160); 介紹 IMI 是基于 Swoole 開發(fā)的協(xié)程 PHP 開發(fā)框架,擁有常駐內(nèi)存、協(xié)程異步非阻塞IO等優(yōu)點(diǎn)。...
摘要:是一個(gè)基于擴(kuò)展實(shí)現(xiàn)的輕量級(jí)高性能的常駐內(nèi)存型的和應(yīng)用服務(wù)框架高度封裝了,,服務(wù)器,以及基于實(shí)現(xiàn)可擴(kuò)展的服務(wù),同時(shí)支持包方式安裝部署項(xiàng)目?;趯?shí)用,抽象事件處理類,實(shí)現(xiàn)與底層的回調(diào)的解耦,支持同步異步調(diào)用,內(nèi)置等常用組件等。 swoolefy swoolefy是一個(gè)基于swoole擴(kuò)展實(shí)現(xiàn)的輕量級(jí)高性能的常駐內(nèi)存型的API和Web應(yīng)用服務(wù)框架,高度封裝了http,websocket,ud...
摘要:易用穩(wěn)定,本次想通過對(duì)的學(xué)習(xí)和個(gè)人解析,吸收框架的思想和設(shè)計(jì)知識(shí),加強(qiáng)自己對(duì)的認(rèn)知和理解。當(dāng)然,筆者能力水平有限,后續(xù)的文章如有錯(cuò)誤,還請(qǐng)指出和諒解。目錄如下后續(xù)添加文章都會(huì)記錄在此服務(wù)啟動(dòng)過程以及主體設(shè)計(jì)流程源碼解析 前言 swoole是什么?官網(wǎng)的原話介紹是這樣的: Swoole 使用純 C 語言編寫,提供了 PHP 語言的異步多線程服務(wù)器,異步 TCP/UDP 網(wǎng)絡(luò)客戶端,異步 ...
閱讀 1074·2021-11-12 10:34
閱讀 999·2021-09-30 09:56
閱讀 675·2019-08-30 15:54
閱讀 2610·2019-08-30 11:14
閱讀 1476·2019-08-29 16:44
閱讀 3215·2019-08-29 16:35
閱讀 2500·2019-08-29 16:22
閱讀 2452·2019-08-29 15:39