前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >化繁为简,从零开始的PHP分布式框架设计

化繁为简,从零开始的PHP分布式框架设计

作者头像
用户1246234
发布2020-01-22 09:34:02
1.7K0
发布2020-01-22 09:34:02
举报
文章被收录于专栏:Swoole开源项目

前言

经历了一个又一个项目,也接触了很多的PHP框架,我欣赏CI的简约,又贪婪swoole的效率,我将CI和swoole很草率的结合到了一起。起初呢风平浪静,慢慢的就遇到了不少的瓶颈,毕竟CI的设计理念还是贴合FPM模式,如何更加得心应手的使用swoole,同时追求开发上和运行时的效率呢,最主要的还是要方便扩展,就萌生了SwooleDistributed这个开源框架的想法。

在SwooleDistributed发布之前,开源社区还没有过针对swoole的分布式框架,起初的目的并不是一个完整的应用框架,而是一个简单的分布式通讯框架,后来需求变多了,框架也就慢慢的丰满了。

分布式

分布式这东西并不是有多神秘,但一个框架在基础构思中就包含分布式的思想,那无疑方便对以后的扩展。分布式系统涉及到多太物理机之间的调控,配置起来也是较为麻烦,SwooleDistributed使用了内网发现的技术手段,自动发现集群环境的物理机进行连接,简化了配置,甚至达到了无配置。

SwooleDistributed在前期可以控制成本的使用单机模式进行部署,也可以在后期进行水平扩展,对逻辑代码无需任何的改动。

你所需要的就是多增加物理机,跑上服务器就行啦。

MVCT

解决了底层的分布式通讯问题,接下来就是MVC结构的搭建了,这部分借鉴了CI的设计,使用Loader模块加载对应的Model,通过路由访问对应的Controller。相信使用过CI框架的工程师很容易就上手。 此外引入了Swoole独特的Task,将swoole的Task进行了封装优化,更加易于使用。

代码语言:javascript
复制
//TestTask.php
class TestTask extends Task
{
   public function test()
   {
       print_r("test timer task\n");
   }
}
//TestController.php
class TestController extends Controller
{
 public function http_test_task()
   {
       $task = $this->loader->task('TestTask');
       $task->test();
       $result = yield $task->coroutineSend();
       $this->http_output->end($result);
   }
}

通过定时器和Task的结合,开发者可以很方便的制作定时任务,而这一切只需要简单的配置即可。

代码语言:javascript
复制
/**
* timerTask定时任务
* (必填)task名称 task_name
* (必填)执行task的方法 method_name
* (选填)执行区间 [start_time,end_time) 格式: Y-m-d H:i:s 没有代表一直执行
* (必填)执行间隔 interval_time 单位: 秒
* (选填)最大执行次数 max_exec,默认不限次数
*/
$config['timerTask'][] = [
   'task_name'=>'TestTask',
   'method_name'=>'test',
   'start_time'=>'Y-m-d 00:00:00',
   'end_time'=>'Y-m-d 23:59:59',
   'interval_time'=>'2',
];

异步连接池

swoole提供了redis和mysql的异步客户端,大大提高的服务端的效率,但问题又来了,如果使用异步客户端,就必须维护一个异步连接池。 SwooleDistributed设计了一个通用的连接池模块,通过这个模块可以快捷简单的创建客户端的连接池,不仅如此redis和mysql的连接池早已封装在核心代码中,开发者只需调用其中的Api无需关注连接池的维护。 swoole的异步redis客户端是基于hredis和我们通常使用的redis扩展不一样,在使用批量方法时回调的值是有所区别,SwooleDistributed屏蔽了这一点不同之处,使用起来和平常的redis扩展一致。 异步的mysql客户端事务通常是比较难写的,SwooleDistributed同样针对mysql事务进行了封装,使用起来也非常的方便。 此外mysql也提供了一个语法构建器,可以简单方便的构建mysql语法。

代码语言:javascript
复制
 public function test_coroutine()
   {
       $mySqlCoroutine = $this->mysql_pool->dbQueryBuilder->select('*')->from('account')->where('uid', 10303)->coroutineSend();
       $result = yield $mySqlCoroutine;
       $redisCoroutine = $this->redis_pool->coroutineSend('get', 'test');
       $result = yield $redisCoroutine;
       return $result;
   }

协程

之前我去过很多家公司,交流的过程中发现有些公司使用php做短连接,用golang做长连接,我问他们为何不用swoole呢?回答都是异步回调太难写了。 确实异步回调写起来很不好看,可能会有多层回调的嵌套,复杂点的代码非常的难看,swoole2.0已经使用了协程,但首先是新功能稳定性尚且不知,其次不支持php7,于是我呢就对现有框架进行了一次大的调整,通过yield关键字实现了全异步的协程风格。使用起来非常的简单,和一般的写法没有什么太大的区别,只要遵循一个原则,涉及到异步的地方加上yield关键字就可以。

代码语言:javascript
复制
    /**
    * 协程测试
    */
   public function http_testCoroutine()
   {
       $this->testModel = $this->loader->model('TestModel', $this);
       $result = yield $this->testModel->test_coroutine();
       $this->http_output->end($result);
   }

协程之间支持嵌套,也支持throw Exception异常捕获,总之用起来和同步的写法基本一致。 协程之间不存在堵塞,也可以通过控制yield的位置调整send和rev的调度策略。 比如:

代码语言:javascript
复制
$mySqlCoroutine = $this->mysql_pool->dbQueryBuilder->select('*')->from('account')->where('uid', 10303)->coroutineSend();
$result = yield $mySqlCoroutine;
$redisCoroutine = $this->redis_pool->coroutineSend('get', 'test');
$result = yield $redisCoroutine;

这段代码调度策略是mysql_send->mysql_rev->redis_send->redis_rev; 我们调整下yield的位置

代码语言:javascript
复制
$mySqlCoroutine = $this->mysql_pool->dbQueryBuilder->select('*')->from('account')->where('uid', 10303)->coroutineSend();
$redisCoroutine = $this->redis_pool->coroutineSend('get', 'test');
$result = yield $mySqlCoroutine;
$result = yield $redisCoroutine;

这段代码调度策略变成了mysql_send->redis_send->mysql_rev->redis_rev;

同时支持TCP和HTTP

这样你就可以开启一个服务同时处理TCP和HTTP请求了,代码复用率就高很多了,同时SwooleDistributed还提供了一些策略,方便隔离http和tcp的路由请求。

Protobuf

提供了一个Protobuf的RPC实例,其实你可以通过框架的Pack和Route模块自由扩展,提供这个例子无非是我自己项目的需要顺便就发出来了,当然你可以自己实现。

其他

很多细小的功能拉,去这看看吧https://www.gitbook.com/book/tmtbe/swooledistributed。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-05-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Swoole开源项目 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 分布式
  • MVCT
  • 异步连接池
  • 协程
  • 同时支持TCP和HTTP
  • Protobuf
  • 其他
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档