Laravel Rate Limiter在DigitalOcean生产环境失效问题求助
解决Laravel生产环境(DigitalOcean+Nginx+Memcached)限流失效问题
1. 先确认Memcached是否正常工作
生产环境限流完全依赖Memcached缓存驱动,优先排查这个核心组件:
- 执行
systemctl status memcached查看服务运行状态,未启动则执行systemctl start memcached并设置开机自启 - 进入Laravel Tinker测试缓存读写:
若无法获取值,说明Laravel无法连接Memcached:php artisan tinker Cache::put('test_throttle', 'check', 60); Cache::get('test_throttle');- 检查
.env中MEMCACHED_HOST(默认127.0.0.1)和MEMCACHED_PORT(默认11211)配置 - 验证
php7.4-memcached扩展是否安装:执行php -m | grep memcached,无输出则在Ubuntu下执行apt install php7.4-memcached,安装后重启php-fpm
- 检查
2. 修复Nginx真实IP传递问题
Laravel限流默认以客户端IP作为标识,若Nginx未传递真实IP,所有请求会被识别为同一IP(服务器自身IP),导致限流失效。在Nginx站点配置中添加以下内容:
location / { # 保留原有配置,新增以下三行 proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; }
修改后重启Nginx:systemctl restart nginx,同时在Laravel中配置信任代理:
- 临时在
.env设置TRUSTED_PROXIES=*(生产环境稳定后建议改为具体IP) - 或在
config/trustedproxy.php中添加Nginx服务器IP到信任列表
3. 验证限流标识的正确性
在自定义限流逻辑中添加日志,确认生产环境获取的客户端IP是否正确:
protected function configureRateLimiter() { RateLimiter::for('test', function (Request $request){ Log::info('Throttle Request IP: ' . $request->ip()); return Limit::perMinute(1); }); }
查看storage/logs/laravel.log,若所有请求IP一致,说明IP传递存在问题,回到第二步修复;也可临时使用固定标识测试限流是否生效:
return Limit::perMinute(1)->by('test_fixed_key');
4. 检查中间件顺序与自定义中间件逻辑
确保throttle中间件优先于ProtectAgainstSpam执行,若自定义中间件提前返回响应,会绕过限流逻辑。同时检查ProtectAgainstSpam代码,必须调用$next($request),不能直接返回响应跳过后续中间件。
5. 清除生产环境缓存
生产环境配置缓存可能导致修改未生效,执行以下命令:
php artisan config:clear php artisan route:clear php artisan cache:clear
6. 确认Laravel缓存配置正确性
检查config/cache.php中的Memcached配置,确保服务器信息与生产环境一致:
'memcached' => [ 'driver' => 'memcached', 'servers' => [ [ 'host' => env('MEMCACHED_HOST', '127.0.0.1'), 'port' => env('MEMCACHED_PORT', 11211), 'weight' => 100, ], ], ],
内容的提问来源于stack exchange,提问作者Pepa Zdepa
相关产品推荐
相关产品推荐

