Swoole扩展的6种模式深入详解


Posted in PHP onMarch 04, 2021

前言

并发问题可以理解为两个问题

  • 并发连接数,就是支持同时接受多少客户端TCP连接
  • 并发请求数,每秒能处理多少请求

Swoole底层基于epoll,所以第一个问题在Swoole扩展中实际上不存在任何问题。使用Swoole可以轻松应对10万甚至100万长连接。开发者唯一需要做的就是修改

ulimit -n

将系统最大文件描述符改为 10万或更大。

不同的模型每秒能处理多少请求数,这个是应用层需要考虑的问题。而且不同的场景下有些模式无法使用。真正的难题就是在这里。实际上

工具永远是死的,而人是活的。

再复杂艰难的场景也阻挡不了聪明的工程师。合理利用Swoole提供的各项功能可以巧妙解决各种难题。

第一 Worker同步阻塞

这个模式的使用方法:

  • swoole_server设置为SWOOLE_PROCESS
  • 只使用Worker进程
  • 根据不同的情况设置worker_num的数值
  • 设置dispatch_mode参数为1或3
  • Worker进程内使用同步阻塞的代码编写方式,这里不使用任何异步IO接口

这个模式的瓶颈就在与onRequestonReceive里代码逻辑的处理速度。按照快慢可以分为几种

  1. 外网CURL调用。这个最慢,快的数百毫秒,慢的情况可能需要几十秒
  2. 内网RPC或Http接口,这个取决与这个接口的速度
  3. MySQL复杂查询,一条SQL如果没有索引可能需要几百毫秒,甚至几秒或更长时间。而如果是主键查询或者索引足够有效可能只需要几毫秒
  4. Redis/Memcache,内存数据库局域网而且是长连接,调用一次可能只需要几百微秒也就是0.x毫秒就能返回
  5. 读取磁盘文件,普通机械磁盘未命中PageCache引起磁盘寻道,可能需要几十毫秒。SSD磁盘速度就快多了几毫秒即可完成随机读取。
  6. 内存文件系统或共享内存,读取/tmp或/dev/shm下的共享文件本质上是读取共享内存,仅需几微妙到几十微秒即可完成。如果是直接读共享内存可能更快,纳秒级别。

进程数量

根据上面的IO耗时,设置适当的进程数量即可。

  • IO很慢就设置几百个Worker进程,如操作MySQL、CURL、大量读写磁盘
  • IO很快就可设置少量进程,如操作Redis、内存文件系统、共享内存

投递模式

如果请求是无状态的可以使用dispatch_mode=1或3,轮循投递或者区分忙闲投递。

长连接应用

比如聊天室,网络游戏。连接之间需要交互的应用。 可以使用 MySQL/Redis/文件 存储用户的连接fd,分组信息。要向某个用户发数据可以根据UID查出对应的fd,发送数据即可。发送分组,可以根据分阻ID查询出fd列表,循环发送数据即可。

第二 Worker非阻塞+Task

这种模式是典型的同步+异步,复杂的业务逻辑使用同步阻塞在Task进程中处理,简单要求高并发的逻辑使用异步非阻塞在Worker进程中处理。

使用方法

  • 使用SWOOLE_PROCESS模式
  • dispatch_mode 设置为2(默认就是2,可不做任何设置)
  • worker_num 设置为CPU核数
  • task_worker_num 根据业务逻辑的耗时情况进行设置,如果平均耗时较长,需要设置数百个进程,耗时较短可设置几十个进程

Worker进程

在这个模式中,Worker进程不能有任何同步阻塞的操作,只处理请求响应或数据接收发送,仅进行PHP数组或对象操作或其他计算逻辑。具体参考 模式3 Worker进程全异步。

Task进程

无状态地处理任务,并返回结果。需要注意单个Task的执行时间,避免处理时间太长导致Task排队过多。

第三 Worker全异步

这个模式就是真正的异步非阻塞编程,在代码中只能使用Swoole提供的异步非阻塞IO操作,不得执行任何普通的PHP阻塞IO函数,如curl、mysql、redis、fsockopen、stream、socket、proc_open等。

与模式二 不同的是全异步服务器不使用Task进程,即使是很复杂的业务逻辑也在Worker进程中执行。纯异步编程需要对开发者要求较高。

使用方法

  • dispatch_mode设置为2
  • worker_num 设置为CPU核数

逻辑实现

Worker进程内的PHP代码只能进行下列3种操作:

  • 使用swoole_redis、swoole_mysql、swoole_http_client、swoole_client+async操作
  • 进行PHP数组、对象操作或其他内存计算逻辑
  • 使用swoole_server的send、push、close、response->end等操作

适用场景

  • 长连接服务
  • 对并发能力和吞吐量有较高要求
  • 团队开发者技术水平较高

弊端和解决方案

  • 纯异步需要使用嵌套回调的方式编写代码,与传统的编程模式完全不同,异步是事件驱动式的,代码不是顺序执行的。
  • 异步嵌套回调的方式在程序逻辑复杂后会变得难以维护

可使用 Promise 或 Yield/Generator 简化异步编程。

第四 Base模式+同步阻塞

Base模式是一个简化版本,Base模式下Swoole的运行原理与Node.js完全一致,是单线程的。对TCP客户端的Accept、Send、Recv、Close都是同一个进程内操作的。

