本文目录导读:

在 PHP 项目中实现异步处理有多种方式,每种方式都有其适用场景,以下是主要的实现方案:
消息队列(最常用)
RabbitMQ
// 生产者
use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;
$connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
$channel = $connection->channel();
$channel->queue_declare('task_queue', false, true, false, false);
$msg = new AMQPMessage('Hello World!', ['delivery_mode' => 2]);
$channel->basic_publish($msg, '', 'task_queue');
// 消费者
$channel->basic_qos(null, 1, null);
$channel->basic_consume('task_queue', '', false, false, false, false, function($msg) {
echo "Received: ", $msg->body, "\n";
$msg->delivery_info['channel']->basic_ack($msg->delivery_info['delivery_tag']);
});
Redis 列表(轻量级)
// 入队
$redis->rpush('task_queue', json_encode(['task' => 'send_email', 'data' => [...]]));
// 出队处理(守护进程)
while ($task = $redis->blpop('task_queue', 5)) {
$data = json_decode($task[1], true);
// 处理任务
}
进程管理工具
Supervisord
[program:worker] command=php /path/to/worker.php process_name=%(program_name)s_%(process_num)02d numprocs=4 autostart=true autorestart=true user=www-data
Gearman(分布式任务系统)
// 客户端
$client = new GearmanClient();
$client->addServer('127.0.0.1', 4730);
$result = $client->doBackground('send_email', json_encode($data));
// Worker
$worker = new GearmanWorker();
$worker->addServer('127.0.0.1', 4730);
$worker->addFunction('send_email', 'sendEmailHandler');
function sendEmailHandler($job) {
$data = json_decode($job->workload(), true);
// 处理邮件发送
}
异步 HTTP 请求
Guzzle 异步客户端
use GuzzleHttp\Client;
use GuzzleHttp\Promise;
$client = new Client();
$promises = [
'request1' => $client->getAsync('http://api1.example.com'),
'request2' => $client->getAsync('http://api2.example.com'),
];
// 等待所有请求完成
$results = Promise\unwrap($promises);
// 或者只等待第一个完成
$first = Promise\settle($promises)['request1'];
Swoole 协程
use Swoole\Coroutine\Http\Client;
Coroutine\run(function () {
$client = new Client('api.example.com', 80);
$client->get('/endpoint1');
// 继续执行其他代码
echo "完成异步请求\n";
});
任务队列平台
Beanstalkd
use Pheanstalk\Pheanstalk;
$pheanstalk = Pheanstalk::create('127.0.0.1');
// 放入队列
$pheanstalk->useTube('email')->put($jobData);
// 消费任务
$job = $pheanstalk->watch('email')->reserve();
$data = json_decode($job->getData(), true);
// 处理任务
$pheanstalk->delete($job);
扩展库和框架
Laravel Queues
// 创建任务
class SendEmail implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function __construct(private $user) {}
public function handle(EmailService $service)
{
$service->send($this->user);
}
}
// 派发任务
SendEmail::dispatch($user)->onQueue('emails');
// 延迟执行
SendEmail::dispatch($user)->delay(now()->addMinutes(10));
Symfony Messenger
// 消息类
class SendEmailMessage
{
public function __construct(private string $email) {}
}
// 发送消息
$this->messageBus->dispatch(new SendEmailMessage($email));
// 异步处理配置
messenger:
transports:
async:
dsn: '%env(MESSENGER_TRANSPORT_DSN)%'
其他方案
PCNTL(进程控制)
$pid = pcntl_fork();
if ($pid == -1) {
die('无法创建子进程');
} elseif ($pid) {
// 父进程继续执行
echo "父进程继续\n";
} else {
// 子进程处理任务
processTask();
exit(0);
}
Workerman
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
$worker = new Worker('tcp://0.0.0.0:1234');
$worker->onMessage = function(TcpConnection $connection, $data) {
$connection->send('异步处理结果');
};
Worker::runAll();
云服务
- AWS SQS + Lambda
- 阿里云 MNS
- 腾讯云 CMQ
选型建议
| 场景 | 推荐方案 |
|---|---|
| 简单任务队列 | Redis + 后台脚本 |
| 复杂业务系统 | RabbitMQ / Kafka |
| 需要实时性 | Swoole / Workerman |
| 分布式系统 | Gearman / 云服务 |
| 框架生态 | Laravel Queue / Symfony Messenger |
| 轻量级异步请求 | Guzzle 异步 |
注意事项
- 任务幂等性:确保任务重复执行不会产生问题
- 失败重试:实现合理的重试机制
- 超时控制:设置合理的超时时间
- 日志记录:完整记录任务处理情况
- 监控告警:监控队列堆积和消费情况
- 并发控制:根据服务能力调整并发数
选择具体方案时,应综合考虑系统规模、团队技术栈、部署环境等因素。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播