.config.php.sw,swoft:基于 Swoole 协程 2.x 的高性能 PHP 微服务框架

20170811141723_922.png

简介

swoft是基于swoole协程2.x的高性能PHP微服务框架,内置http服务器。框架全协程实现,性能优于传统的php-fpm模式。

基于swoole易扩展

内置http协程服务器

MVC分层设计

高性能路由

全局容器注入

高性能RPC

服务治理熔断、降级、负载、注册与发现

RPC服务

连接池Mysql、Redis、RPC

强大的日志系统

Future

连接池等待队列

国际化i18

restful风格

mysql数据库ORM

inotify自动reload

crontab定时任务

服务监控

日志统计分析

统一配置中心

快速入门

文档

环境要求

hiredis

composer

PHP7.X

Swoole2.x且开启协程和异步redis

安装

clone项目

composer install安装依赖

配置base.php

设置启动参数swoft.ini

启动

启动服务支持HTTP和TCP同时启动,swoft.ini中配置。

常用命令

//启动服务

php swoft.php start

// 重启

php swoft.php restart

// 重新加载

php swoft.php reload

// 关闭服务

php swoft.php stop

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 = 80

model = SWOOLE_PROCESS

type = SWOOLE_SOCK_TCP

[setting]

worker_num = 4

max_request = 10000

daemonize = 0;

dispatch_mode = 2

log_file = '../runtime/swoft/swoole.log';

路由器

路由解析有两种方式,注册路由和自动解析,所有路由都在routes.php中配置。路由配置参数(base.php):

return [

// ...

'router' => [

'class' => \swoft\web\Router::class,

'ignoreLastSep' => false, // 是否忽略最后一个斜杠,设置false后,/user/index和/user/index/是两个不同的路由

'tmpCacheNumber' => 1000,// 缓存路由数,最近一1000条

'matchAll' => '', // 匹配所有,所有请求都会匹配到这个uri或闭包

// 自动路由配置

'autoRoute' => true,// 是否开启自动匹配路由,默认是false

'controllerNamespace' => 'app\\controllers', // 命名空间

'controllerSuffix' => 'Controller', // 控制器后缀

],

// ...

];

路由实例

//匹配 GET 请求. 处理器是个闭包 Closure

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

$resposne = App::getResponse();

$resposne->setResponseContent("hello");

$resposne->send();

});

// 匹配参数 'test/john'

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

echo $arg; // 'john'

}, [

'tokens' => [

'name' => '\w+', // 添加参数匹配限制。若不添加对应的限制,将会自动设置为匹配除了'/'外的任何字符

]

]);

// 可选参数支持。匹配 'hello' 'hello/john'

$router->get('/hello[/{name}]', 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('/', app\controllers\Home::class);

$router->get('/index', 'app\controllers\Home@index');

$router->get('/about', 'app\controllers\Home@about');

// 访问 '/home/test' 将会执行 'app\controllers\Home::test()'

$router->any('/home/{any}', app\controllers\Home::class);

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

$router->any('/home[/{name}]', app\controllers\Home::class);

// 配置 matchAll 可用于拦截所有请求,目前有如下两种方式。

//路由path

'matchAll' => '/about',

//回调

'matchAll' => function () {

$resposne = App::getResponse();

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

$resposne->send();

},

控制器

继承\swoft\web\Controller控制器定义controller,@Inject自动注入Logic依赖,Logic中也可以使用@Inject自动注入dao层或其它依赖,注入的依赖默认是单列的。

class IndexController extends Controller

{

/**

* @Inject()

* @var IndexLogic

*/

private $logic;

public function actionDemo()

{

// 获取所有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("data", 'suc');

// 重定向一个URI

$this->redirect("/login/index");

}

}

连接池

连接池使用简单,只需在base.php里面配置对应服务连接池即可。

return [

// ...

// RCP打包、解包

"packer" => [

'class' => JsonPacker::class

],

// 服务发现bean, 目前系统支持consul,只行实现

'consulProvider' => [

'class' => \swoft\service\ConsulProvider::class

],

// user服务连接池

"userPool" => [

"class" => \swoft\pool\ServicePool::class,

"uri" => '127.0.0.1:8099,127.0.0.1:8099', // useProvider为false时,从这里识别配置

"maxIdel" => 6,// 最大空闲连接数

"maxActive" => 10,// 最大活跃连接数

"maxWait" => 20,// 最大的等待连接数

"timeout" => '${config.service.user.timeout}',// 引用properties.php配置值

"balancer" => '${randomBalancer}',// 连接创建负载

"serviceName" => 'user',// 服务名称,对应连接池的名称格式必须为xxxPool/xxxBreaker

"useProvider" => false,

'serviceprovider' => '${consulProvider}' // useProvider为true使用,用于发现服务

],

// user服务熔断器

"userBreaker" => [

'class' => \swoft\circuit\CircuitBreaker::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(new \Exception("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);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值