与Process同步阻塞模式不同的是BASE模式下Worker进程的调度由操作系统实现。因此可以实现一个Leader-Follower模式的服务器程序。

使用方法

  • 使用SWOOLE_BASE模式
  • worker_num根据逻辑代码的耗时情况设置几百或几十
  • worker进程内使用同步阻塞IO操作

适用场景

  • 适合短连接 & 请求响应式 服务,如Web服务、RPC服务
  • 这种模式不能实现单连接并发,客户端的连接被某个Worker进程Accept之后,只能在此进程内处理请求

第五 Process

Process提供了对进程管理的封装。基于Process可实现:

多进程+进程间通信编程

将其他语言编写的程序包装为子进程,重定向标准输入输出到管道,与该程序进行通信。可实现任意编程语言为我PHP所用。

第六 sendMessage

到此这篇关于Swoole扩展的6种模式深入详解的文章就介绍到这了,更多相关Swoole扩展的5种模式内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

PHP 相关文章推荐
php字符串截取问题
Nov 28 PHP
php strlen mb_strlen计算中英文混排字符串长度
Jul 10 PHP
从康盛产品(discuz)提取出来的模板类
Jun 28 PHP
基于header的一些常用指令详解
Jun 06 PHP
百度地图API应用之获取用户的具体位置
Jun 10 PHP
php判断文件上传类型及过滤不安全数据的方法
Dec 17 PHP
php数组索引与键值操作技巧实例分析
Jun 24 PHP
PHP5.5.15+Apache2.4.10+MySQL5.6.20配置方法分享
May 06 PHP
php中namespace及use用法分析
Dec 06 PHP
PHP实现的文件上传类与用法详解
Jul 05 PHP
php实现微信公众号企业转账功能
Oct 01 PHP
php设计模式之组合模式实例详解【星际争霸游戏案例】
Mar 27 PHP
php中Swoole的热更新实现代码实例
Mar 04 #PHP
PHP安装扩展mcrypt以及相关依赖项深入讲解
Mar 04 #PHP
PHP实现页面静态化深入讲解
Mar 04 #PHP
php实现对短信验证码发送次数的限制实例讲解
Mar 04 #PHP
swoole锁的机制代码实例讲解
Mar 04 #PHP
PHP实现chrome表单请求数据转换为接口使用的json数据
Mar 04 #PHP
windows系统php环境安装swoole具体步骤
Mar 04 #PHP
You might like
基于文本的搜索
2006/10/09 PHP
PHP数据源架构模式之表入口模式实例分析
2020/01/23 PHP
Mootools 1.2教程 Fx.Morph、Fx选项和Fx事件
2009/09/15 Javascript
jQuery 跨域访问问题解决方法
2009/12/02 Javascript
JQuery实现的在新窗口打开链接的方法小结
2010/04/22 Javascript
基于Jquery 解决Ajax请求的页面 浏览器后退前进功能,页面刷新功能实效问题
2010/12/11 Javascript
非常有用的40款jQuery 插件推荐(系列二)
2011/12/25 Javascript
对jQuery的事件绑定的一些思考(补充)
2013/04/20 Javascript
jquery获取颜色在ie和ff下的区别示例介绍
2014/03/28 Javascript
ztree获取当前选中节点子节点id集合的方法
2015/02/12 Javascript
JS Array创建及concat()split()slice()的使用方法
2016/06/03 Javascript
基于vue2的table分页组件实现方法
2017/03/20 Javascript
JavaScript实现的冒泡排序法及统计相邻数交换次数示例
2017/04/26 Javascript
vue.js通过路由实现经典的三栏布局实例代码
2018/07/08 Javascript
JS实现方形抽奖效果
2018/08/27 Javascript
创建echart多个联动的示例代码
2018/11/23 Javascript
js/jquery遍历对象和数组的方法分析【forEach,map与each方法】
2019/02/27 jQuery
如何通过setTimeout理解JS运行机制详解
2019/03/23 Javascript
vue项目前端微信JSAPI与外部H5支付相关实现过程及常见问题
2020/04/14 Javascript
微信小程序学习总结(四)事件与冒泡实例分析
2020/06/04 Javascript
Python获取文件ssdeep值的方法
2014/10/05 Python
使用Python神器对付12306变态验证码
2016/01/05 Python
Python Series从0开始索引的方法
2018/11/06 Python
postman传递当前时间戳实例详解
2019/09/14 Python
Python-Flask:动态创建表的示例详解
2019/11/22 Python
python中如何进行连乘计算
2020/05/28 Python
国外平面设计素材网站:The Hungry JPEG
2017/03/28 全球购物
俄罗斯珠宝市场的领导者之一:Бронницкий ювелир
2019/10/02 全球购物
俄罗斯一家时尚女装商店:Charuel
2019/12/04 全球购物
外贸主管求职简历的自我评价
2013/10/23 职场文书
医科大学生的自我评价
2013/12/04 职场文书
2014年个人债务授权委托书范本
2014/09/22 职场文书
2019自荐信范文集锦!
2019/07/03 职场文书
使用logback实现按自己的需求打印日志到自定义的文件里
2021/08/30 Java/Android
Python实现灰色关联分析与结果可视化的详细代码
2022/03/25 Python
星际争霸:毕姥爷vs解冻01
2022/04/01 星际争霸