Hyperf 核心概念
1. Hyperf 简介
1.1 什么是 Hyperf?
Hyperf 是一个高性能、高灵活性的协程框架,基于 Swoole 协程构建,专为云原生、微服务架构而设计。
核心特点:
- 🚀 高性能:基于 Swoole 协程,QPS 可达数万
- 🔄 全协程化:从框架底层到应用层全面协程化
- 🏗️ 微服务:内置服务注册、发现、治理能力
- 🎯 依赖注入:强大的 DI 容器和注解支持
- 📦 组件化:提供 70+ 官方组件
- ☁️ 云原生:支持容器化部署、配置中心、服务网格
1.2 应用场景
适用场景:
- ✅ 高并发 API 服务
- ✅ 微服务架构
- ✅ WebSocket 实时通信
- ✅ 消息队列消费者
- ✅ 定时任务系统
- ✅ RPC 服务
不适用场景:
- ❌ 简单的内容管理系统(CMS)
- ❌ 低并发的企业官网
- ❌ 需要共享主机的项目
- ❌ 团队对协程不熟悉的场景
1.3 性能对比
压测场景:简单 JSON API 返回
并发:100 连接
持续时间:30 秒
Laravel (PHP-FPM): QPS: 500-800
ThinkPHP (PHP-FPM): QPS: 600-900
Hyperf (Swoole): QPS: 15,000-30,000
2. 核心概念
2.1 常驻内存
传统 PHP-FPM 模式:
请求 → 启动 PHP → 加载框架 → 执行业务 → 返回结果 → 销毁进程
↑
每次都要重新加载
Hyperf (Swoole) 模式:
启动时:启动 → 加载框架 → 常驻内存
运行时:请求 → 执行业务 → 返回结果 → 继续等待请求
↑
框架已在内存中,无需重复加载
优势:
- 减少框架加载时间
- 减少文件 IO 操作
- 可以使用连接池(数据库、Redis 等)
- 可以在内存中缓存数据
注意事项:
- 修改代码后需要重启服务(或使用热重载)
- 需要注意内存泄漏问题
- 全局变量会常驻内存
2.2 协程
什么是协程?
协程是一种用户态的轻量级线程,由程序自己控制调度,而非操作系统。
协程 vs 线程 vs 进程:
| 特性 | 进程 | 线程 | 协程 |
|---|---|---|---|
| 调度者 | 操作系统 | 操作系统 | 用户程序 |
| 切换开销 | 大(MB级) | 中(KB级) | 小(字节级) |
| 并发量 | 低(几十个) | 中(几百个) | 高(几万个) |
| 资源占用 | 高 | 中 | 低 |
协程示例:
<?php
use Swoole\Coroutine;
// 启动 3 个协程
Coroutine\run(function () {
// 协程 1
Coroutine::create(function () {
echo "协程1开始\n";
Coroutine::sleep(1); // 模拟 IO 等待,挂起当前协程
echo "协程1结束\n";
});
// 协程 2
Coroutine::create(function () {
echo "协程2开始\n";
Coroutine::sleep(0.5);
echo "协程2结束\n";
});
// 协程 3
Coroutine::create(function () {
echo "协程3开始\n";
echo "协程3结束\n";
});
});
// 输出顺序:
// 协程1开始
// 协程2开始
// 协程3开始
// 协程3结束
// 协程2结束 (0.5秒后)
// 协程1结束 (1秒后)
协程调度原理:
时间线:
0ms: [协程1启动] → sleep(1000ms) → 挂起
[协程2启动] → sleep(500ms) → 挂起
[协程3启动] → 立即执行 → 完成
500ms: [协程2唤醒] → 继续执行 → 完成
1000ms: [协程1唤醒] → 继续执行 → 完成
2.3 依赖注入(DI)
什么是依赖注入?
依赖注入是一种设计模式,将类所依赖的对象从外部传入,而不是在类内部创建。
传统方式:
<?php
class UserService
{
private $db;
public function __construct()
{
// 在类内部创建依赖
$this->db = new Database();
}
}
依赖注入方式:
<?php
class UserService
{
private $db;
// 从外部注入依赖
public function __construct(Database $db)
{
$this->db = $db;
}
}
Hyperf 中的依赖注入:
<?php
namespace App\Controller;
use App\Service\UserService;
use Hyperf\Di\Annotation\Inject;
class IndexController
{
#[Inject]
private UserService $userService;
public function index()
{
// 直接使用,无需手动创建
return $this->userService->getUserList();
}
}
优势:
- 降低耦合度
- 便于单元测试
- 便于替换实现
- 自动管理对象生命周期
2.4 注解(Annotation)
Hyperf 大量使用 **PHP 8 属性(Attributes)**进行配置。
常用注解:
<?php
namespace App\Controller;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\GetMapping;
use Hyperf\HttpServer\Annotation\PostMapping;
use Hyperf\Di\Annotation\Inject;
#[Controller(prefix: '/api/user')]
class UserController
{
#[Inject]
private UserService $userService;
#[GetMapping(path: 'list')]
public function list()
{
return $this->userService->getUserList();
}
#[PostMapping(path: 'create')]
public function create()
{
// ...
}
}
2.5 AOP(面向切面编程)
AOP 允许在不修改原有代码的情况下,对方法进行增强。
示例:记录方法执行时间
<?php
namespace App\Aspect;
use Hyperf\Di\Annotation\Aspect;
use Hyperf\Di\Aop\AbstractAspect;
use Hyperf\Di\Aop\ProceedingJoinPoint;
#[Aspect]
class TimeAspect extends AbstractAspect
{
// 要切入的类
public array $classes = [
UserService::class,
];
public function process(ProceedingJoinPoint $proceedingJoinPoint)
{
$start = microtime(true);
// 执行原方法
$result = $proceedingJoinPoint->process();
$time = microtime(true) - $start;
echo "执行时间:{$time}秒\n";
return $result;
}
}
3. Hyperf vs 传统框架
3.1 生命周期对比
传统框架(Laravel/ThinkPHP):
每次请求:
1. Nginx 接收请求
2. 转发给 PHP-FPM
3. 启动 PHP 进程
4. 加载框架文件
5. 加载配置文件
6. 连接数据库
7. 执行业务逻辑
8. 返回响应
9. 销毁进程
下次请求:重复上述所有步骤
Hyperf:
启动时(一次):
1. 启动 Swoole Server
2. 加载框架和配置
3. 初始化连接池
4. 扫描注解,构建容器
请求处理(每次):
1. Swoole 接收请求
2. 从连接池获取数据库连接
3. 执行业务逻辑
4. 返回响应
5. 归还连接到连接池
下次请求:只执行请求处理步骤
3.2 并发模型对比
传统框架(同步阻塞):
// 查询用户信息
$user = Db::table('users')->find(1); // 阻塞 10ms
// 查询订单信息
$order = Db::table('orders')->where('user_id', 1)->get(); // 阻塞 20ms
// 总耗时:10ms + 20ms = 30ms
Hyperf(协程异步):
use Hyperf\Utils\Coroutine;
// 并发查询
[$user, $order] = Coroutine::parallel([
fn() => Db::table('users')->find(1), // 10ms
fn() => Db::table('orders')->where('user_id', 1)->get(), // 20ms
]);
// 总耗时:max(10ms, 20ms) = 20ms
3.3 代码对比
路由定义:
// Laravel
Route::get('/user/{id}', [UserController::class, 'show']);
// Hyperf
#[GetMapping(path: 'user/{id}')]
public function show(int $id) { }
数据库查询:
// Laravel
$users = DB::table('users')->where('status', 1)->get();
// Hyperf(几乎一样)
$users = Db::table('users')->where('status', 1)->get();
缓存使用:
// Laravel
Cache::put('key', 'value', 3600);
$value = Cache::get('key');
// Hyperf
use Hyperf\Cache\Annotation\Cacheable;
#[Cacheable(prefix: 'user', ttl: 3600)]
public function getUserById(int $id)
{
return Db::table('users')->find($id);
}
4. 学习建议
4.1 前置知识
建议先掌握:
- ✅ PHP 基础(面向对象、命名空间、Trait)
- ✅ Composer 依赖管理
- ✅ PSR 规范(PSR-4、PSR-7、PSR-11)
- ✅ 至少一个传统 PHP 框架(Laravel/ThinkPHP)
可以边学边掌握:
- 📚 Swoole 基础
- 📚 协程概念
- 📚 依赖注入原理
4.2 学习路径
第一步:快速入门
1. 创建项目
2. 编写简单的 HTTP 接口
3. 连接数据库
4. 使用缓存
第二步:深入理解
1. 协程调度原理
2. 依赖注入容器
3. AOP 切面编程
4. 注解系统
第三步:进阶应用
1. 微服务架构
2. 服务注册与发现
3. RPC 调用
4. 配置中心
第四步:性能优化
1. 连接池优化
2. 缓存策略
3. 异步队列
4. 性能监控
4.3 常见问题
Q1:Hyperf 比 Laravel 难学吗?
A:Hyperf 的 API 设计与 Laravel 很相似,如果你熟悉 Laravel,上手 Hyperf 会很快。主要的学习曲线在于理解协程和 Swoole 的特性。
Q2:必须精通 Swoole 才能用 Hyperf 吗?
A:不需要。Hyperf 封装了 Swoole 的细节,你可以像使用传统框架一样使用 Hyperf。但了解 Swoole 的基础概念(协程、事件循环)会帮助你更好地理解和优化代码。
Q3:Hyperf 适合小项目吗?
A:如果项目并发量不高(QPS < 1000),使用传统框架会更简单。Hyperf 的优势在于高并发场景。
Q4:协程会带来什么问题?
A:主要注意事项:
- 不能使用传统的阻塞函数(sleep、file_get_contents 等)
- 需要使用协程安全的客户端(Redis、MySQL 等)
- 注意协程上下文的传递
5. 要点
5.1 必须掌握
- Hyperf 的核心特性(协程、DI、AOP)
- 与传统框架的区别
- 协程的基本概念和优势
- 常驻内存带来的影响
- 适用场景和不适用场景
5.2 加分项
- 有实际项目经验
- 了解 Swoole 的事件循环
- 能说出性能优化案例
- 了解微服务相关概念
5.3 高频题
-
Hyperf 和 Laravel 有什么区别?
- 运行方式:Swoole 常驻内存 vs PHP-FPM
- 并发模型:协程 vs 同步阻塞
- 性能:高性能 vs 普通性能
- 适用场景:微服务、高并发 vs 通用 Web 应用
-
什么是协程?
- 用户态的轻量级线程
- 由程序控制调度,而非操作系统
- 遇到 IO 操作时自动挂起,IO 完成时恢复
- 单个进程可以运行数万个协程
-
Hyperf 如何实现高性能?
- Swoole 常驻内存,减少框架加载时间
- 协程实现异步 IO,提高并发能力
- 连接池复用,减少连接开销
- 事件驱动,高效处理并发请求
下一步:阅读 02-协程与Swoole.md 深入理解协程原理