當前位置:
首頁 > 知識 > Swoft-基於swoole2.0的高性能微服務框架

Swoft-基於swoole2.0的高性能微服務框架

簡介

swoft是基於swoole協程2.x的高性能PHP微服務框架,內置http伺服器。框架全協程實現,性能優於傳統的php-fpm模式。

基於swoole易擴展

內置http協程伺服器

MVC分層設計

高性能路由

全局容器注入

高性能RPC

別名機制

事件機制

國際化(i18n)

服務治理熔斷、降級、負載、註冊與發現

連接池Mysql、Redis、RPC

資料庫ORM

inotify自動reload

強大的日誌系統

Future

連接池等待隊列

restful風格

crontab定時任務

服務監控

日誌統計分析

統一配置中心

更新記錄

......

2017-08-15 重構console命令行

2017-08-24 重寫IOC容器,新增控制器路由註解註冊,不再依賴php-di。使用時,重新composer安裝

2017-08-28 inotify自動reload

2017-09-02 別名機制、事件機制、國際化(i18n),命名空間統一大寫。

2017-09-19 資料庫ORM

系統架構

快速入門

文檔

中文文檔

環境要求

hiredis

composer

PHP7.X

inotify(可選)

Swoole2.x且開啟協程和非同步redis

安裝

手動安裝

clone項目

composer install安裝依賴

composer安裝

composer.phar create-project stelin/swoft swoft(未開代理,會有點慢)

配置

配置base.php

設置啟動參數swoft.ini

啟動

啟動服務支持HTTP和TCP同時啟動,swoft.ini中配置。

常用命令

//啟動服務,是否是守護進程,根據swoft.ini配置

phpswoft.phpstart

//守護進程啟動,覆蓋swoft.ini守護進程配置

phpswoft.phpstart-d

//重啟

phpswoft.phprestart

//重新載入

phpswoft.phpreload

//關閉服務

phpswoft.phpstop

Swoft.ini參數

[swoft]

;;;;;;;;;;;;;;;;;;;;About swoft.ini;;;;;;;;;;;;;;;;;;;;

[server]pfile = /tmp/swoft.pid ;

pname ="php-swf";

[tcp]

enable= 1;

host ="0.0.0.0"

port = 8099

type= SWOOLE_SOCK_TCP[http]host ="0.0.0.0"port = 80model = SWOOLE_PROCESStype= SWOOLE_SOCK_TCP[setting]worker_num = 4max_request = 10000daemonize = 0;dispatch_mode = 2log_file = SWOOLE_LOG_PATH

路由器

路由解析有兩種方式,註冊路由和自動解析,所有路由都在routes.php中配置。建議所有路由都提前註冊,或者通過註解註冊,不建議使用自動路由解析。路由配置參數(base.php):

