我的 Laravel 应用程序位于负载均衡器后面,并且 2 个 EC2 实例同时运行。在我只在一台服务器上管理 cronjob 之前,但这不是理想的方式,因为如果负载增加或发生异常错误,并且如果第三个 EC2 实例初始化,那么 cronjob 也会在该服务器上启动,并且我的 cronjob 正在执行关键任务,例如条带充电或过期订阅,如果两台服务器都执行 cronjob 任务,那么用户将多次对条带收费。
为了解决这种情况,我使用 Redis 实现了分布式锁定。我将 .env 文件中的默认缓存驱动程序从文件更改为 redis。
CACHE_DRIVER=redis
并在Console/Kernel.php
中添加了这样的onOneServer方法。
$schedule->command('subscription:autorenew')->everyMinute()->withoutOverlapping()->onOneServer();
现在,即使两台服务器都启用了 crontab,它也只在一台服务器上执行任务,但我的部署管道有命令
php artisan cache:clear
,因为即使任务正在进行中,锁也被释放,第二台服务器也同时开始执行相同的任务.
是否有任何 Laravel 内置方式可以让我设置默认值
CACHE_DRIVER=file
并仍然使用 Redis 进行分布式锁,以便 php artisan cache:clear
不影响 Redis 缓存锁?
问题:php artisan cache:clear 命令清除了所有缓存,包括 onOneServer() 使用的 Redis 锁,导致任务在两台服务器上运行。
解决方案:
为锁建立单独的 Redis 连接:在 config/database.php 中,仅为 onOneServer 锁设置一个新的 Redis 连接(例如 redis_lock)。这将锁与一般缓存清除隔离开来。
避免在生产中使用cache:clear:对特定键使用特定命令,如config:clear或cache:forget,而不是清除所有内容。
此设置可防止缓存:清除影响您的锁定,确保 onOneServer() 按预期跨 EC2 实例工作。