Laravel-Excel 分布式任务处理:使用 Redis 队列处理多服务器导入
Laravel-Excel 分布式任务处理:使用 Redis 队列处理多服务器导入
【免费下载链接】Laravel-Excel 🚀 Supercharged Excel exports and imports in Laravel 项目地址: https://gitcode.com/gh_mirrors/la/Laravel-Excel
为什么需要分布式任务处理?
在处理大型 Excel 文件导入时,单服务器往往面临内存溢出、超时等问题。通过 Redis 队列将导入任务分发到多台服务器处理,可以显著提升性能和可靠性。Laravel-Excel 提供了完整的队列支持,结合 Redis 可实现真正的分布式处理。
核心组件与工作原理
Laravel-Excel 的分布式处理基于以下核心类实现:
- QueueImport.php:负责将导入任务加入队列
- ReadChunk.php:处理文件分块读取
- ExtendedQueueable.php:扩展 Laravel 队列功能,支持任务链式处理
- ModelManager.php:管理模型数据批量写入
分布式处理流程
实现步骤
1. 配置 Redis 队列
修改 Laravel 配置文件 config/queue.php,设置 Redis 作为默认队列驱动:
'default' => env('QUEUE_CONNECTION', 'redis'),
'redis' => [
'driver' => 'redis',
'connection' => 'default',
'queue' => env('REDIS_QUEUE', 'default'),
'retry_after' => 90,
'block_for' => null,
],
2. 创建支持队列的导入类
实现 ShouldQueue 接口创建可队列化的导入类:
'required|email|unique:users',
'name' => 'required',
];
}
/**
* 转换为模型
*/
public function model(array $row)
{
return new User([
'name' => $row[0],
'email' => $row[1],
'password' => bcrypt('password'),
]);
}
}
3. 分发导入任务到队列
在控制器中分发导入任务:
use AppImportsUsersImport;
use MaatwebsiteExcelFacadesExcel;
public function import()
{
Excel::queueImport(new UsersImport, request()->file('file'));
return back()->with('message', '导入任务已开始处理');
}
4. 启动队列处理器
在多台服务器上启动队列处理器:
php artisan queue:work redis --queue=imports --tries=3
高级功能
监控任务进度
使用 WithProgressBar 接口实现进度监控:
use MaatwebsiteExcelConcernsWithProgressBar;
use IlluminateConsoleOutputStyle;
class UsersImport implements WithProgressBar
{
public function getConsoleOutput(): OutputStyle
{
return new OutputStyle(app()->input, app()->output);
}
}
错误处理与重试
实现 SkipsOnError 和 SkipsOnFailure 接口处理错误:
use MaatwebsiteExcelConcernsSkipsOnError;
use MaatwebsiteExcelConcernsSkipsOnFailure;
use MaatwebsiteExcelValidatorsFailure;
use Throwable;
class UsersImport implements SkipsOnError, SkipsOnFailure
{
public function onError(Throwable $e)
{
// 处理错误
logger()->error($e->getMessage());
}
public function onFailure(Failure ...$failures)
{
// 处理验证失败
foreach ($failures as $failure) {
logger()->error("行 {$failure->row()}: {$failure->errors()[0]}");
}
}
}
性能优化建议
- 合理设置分块大小:根据服务器配置调整
chunkSize,通常建议 500-2000 行 - 使用批量插入:通过
ModelManager的批量写入功能减少数据库连接开销 - 优化 Redis 配置:调整
retry_after和block_for参数避免任务重复执行 - 监控队列状态:使用 Laravel Horizon 监控队列运行状态
常见问题解决
内存溢出问题
- 减小分块大小
- 禁用不必要的事件监听
- 使用
WithCustomQuerySize自定义查询大小
任务执行超时
修改队列超时设置:
// 在导入类中设置
public $timeout = 300; // 5分钟超时
数据一致性保证
使用数据库事务确保数据一致性:
use IlluminateSupportFacadesDB;
public function model(array $row)
{
DB::beginTransaction();
try {
$user = new User([
// ...
]);
$user->save();
DB::commit();
return $user;
} catch (Exception $e) {
DB::rollBack();
throw $e;
}
}
总结
通过 Laravel-Excel 结合 Redis 队列实现的分布式任务处理,能够有效解决大型 Excel 文件导入的性能瓶颈问题。核心在于将大任务分解为小任务,通过多服务器并行处理提高效率。实际应用中需根据数据量大小和服务器资源情况,合理调整分块大小和队列配置,以达到最佳性能。
要深入了解 Laravel-Excel 的队列功能,可以查看源代码中的 QueueImport.php 和 ReadChunk.php 实现。
扩展阅读
- Laravel 队列文档: https://laravel.com/docs/queues
- Laravel-Excel 官方文档: https://docs.laravel-excel.com
- Redis 分布式锁实现
【免费下载链接】Laravel-Excel 🚀 Supercharged Excel exports and imports in Laravel 项目地址: https://gitcode.com/gh_mirrors/la/Laravel-Excel