return[//...

router =>[

class =>swoftwebRouter::class,

ignoreLastSep =>false,

//是否忽略最後一個斜杠,設置false後,/user/index和/user/index/是兩個不同的路由

tmpCacheNumber =>1000,//緩存路由數,最近一1000條

matchAll => ,//匹配所有,所有請求都會匹配到這個uri或閉包],

//...

];

路由註冊實例

//匹配 GET 請求. 處理器是個閉包 Closure

$router->get( / ,function() {

$resposne=App::getResponse();

$resposne->setResponseContent("hello");

$resposne->send();});//匹配參數 test/john

$router->get( /test/ ,function($arg) {

echo$arg;// john },

[ tokens =>[

name => w+ ,//添加參數匹配限制。若不添加對應的限制,將會自動設置為匹配除了 / 外的任何字元

]]);//可選參數支持。匹配 hello hello/john

$router->get( /hello[/] ,function($name= No ) {

echo$name;// john }, [

tokens =>[

name => w+ ,//添加參數匹配限制

]]);//匹配 POST 請求

$router->post( /user/login ,function() {

$request=App::getRequest();

var_dump($request->getGetParameters(),$request->getPostParameters());});

//匹配 GET 或者 POST

$router->map([ get , post ], /user/login ,function() {

$request=App::getRequest();

var_dump($request->getGetParameters(),$request->getPostParameters());});

//允許任何請求方法

$router->any( /home ,function() {

$resposne=RequestContext::getResponse();

$resposne->setResponseContent("hello, you request page is /home");

$resposne->send();});

$router->any( /404 ,function() {

$resposne=App::getResponse();

$resposne->setResponseContent("Sorry,This page not found.");

$resposne->send();});//路由組

$router->group( /user ,function($router) {

$router->get( / ,function() {

$resposne=App::getResponse();

$resposne->setResponseContent("hello. you access: /user/");

$resposne->send();});

$router->get( /index ,function() {

$resposne=App::getResponse();

$resposne->setResponseContent("hello. you access: /user/index");

$resposne->send();});});

//通過@符號連接控制器類和方法名可以指定執行方法

$router->get( / ,appcontrollersHome::class);

$router->get( /index , appcontrollersHome@index );

$router->get( /about , appcontrollersHome@about );

//訪問 /home/test 將會執行 appcontrollersHome::test()

$router->any( /home/ ,appcontrollersHome::class);

//可匹配 /home , /home/test 等

$router->any( /home[/] ,appcontrollersHome::class);

//配置 matchAll 可用於攔截所有請求,目前有如下兩種方式。//路由path

matchAll => /about ,//回調 matchAll =>function() {

$resposne=App::getResponse();

$resposne->setResponseContent("System Maintaining ... ...");

$resposne->send();},

控制器

一個繼承swoftwebController的類既是控制器,控制器有兩種註解自動註冊和手動註冊兩種方式。建議使用註解自動註冊,方便簡潔,維護簡單。多次註冊相同的路由前者會被後者覆蓋。

註解自動註冊

註解自動註冊常用到三個註解@AutoController、@Inject、@RequestMapping.

@AutoController

已經使用@AutoController,不能再使用@Bean註解。

@AutoController註解不需要指定bean名稱,統一類為bean名稱

@AutoController()默認自動解析controller前綴,並且使用駝峰格式。

@AutoController(prefix="/demo2")或@AutoController("/demo2")功能一樣,兩種使用方式。

@Inject

使用和之前的一樣

@RequestMapping

@RequestMapping(route="/index2")或@RequestMapping("/index2")功能一樣兩種方式使用,這種默認是支持get和post方式@RequestMapping(route="/index2", method=RequestMethod::GET)註冊支持的方法

不使用@RequestMapping或RequestMapping()功能一樣,都是默認解析action方法,以駝峰格式,註冊路由。

/*** 控制器demo** @AutoController(prefix="/demo2")**@usesDemoController*@version2017年08月22日*@authorstelin

*@copyrightCopyright 2010-2016 swoft software*@licensePHP Version 7.x {@linkhttp://www.php.net/license/3_0.txt}*/classDemoControllerextendsController{/*** 注入邏輯層** @Inject()*@varIndexLogic*/private$logic;/*** 定義一個route,支持get和post方式,處理uri=/demo2/index** @RequestMapping(route="index", method=)*/publicfunctionactionIndex(){//獲取所有GET參數$get=$this->get();//獲取name參數默認值defaultName$name=$this->get( name , defaultName );//獲取所有POST參數$post=$this->post();//獲取name參數默認值defaultName$name=$this->post( name , defaultName );//獲取所有參,包括GET或POST$request=$this->request();//獲取name參數默認值defaultName$name=$this->request( name , defaultName );//json方式顯示數據$this->outputJson("suc");}/*** 定義一個route,支持get,以"/"開頭的定義,直接是根路徑,處理uri=/index2** @RequestMapping(route="/index2", method=RequestMethod::GET)*/publicfunctionactionIndex2(){//重定向一個URI$this->redirect("/login/index");}/*** 沒有使用註解,自動解析注入,默認支持get和post,處理uri=/demo2/index3*/publicfunctionactionIndex3(){$this->outputJson("suc3");}}

手動註冊

手動註冊常用@Bean、@Inject註解,手動註冊還要多一步就是在routes.php裡面註冊自己的路由規則。

手動註冊@Bean()只能這樣預設方式。並且不能使用@AutoController註解

/*** 控制器demo** @Bean()**@usesDemoController*@version2017年08月22日*@authorstelin

*@copyrightCopyright 2010-2016 swoft software*@licensePHP Version 7.x {@linkhttp://www.php.net/license/3_0.txt}*/classDemoControllerextendsController{/*** 注入邏輯層** @Inject()*@varIndexLogic*/private$logic;/*** uri=/demo2/index*/publicfunctionactionIndex(){//獲取所有GET參數$get=$this->get();//獲取name參數默認值defaultName$name=$this->get( name , defaultName );//獲取所有POST參數$post=$this->post();//獲取name參數默認值defaultName$name=$this->post( name , defaultName );//獲取所有參,包括GET或POST$request=$this->request();//獲取name參數默認值defaultName$name=$this->request( name , defaultName );//json方式顯示數據$this->outputJson("suc");}/*** uri=/index2*/publicfunctionactionIndex2(){//重定向一個URI//$this->redirect("/login/index");$this->outputJson("suc2");}/***/publicfunctionactionIndex3(){$this->outputJson("suc3");}}

routes.php手動註冊路由:

//...$router->map([ get , post ], /demo2/index , appcontrollersDemoController@index );$router->get( /index2 , appcontrollersDemoController@index2 );$router->get( /demo2/index3 , appcontrollersDemoController@index3 );

連接池

連接池使用簡單,只需在base.php裡面配置對應服務連接池即可。

return[//...//RCP打包、解包"packer"=>[ class =>JsonPacker::class],//服務發現bean, 目前系統支持consul,只行實現"consulProvider =>[ class =>swoftserviceConsulProvider::class],//user服務連接池"userPool"=>["class"=>swoftpoolServicePool::class,"uri"=> 127.0.0.1:8099,127.0.0.1:8099 ,//useProvider為false時,從這裡識別配置"maxIdel"=>6,//最大空閑連接數"maxActive"=>10,//最大活躍連接數"maxWait"=>20,//最大的等待連接數"timeout"=> $ ,//引用properties.php配置值"balancer"=> $ ,//連接創建負載"serviceName"=> user ,//服務名稱,對應連接池的名稱格式必須為xxxPool/xxxBreaker"useProvider"=>false, serviceprovider => $ //useProvider為true使用,用於發現服務],//user服務熔斷器"userBreaker"=>[ class =>swoftcircuitCircuitBreaker::class, delaySwithTimer =>8000],//...];

緩存

緩存目前只支持redis,redis使用有兩種方式直接調用和延遲收包調用。

//直接調用RedisClient::set( name , redis client stelin ,180);$name=RedisClient::get( name );RedisClient::get($name);//延遲收包調用$ret=RedisClient::deferCall( get , [ name ]);$ret2=RedisClient::deferCall( get , [ name ]);$result=$ret->getResult();$result2=$ret2->getResult();$data=[ redis =>$name, defer =>$result, defer2 =>$result2,];

RPC調用

RPC及內部服務通過監聽TCP埠實現,通過swoft.ini日誌配置TCP監聽埠信息。RPC調用內部實現連接池、熔斷器、服務註冊與發現等。

//直接調用$result=Service::call("user", User::getUserInfo , [2,6,8]);//並發調用$res=Service::deferCall("user", User::getUserInfo , [3,6,9]);$res2=Service::deferCall("user", User::getUserInfo , [3,6,9]);$users=$res->getResult();$users2=$res2->getResult();$deferRet=$users;$deferRet2=$users2;

HttpClient

系統提供HttpClient來實現HTTP調用,目前有兩種方式,直接調用和延遲收包調用,延遲收包,一般用於並發調用。

//直接調用$requestData=[ name => boy , desc => php ];$result=HttpClient::call("http://127.0.0.1/index/post?a=b",HttpClient::GET,$requestData);$result=$result;//延遲調用方式實現兩個請求並發調用$ret=HttpClient::deferCall("http://127.0.0.1/index/post",HttpClient::POST,$requestData);$ret2=HttpClient::deferCall("http://127.0.0.1/index/post",HttpClient::POST,$requestData);$defRet1=$ret->getResult();$defRet2=$ret->getResult();

日誌

日誌記錄一般用戶問題的問的分析,系統的定位。目前日誌規劃有debug trace error info warning notice等級別。每種不同的級別用戶記錄不同重要程度的信息。系統會為每一個請求生成一條notice,並且一個請求產生的所有日誌都有一個相同的logid,notice裡面記錄該請求的詳細信息,比如uri 總共耗時 緩存或db操作時間等等信息。

//標記開始App::profileStart("tag");//直接輸出異常App::error(newException("error exception"));App::error("this errro log");App::info("this errro log");//數組App::error([ name => boy ]);App::debug("this errro log");//標記結束App::profileEnd("tag");//統計緩存命中率App::counting("cache",1,10);


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 PHP技術大全 的精彩文章:

一個MySQL 5.7分區表性能下降的案例分析
代碼質量管控的四個階段
利用sed批量更改文件名
PHP與大數據開發實踐

TAG:PHP技術大全 |