简介
Hypervel 是一个类似 Laravel 风格的 PHP 框架,具备原生协程支持,拥有超高性能。
Hypervel 移植了 Laravel 的许多核心组件,同时保留了熟悉的使用模式,使得 Laravel 开发者可以快速上手。这个框架将 Laravel 优雅、富有表现力的开发体验,与基于协程编程所带来的强大性能优势相结合。如果你是 Laravel 开发者,使用这个框架会感觉非常自然,几乎不需要额外学习。
Hypervel 非常适合用于构建微服务、API 网关以及高并发应用 —— 这些正是传统 PHP 框架常常面临性能瓶颈的场景。
为什么选择 Hypervel?
虽然 Laravel Octane 在提升 Laravel 应用性能方面表现出色,但我们仍然需要理解现代 Web 应用的本质。在多数情况下,延迟主要来自 I/O 操作,比如文件读写、数据库查询和 API 请求。
然而,Laravel 本身并不支持协程 —— 整个框架是为阻塞式 I/O 环境设计的。那些严重依赖 I/O 操作的应用仍然会遇到性能瓶颈。举个例子:
假设你正在构建一个由 AI 驱动的聊天机器人,每次对话的 API 响应时间为 3 到 5 秒。如果使用 Laravel Octane,并配置了 10 个 worker 来处理 10 个并发请求,那么所有的 worker 都会在请求完成之前被阻塞。
对于 I/O 密集型场景,即使使用 Laravel Octane,应用的并发处理能力仍然受到 I/O 操作时长的限制。Hypervel 通过协程来解决这个问题,能高效处理并发 I/O 操作而不阻塞 worker。这种方式可以显著提升那些对 I/O 依赖较重的应用的性能和并发能力。
此外,Laravel Octane 在近期支持协程的可能性也不大(参见 这个 issue),因为目前只有 Swoole 运行时支持这一特性,并且还要考虑与现有框架和第三方包的兼容性。
重要说明
即使 Laravel Octane 支持了协程,这些协程也仅限于单个请求内部 —— 所有 I/O 操作完成前,worker 仍然会被阻塞。这意味着在这类场景中,你的 Laravel 应用依然无法获得更好的 QPS 表现。
更多信息可参考 这个 Pull Request。
Laravel Octane
Laravel 以其优雅、富有表现力的语法、强大的组件生态以及活跃的社区而闻名。但由于 PHP-FPM 的传统执行模型,即使对框架进行各种优化,Laravel 的性能依然有限。
在 LaraCon 2021 上,Taylor Otwell 宣布推出 Laravel Octane —— 这是由 Laravel 官方团队维护的第一个性能增强包。Octane 通过让你的代码运行在长驻进程中(如 Swoole、RoadRunner 或 FrankenPHP)显著提升 Laravel 应用的性能。
了解更多请参见 Laravel Octane。
Hyperf
Hypervel 构建于 Hyperf 生态之上,类似于 Laravel 与 Symfony 的关系。Hyperf 是一个基于 Swoole 和 Swow 驱动的高性能框架,所有组件都原生支持协程,并严格遵循 PSR 标准。它让开发者可以轻松构建高并发应用,且内置非阻塞 I/O 支持。
Hyperf 项目在 GitHub 上非常活跃,功能更新和版本发布频繁,显示出强大的社区活力和持续发展能力。自 2019 年以来,Hyperf 在 GitHub 上已获得超过 6000 颗星,有 350 多位贡献者,是那些希望使用异步 I/O 构建高性能 PHP 项目的开发者的首选框架之一。
更多信息请访问 Hyperf 官网。
基准测试
基准测试包含两个不同场景,用于评估框架在不同条件下的性能:
简单 API 测试:
- 提供一个基本的 hello world API 接口
- 无中间件
- 测试原始响应速度
模拟 I/O 等待测试:
- 使用 sleep 模拟 1 秒 I/O 延迟
- 延迟后返回 hello world
- 测试 I/O 密集型场景下的性能
worker 数量默认为 CPU 核心数
测试环境说明:
- 硬件:Apple M1 Pro 2021
- CPU:8 核心
- 内存:16 GB
简单 API 测试
- Laravel Octane(8 个 worker)
10 秒测试 @ http://127.0.0.1:8000/api
4 线程 100 连接
平均延迟:15.93ms,标准差:16.86ms,最大值:155.82ms,87.02% 在标准范围内
每秒请求数:2.07k,最大 3.10k
总请求数:82661,耗时 10.04 秒,读取数据:16.95MB
每秒请求数:8230.97
每秒传输:1.69MB
- Hypervel(8 个 worker)
10 秒测试 @ http://127.0.0.1:9501/api
4 线程 100 连接
平均延迟:7.66ms,标准差:17.85ms,最大值:249.92ms,90.25% 在标准范围内
每秒请求数:24.42k,最大 54.37k
总请求数:971692,耗时 10.06 秒,读取数据:151.98MB
每秒请求数:96562.80
每秒传输:15.10MB
模拟 I/O 等待测试
- Laravel Octane(8 个 worker)
10 秒测试 @ http://127.0.0.1:8000/api
4 线程 100 连接
平均延迟:1.03s,标准差:184.92 微秒,最大值:1.03s,87.50% 在标准范围内
每秒请求数:1.52,最大 5.00
总请求数:80,耗时 10.10 秒,读取数据:16.80KB
Socket 错误:连接 0,读取 0,写入 0,超时 72
每秒请求数:7.92
每秒传输:1.66KB
- Hypervel(8 个 worker)
10 秒测试 @ http://10.10.4.12:9501/api
16 线程 15000 连接
平均延迟:1.02s,标准差:64.72ms,最大值:1.87s,93.62% 在标准范围内
每秒请求数:1.16k,最大 9.15k
总请求数:109401,耗时 10.09 秒,读取数据:19.82MB
每秒请求数:10842.71
每秒传输:1.96MB
这次测试我在另一台机器上运行 wrk,确保它能使用更多资源来维持更高连接数。
Laravel Octane 的 QPS 接近 8,但由于和 Hypervel 相差太大,所以在图表中表现得非常低。