想象一下这个场景:用户在你的网站上点击「生成文案」按钮,结果页面转圈转了整整30秒才出结果——这不是用户想要的体验。作为后端开发者,我们都知道这种同步调用的体验有多糟糕。今天我就来教你用 Laravel 队列把 AI API 调用变成「后台任务」,用户点击后秒回「任务已提交,正在生成中...」,体验直接起飞。
这篇文章面向零基础的 Laravel 开发者,我会手把手带你从零配置到线上运行。整个过程中我们会使用 HolySheep AI 的 API,因为它支持国内直连、延迟低于 50ms,而且人民币汇率 1:1 无损,是国内开发者的最佳选择。
一、为什么 AI API 调用需要异步队列?
直接调用 AI API 有三个致命问题:
- 超时风险:AI 模型响应时间通常在 2-10 秒,如果你的 PHP 请求超时设置是 30 秒,可能还能应付。但如果并发量上来,服务器很容易扛不住。
- 用户体验差:用户必须盯着转圈等待,不知道要等多久,容易以为页面卡死了直接刷新。
- 资源浪费:一个 PHP 进程被 AI 请求占住 10 秒,这期间它没法处理其他请求,并发能力直接打骨折。
用队列处理的流程是这样的:用户提交请求 → Laravel 把任务扔进队列 → 立即返回「任务ID」给前端 → 后台 worker 慢慢处理 AI 请求 → 前端轮询查询结果。这样一个 PHP 进程可以同时处理成百上千个请求。
二、环境准备与 HolySheep API 配置
2.1 安装 Laravel(已有项目可跳过)
composer create-project laravel/laravel ai-queue-demo
cd ai-queue-demo
php artisan serve
2.2 配置队列驱动
Laravel 支持多种队列驱动,我们用数据库作为演示(生产环境建议用 Redis):
# .env 文件配置
QUEUE_CONNECTION=database
生成队列任务表
php artisan queue:table
php artisan migrate
2.3 配置 HolySheep API Key
先去 注册 HolySheep AI 获取 API Key。注册就送免费额度,支持微信和支付宝充值,汇率是人民币 1:1 无损兑换美元,相比官方 ¥7.3=$1 能节省超过 85% 的成本。
# .env 文件添加
HOLYSHEEP_API_KEY=YOUR_HOLYSHEEP_API_KEY
HOLYSHEEP_BASE_URL=https://api.holysheep.ai/v1
// config/services.php 添加
'holysheep' => [
'api_key' => env('HOLYSHEEP_API_KEY'),
'base_url' => env('HOLYSHEEP_BASE_URL', 'https://api.holysheep.ai/v1'),
],
三、创建 AI 调用的 Job 类
在 Laravel 中,队列任务用 Job 类封装。我们创建一个专门处理 AI 生成的 Job:
php artisan make:job GenerateAIContentJob
<?php
// app/Jobs/GenerateAIContentJob.php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
class GenerateAIContentJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public int $tries = 3;
public int $timeout = 120;
protected string $taskId;
protected string $userPrompt;
protected string $systemPrompt;
public function __construct(string $taskId, string $userPrompt, string $systemPrompt = '')
{
$this->taskId = $taskId;
$this->userPrompt = $userPrompt;
$this->systemPrompt = $systemPrompt ?: '你是一个专业的文案助手';
}
public function handle(): void
{
$apiKey = config('services.holysheep.api_key');
$baseUrl = config('services.holysheep.base_url');
// 构建消息格式
$messages = [];
if ($this->systemPrompt) {
$messages[] = ['role' => 'system', 'content' => $this->systemPrompt];
}
$messages[] = ['role' => 'user', 'content' => $this->userPrompt];
// 调用 HolySheep API
$response = Http::withHeaders([
'Authorization' => 'Bearer ' . $apiKey,
'Content-Type' => 'application/json',
])->timeout(60)->post($baseUrl . '/chat/completions', [
'model' => 'gpt-4.1', // HolySheep 支持的模型
'messages' => $messages,
'max_tokens' => 2000,
]);
if ($response->successful()) {
$result = $response->json();
$content = $result['choices'][0]['message']['content'] ?? '';
// 把结果存入数据库或缓存
cache()->put('ai_result_' . $this->taskId, [
'status' => 'completed',
'content' => $content,
'completed_at' => now()->toIso8601String(),
], now()->addHours(24));
Log::info("AI任务完成: {$this->taskId}");
} else {
throw new \Exception("HolySheep API 调用失败: " . $response->body());
}
}
public function failed(\Throwable $exception): void
{
// 任务失败后的处理
cache()->put('ai_result_' . $this->taskId, [
'status' => 'failed',
'error' => $exception->getMessage(),
], now()->addHours(24));
Log::error("AI任务失败: {$this->taskId}", [
'error' => $exception->getMessage()
]);
}
}
四、控制器:接收请求、派发任务
<?php
// app/Http/Controllers/AIController.php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Jobs\GenerateAIContentJob;
use Illuminate\Support\Str;
class AIController extends Controller
{
public function generate(Request $request)
{
$request->validate([
'prompt' => 'required|string|max:5000',
]);
// 生成唯一任务ID
$taskId = (string) Str::uuid();
// 把任务扔进队列
GenerateAIContentJob::dispatch(
$taskId,
$request->input('prompt'),
$request->input('system_prompt', '')
);
// 立即返回任务ID,前端用它轮询结果
return response()->json([
'code' => 0,
'msg' => '任务已提交',
'data' => [
'task_id' => $taskId,
'status_url' => '/api/ai/status/' . $taskId,
]
]);
}
public function status(Request $request, string $taskId)
{
$result = cache()->get('ai_result_' . $taskId);
if (!$result) {
return response()->json([
'code' => 404,
'msg' => '任务不存在或已过期',
'data' => ['status' => 'not_found']
]);
}
return response()->json([
'code' => 0,
'msg' => 'success',
'data' => $result
]);
}
}
五、启动队列 Worker
派发任务后,还需要启动队列监听器来实际执行任务:
# 启动队列监听(开发环境)
php artisan queue:work
生产环境建议用 Supervisor 守护进程
/etc/supervisor/conf.d/laravel-worker.conf
[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /path/to/artisan queue:work redis --sleep=3 --tries=3 --max-time=3600
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
user=www-data
numprocs=4
redirect_stderr=true
stdout_logfile=/var/log/laravel-worker.log
stopwaitsecs=3600
我自己在部署时遇到过队列监听莫名停止的问题,后来改成 Supervisor 守护 + 自动重启,基本实现了「零维护」。 HolySheep API 的响应速度非常快,平均延迟在 30-50ms 之间,配合队列处理,并发能力至少提升了 10 倍。
六、路由配置
// routes/api.php
use App\Http\Controllers\AIController;
Route::post('/ai/generate', [AIController::class, 'generate']);
Route::get('/ai/status/{taskId}', [AIController::class, 'status']);
七、前端调用示例
<!-- 简单的 HTML + JavaScript 示例 -->
<div id="app">
<textarea v-model="prompt" placeholder="输入你的需求..."></textarea>
<button @click="submit" :disabled="loading">
{{ loading ? '生成中...' : '提交' }}
</button>
<div v-if="result">AI 回复:{{ result }}</div>
</div>
<script>
new Vue({
el: '#app',
data: { prompt: '', loading: false, taskId: null, result: '' },
methods: {
async submit() {
this.loading = true;
// 1. 提交任务
const res = await fetch('/api/ai/generate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ prompt: this.prompt })
});
const data = await res.json();
this.taskId = data.data.task_id;
// 2. 轮询查询结果
this.pollResult();
},
async pollResult() {
const poll = async () => {
const res = await fetch(/api/ai/status/${this.taskId});
const data = await res.json();
if (data.data.status === 'completed') {
this.result = data.data.content;
this.loading = false;
} else if (data.data.status === 'failed') {
alert('生成失败:' + data.data.error);
this.loading = false;
} else {
setTimeout(poll, 1000); // 每秒轮询一次
}
};
poll();
}
}
})
</script>
八、HolySheep API 价格优势说明
在实际生产中,API 调用成本是必须考虑的因素。我对比了主流 AI 平台:
- GPT-4.1:$8.00 / MTok(输出)
- Claude Sonnet 4.5:$15.00 / MTok(输出)
- Gemini 2.5 Flash:$2.50 / MTok(输出)
- DeepSeek V3.2:$0.42 / MTok(输出)
用 HolySheep API 的好处是:人民币 1:1 汇率无损兑换,没有额外的货币转换损失。对于一个月调用量在百万 Token 级别的应用,光汇率差就能节省上千元。而且 HolySheep 支持微信、支付宝直接充值,对于没有国际信用卡的开发者来说太友好了。
常见报错排查
错误一:queue:work 报错 "Connection refused"
原因:队列连接配置错误或 Redis/MySQL 服务未启动。
# 排查步骤
php artisan config:clear
php artisan queue:restart
如果用 Redis,检查 redis 服务
redis-cli ping # 应返回 PONG
.env 中确保配置正确
REDIS_HOST=127.0.0.1
REDIS_PORT=6379
错误二:AI API 返回 401 Unauthorized
原因:API Key 配置错误或已过期。
# 检查 .env 配置
HOLYSHEEP_API_KEY=YOUR_HOLYSHEEP_API_KEY # 不要有空格或引号
在 tinker 中验证配置是否加载
php artisan tinker
>>> config('services.holysheep.api_key')
=> "YOUR_HOLYSHEEP_API_KEY"
错误三:任务一直处于 pending 状态
原因:队列 worker 未启动或配置为 sync 模式。
# 检查 .env 配置
QUEUE_CONNECTION=database # 不能是 sync
确认 worker 正在运行
ps aux | grep queue:work
如果 worker 已运行,查看失败任务
php artisan queue:failed
php artisan queue:retry all
错误四:AI 请求超时 "cURL error 28"
原因:网络连接 HolySheep API 超时,可能是防火墙或 DNS 问题。
# 在服务器上测试连接
curl -v https://api.holysheep.ai/v1/models \
-H "Authorization: Bearer YOUR_HOLYSHEEP_API_KEY"
如果超时,更换 DNS
/etc/resolv.conf
nameserver 8.8.8.8
nameserver 114.114.114.114
总结
通过这篇文章,你应该已经掌握了用 Laravel 队列 + HolySheep AI API 实现异步处理的完整方案。核心要点:
- 用户请求立即返回 task_id,前端轮询获取结果
- AI 调用逻辑封装在 Job 类中,通过队列异步执行
- 用 Supervisor 守护 queue:work 进程保证稳定性
- 优先选择 HolySheep 这类国内直连、低延迟、人民币无损兑换的 API 服务商
异步队列是处理 AI API 的最佳实践,它让你的应用在面对高并发时依然游刃有余。如果你在配置过程中遇到任何问题,欢迎留言交流。