基于 PHP Fiber 和 Workerman 实现的高性能异步 IO 扩展包,提供类似 Python asyncio 的 API 和功能。
v2.0.3 新特性: Workerman 性能全面优化!自动选择最优事件循环(10-100x性能提升)、多进程模式、完整生产工具!详见 更新日志
- 🚀 基于 PHP Fiber - 原生协程支持,性能卓越
- ⚡ 完全事件驱动 - 零轮询,充分利用 Workerman 高性能
- 🎯 并发控制 - gather, wait_for, 任务管理
- ⏰ 精确定时 - < 0.1ms 延迟,Timer 事件驱动
- 🛡️ 异常处理 - 完整的错误传播和处理
- 📦 简洁API - 类似 Python asyncio 的使用体验
- 🚀 Event Loop Auto-Selection - 自动选择最优事件循环(Ev/Event/Select) (v2.0.3)
- 🔄 Multi-Process Mode - 多进程模式,充分利用多核 CPU (v2.0.3)
- 🚦 Semaphore - 信号量并发控制 (v2.0.3)
- 💊 HealthCheck - 应用健康检查 (v2.0.3)
- 🛑 GracefulShutdown - 优雅关闭处理 (v2.0.3)
- 📏 ResourceLimits - 资源限制管理 (v2.0.3)
- 📊 AsyncIO Monitor - 实时监控任务、内存、性能指标
- 🐛 AsyncIO Debugger - 追踪 Fiber 调用链,可视化调用栈
- 🌐 AsyncIO HTTP Client - 完整的异步 HTTP 客户端(支持 SSL、重定向等)
- 🔧 Performance Monitor - 任务计时、慢任务追踪、Prometheus 导出 (v2.0.2)
- 🔗 Connection Pool - HTTP 连接池管理和统计 (v2.0.2)
- 🧹 Auto Fiber Cleanup - 自动清理已终止的 Fiber,防止内存泄漏 (v2.0.2)
composer require pfinalclub/asyncio- PHP >= 8.1 (需要 Fiber 支持)
- Workerman >= 4.1
AsyncIO 自动选择最优事件循环,性能差异可达 10-100 倍!
| 事件循环 | 并发能力 | 性能 | 安装方法 |
|---|---|---|---|
| Select | < 1K | 基准 (1x) | 默认内置 |
| Event (libevent) | > 10K | 3-5x | pecl install event |
| Ev (libev) | > 100K | 10-20x | pecl install ev ⭐推荐 |
测试场景: 100个并发任务
┌──────────┬─────────┬──────────┬───────────┐
│ 事件循环 │ 耗时(s) │ 吞吐量 │ 相对性能 │
├──────────┼─────────┼──────────┼───────────┤
│ Select │ 1.25 │ 80/s │ 1x │
│ Event │ 0.31 │ 322/s │ 4x ⚡ │
│ Ev │ 0.12 │ 833/s │ 10.4x 🚀 │
└──────────┴─────────┴──────────┴───────────┘
# macOS
brew install libev
pecl install ev
# Ubuntu/Debian
sudo apt-get install libev-dev
pecl install ev
# CentOS/RHEL
sudo yum install libev-devel
pecl install ev运行时会自动检测并提示:
⚠️ 使用 Select 事件循环 - 基础性能 (<1K 并发)
💡 提示: 安装 ev 或 event 扩展可提升性能 10-100 倍
充分利用多核 CPU,性能提升 8倍(8核CPU)!
use function PfinalClub\Asyncio\Production\run_multiprocess;
run_multiprocess(function() {
// 你的异步代码
}, [
'worker_count' => 8, // 8个进程
'name' => 'AsyncIO',
]);性能对比:
- 单进程: 1000 QPS
- 8进程: 8000 QPS (8倍提升)
更多详情见 生产环境部署
<?php
require_once __DIR__ . '/vendor/autoload.php';
use function PfinalClub\Asyncio\{run, sleep};
// 定义一个异步函数
function hello_world(): mixed
{
echo "Hello\n";
sleep(1); // 异步睡眠 1 秒
echo "World\n";
return "Done!";
}
// 运行主函数
$result = run(hello_world(...));
echo "Result: {$result}\n";<?php
use function PfinalClub\Asyncio\{run, create_task, gather, sleep};
function task1(): string
{
echo "Task 1 开始\n";
sleep(2);
echo "Task 1 完成\n";
return "结果 1";
}
function task2(): string
{
echo "Task 2 开始\n";
sleep(1);
echo "Task 2 完成\n";
return "结果 2";
}
function main(): array
{
// 创建任务
$t1 = create_task(task1(...));
$t2 = create_task(task2(...));
// 并发等待所有任务完成
$results = gather($t1, $t2);
return $results; // ['结果 1', '结果 2']
}
run(main(...));<?php
use function PfinalClub\Asyncio\{run, wait_for, sleep};
use PfinalClub\Asyncio\TimeoutException;
function slow_task(): string
{
sleep(5);
return "完成";
}
function main(): void
{
try {
// 最多等待 2 秒
$result = wait_for(slow_task(...), 2.0);
echo "结果: {$result}\n";
} catch (TimeoutException $e) {
echo "任务超时: {$e->getMessage()}\n";
}
}
run(main(...));<?php
use function PfinalClub\Asyncio\{run, create_task, await, sleep};
function background_task(string $name): string
{
for ($i = 1; $i <= 5; $i++) {
echo "{$name}: 步骤 {$i}\n";
sleep(0.5);
}
return "{$name} 完成";
}
function main(): void
{
// 创建多个后台任务
$task1 = create_task(fn() => background_task("任务A"));
$task2 = create_task(fn() => background_task("任务B"));
// 等待一段时间
sleep(2);
// 检查任务状态
echo "任务1 完成: " . ($task1->isDone() ? "是" : "否") . "\n";
echo "任务2 完成: " . ($task2->isDone() ? "是" : "否") . "\n";
// 等待任务完成
$result1 = await($task1);
$result2 = await($task2);
echo "{$result1}, {$result2}\n";
}
run(main(...));查看 examples 目录获取完整示例:
| 示例 | 说明 |
|---|---|
| 01_hello_world.php | Hello World 入门 |
| 02_concurrent_tasks.php | 并发任务执行 |
| 03_timeout_cancel.php | 超时和取消 |
| 04_http_client.php | HTTP 客户端 |
| 05_error_handling.php | 错误处理 |
| 06_real_world_crawler.php | 网页爬虫 |
| 07_monitor_performance.php | 性能监控 |
| 08_async_queue.php | 异步队列 |
运行主函数直到完成并返回结果。这是程序的主入口点。
$result = run(my_function(...));创建并调度一个任务,立即开始执行。
$task = create_task(my_function(...), 'my-task');create_task 的别名,更符合异步编程习惯。
$task = async(my_function(...));异步睡眠指定的秒数。必须在 Fiber 上下文中调用。
sleep(1.5); // 睡眠 1.5 秒等待任务完成并返回结果。
$result = await($task);并发运行多个任务并等待它们全部完成。
$results = gather($task1, $task2, $task3);等待任务完成,如果超时则抛出 TimeoutException。
try {
$result = wait_for(my_task(...), 5.0);
} catch (TimeoutException $e) {
echo "超时!\n";
}获取当前事件循环实例。
$loop = get_event_loop();检查任务是否已完成。
获取任务结果(如果任务未完成会抛出异常)。
取消任务。
添加任务完成时的回调。
Future 表示一个未来的结果,可以手动设置。
$future = create_future();
// 在某处设置结果
$future->setResult("结果");
// 等待结果
$result = await_future($future);use function PfinalClub\Asyncio\{run, create_task, gather};
use PfinalClub\Asyncio\Http\AsyncHttpClient;
function main(): void
{
$client = new AsyncHttpClient(['timeout' => 10]);
// 单个请求
$response = $client->get('https://api.example.com/users');
echo "Status: {$response->getStatusCode()}\n";
echo "Body: {$response->getBody()}\n";
// 并发请求
$task1 = create_task(fn() => $client->get('https://api.example.com/users/1'));
$task2 = create_task(fn() => $client->get('https://api.example.com/users/2'));
$task3 = create_task(fn() => $client->get('https://api.example.com/users/3'));
$responses = gather($task1, $task2, $task3);
foreach ($responses as $response) {
echo "Status: {$response->getStatusCode()}\n";
}
}
run(main(...));use function PfinalClub\Asyncio\{run, create_task, gather};
use PfinalClub\Asyncio\Monitor\AsyncioMonitor;
function main(): void
{
$monitor = AsyncioMonitor::getInstance();
// 创建任务
$tasks = [
create_task(fn() => my_task1()),
create_task(fn() => my_task2()),
];
gather(...$tasks);
// 显示监控报告
echo $monitor->report();
// 导出 JSON
echo $monitor->toJson();
}
run(main(...));use function PfinalClub\Asyncio\run;
use PfinalClub\Asyncio\Debug\AsyncioDebugger;
function main(): void
{
$debugger = AsyncioDebugger::getInstance();
$debugger->enable();
// 你的代码...
// 显示调用链
echo $debugger->visualizeCallChain();
// 显示报告
echo $debugger->report();
}
run(main(...));| v1.x (Generator) | v2.0 (Fiber) |
|---|---|
function f(): \Generator |
function f(): mixed |
yield sleep(1) |
sleep(1) |
yield $task |
await($task) |
yield gather(...) |
gather(...) |
run(generator()) |
run(callable) |
旧代码 (v1.x):
function task(): \Generator {
yield sleep(1);
$result = yield other_task();
return $result;
}
run(main());新代码 (v2.0):
function task(): mixed {
sleep(1);
$result = await(other_task_as_task());
return $result;
}
run(main(...));- ✅ 性能提升 2-3 倍 - 原生 Fiber 比 Generator 快
- ✅ 代码更简洁 - 不需要到处 yield
- ✅ 更好的堆栈 - 完整的错误追踪
- ✅ 真正的协程 - 不是 Generator 模拟
创建 1000 个任务: ~2-3ms (v1.x: ~6ms)
5000 并发任务: ~20-25ms (v1.x: ~47ms)
性能提升: 2-3倍
- PHP 版本要求: 必须 PHP >= 8.1(需要 Fiber 支持)
- Fiber 上下文:
sleep(),await()等函数必须在 Fiber 中调用 - 破坏性变更: v2.0 与 v1.x 不兼容,需要重写代码
MIT License
欢迎提交 Issue 和 Pull Request!
核心优化:
- ✨ 自动选择最优事件循环 - Ev > Event > Select,性能提升 10-100 倍
- ✨ 多进程模式 - 充分利用多核 CPU,性能提升 8 倍(8核)
- ✨ 生产工具包 - HealthCheck, GracefulShutdown, ResourceLimits
- ✨ 并发控制 - Semaphore 信号量,限制并发任务数
性能提升:
事件循环性能(100 并发任务):
- Select: 80 tasks/s (基准)
- Event: 322 tasks/s (4x)
- Ev: 833 tasks/s (10.4x) 🚀
多进程模式(8核 CPU):
- 单进程: 1000 QPS
- 8进程: 8000 QPS (8x) ⚡
新增 API:
// 事件循环优化(自动)
use PfinalClub\Asyncio\EventLoop;
$type = EventLoop::getEventLoopType(); // 'Ev', 'Event', 或 'Select'
// 多进程模式
use function PfinalClub\Asyncio\Production\run_multiprocess;
run_multiprocess($callback, ['worker_count' => 8]);
// 并发控制
use function PfinalClub\Asyncio\semaphore;
$sem = semaphore(5); // 最多 5 个并发
$sem->acquire();
// ... 执行任务
$sem->release();
// 生产工具
use function PfinalClub\Asyncio\Production\{health_check, graceful_shutdown, resource_limits};
health_check()->check();
graceful_shutdown(30)->register();
resource_limits(['max_memory_mb' => 512])->enforce();破坏性变更:
- HTTP 连接复用实现调整(由于 Workerman 限制,转为软连接池 + Keep-Alive 头)
新功能:
- ✨ Fiber 自动清理 - 每 100 个 Fiber 或 run() 结束时自动清理,防止内存泄漏
- ✨ HTTP 连接池 - 完整的连接池实现,支持连接统计和健康检查
- ✨ 性能监控系统 - 任务计时、慢任务追踪、Prometheus/JSON 导出
性能提升:
- 长时间运行稳定性提升 - 不再有内存泄漏
- HTTP 连接管理优化 - 连接统计和自动清理
- 生产可观测性提升 - 完整的性能指标和慢任务追踪
新增 API:
// 性能监控
use function PfinalClub\Asyncio\Monitor\{export_metrics, get_performance_snapshot, set_slow_task_threshold};
// 导出 JSON 格式指标
$json = export_metrics('json');
// 导出 Prometheus 格式指标
$prometheus = export_metrics('prometheus');
// 获取完整性能快照
$snapshot = get_performance_snapshot();
// 设置慢任务阈值(默认 1.0 秒)
set_slow_task_threshold(2.0);兼容性:
- ✅ 完全向后兼容 v2.0.1
- ✅ 无需修改代码
性能优化:
- ⚡ 完全事件驱动 - 移除所有轮询机制
- ⚡ 零延迟恢复 - await/gather 直接恢复 Fiber
- ⚡ 精确定时 - sleep() 直接使用 Timer
- ⚡ CPU 效率 - 空闲时 CPU 使用率 < 1%
性能提升:
- sleep() 精度: 10x (±0.1ms vs ±1ms)
- await() 延迟: 10-20x (<0.1ms vs 1-2ms)
- HTTP 吞吐: 1.5x (120 vs 80 req/s)
- 整体性能: 1.5-2x
兼容性:
- ✅ 完全向后兼容 v2.0.0
- ✅ 无需修改代码
详见 性能优化文档
重大变更:
- 完全基于 PHP Fiber 重写
- 移除所有 Generator 代码
- 性能提升 2-3 倍
- API 变更(不兼容 v1.x)
新特性:
- 原生 Fiber 支持
- 更简洁的 API
- 更好的性能
- 完整的错误堆栈
迁移: 请参考迁移指南从 v1.x 升级到 v2.0
版本: 2.0.2
更新日期: 2025-01-20
PHP 要求: >= 8.1