前引
hyperf 我所熟悉的是基于swoole驱动的模式(协程)。
hyperf 完全取代了php-fpm,即是nginx转发请求不再转发给php-fpm ,而是转发给hyperf启动的进程处理。(甚至于hyperf 也可越过nginx 直接处理用户请求,但一般我们会在前面加一个代理(nginx)来转接请求)
hyperf的优点
- 协程的支持:基于swoole的请求协程化,一个请求对应一个协程。但因协程是用户线程(用户创建的线程,所以这个线程的声明周期及何时发生上下文切换均由我们自己管理)。所以无法使用多核cpu的特性(意为在一个含有协程的进程中同时运行多个协程)。如果要使用多核cpu的特性,就需要使用多进程模型(多个进程监听同一个端口,采用惊群现象处理请求,每个cpu负责一个含有协程的进程)
- 微服务化:便捷简单微服务化支持,我仅了解json-http rpc协议,grpc太复杂暂不了解。且有完善的分布式事务支持(go 语言编写的DTM 事务协调器,使用这个协调器对接hyperf实现稳定的分布式事务)
- 运行速度极快:因采用协程,所以运行速度快(但要注意阻塞问题,同一时刻只有一个协程在跑,如这个协程在运行时产生的阻塞是否会使cpu产生等待问题需要考虑。(比如与mysql建立连接是否会使cpu堵塞在这个协程上))
- 与其他框架(laravel)在结构上、组件功能上无较大差异:路由、验证器、中间件、ORM、队列、请求、响应、控制器、命令、测试、异常处理等。(可快速上手)
- 新增守护进程支持,一次启动,即可长时工作在任务后台(如队列监听守护进程,也可创建一个proccess 对象,自定义这个守护进程的逻辑)
- mysql连接池,redis连接池 快捷实现(主要用户解决程序运行需要和mysql建立连接锁产生的阻塞问题,mysql连接数问题)
hyperf的缺点
- 瞬时流量爆发(如秒杀、红包等场景)
a、 此场景下会在进程中产生大量的协程,每个协程都需要建立mysql连接时会导致mysql连接数耗尽而导致mysql抛出连接数异常
b、每个协程在创建成功后会被分配多少内存,当数量过多后是否会挤爆进程(受操作系统和配置的影响),导致无法对外提供服务
c、当采用数据库连接池解决连接数问题后,mysql数据库的iops指标是否能满足需求。(单位时间内的读写能力是否能支撑这么高的迸发)
d、当采用队列消息时,如果队列过长,且因意外原因,导致了服务器重启,如何恢复队列任务的执行(redis方案不可取,redis一旦重启,内存数据就没了,虽然可以采用数据持久化,但一般来说很少用redis来存储数据。查阅官方文档并无mysql数据库队列消息的实现,估计只有自己去封装一个包来实现mysql队列任务了)
还有其它很多需要考虑的问题点,本次就暂时整理这些。
写下这篇文章并不是反馈hyperf不好,反之,hyperf 很好。他实现了php 微服务化,且针对微服务也做了负载,nacos等的支持。他让php在框架选型的范围上有了更多的支持。
但是学习和使用hyperf框架需要较强的技术知识
关联技术知识
- Linux操作系统基本命令的熟悉
- lnmp环境搭建(开发环境一般采用宝塔来搭建)
- windows上搭建linux虚拟机(我采用hyper-v Windows扩展工具搭建,但要cpu支持虚拟化,如不支持需要进入dos命令界面开启cpu虚拟化)如Ubuntu
- phpstorm 搭载ftp协议与虚拟机ubuntu进行文件(达到本地修改直接自动同步至虚拟机ubuntu指定目录)
- 进程方面的知识:进程的状态,进程的调度,cpu在线程和进程上发生上下文切换时所做的工作
- nginx代理
- nginx的工作模式(master-work),hyperf swoole 驱动的工作模式
- 多线程编程知识:主要考虑同一进程中,线程之间共享内存(程序运行可能产生的内存溢出,脏数据的产生等问题)