You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

API Platform控制器调用JWT刷新接口超时问题求助

解决控制器内调用自身API超时的问题

嘿,我之前也踩过这个坑!你现在遇到的超时问题,本质是同一个请求上下文里的自调用死锁:当你的PHP进程(比如FPM)正在处理当前控制器请求时,又发起了一个对自身服务的HTTP请求,这个新请求需要等待当前进程释放资源才能被处理,结果两边互相卡住,最终导致超时。而Postman能正常调用是因为它是外部请求,会占用新的服务器进程,不会和当前请求抢资源。

下面给你两个可行的解决方案,按推荐程度排序:

1. 直接调用业务服务(最优解)

API Platform的JWT刷新逻辑肯定是封装在某个内部服务里的,完全没必要绕HTTP请求。比如如果你用的是LexikJWTAuthenticationBundle(最常用的Symfony JWT组件),可以直接注入对应的刷新服务来处理:

首先在控制器的构造函数或者方法中注入Lexik\Bundle\JWTAuthenticationBundle\Services\JWTTokenRefreshInterface

use Lexik\Bundle\JWTAuthenticationBundle\Services\JWTTokenRefreshInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;

class YourController extends AbstractController
{
    public function yourAction(string $refresh_token, JWTTokenRefreshInterface $refreshService)
    {
        // 直接调用刷新逻辑,不用走HTTP
        $newTokenData = $refreshService->refresh($refresh_token);
        
        // 这里可以直接获取新的access_token和refresh_token
        $newAccessToken = $newTokenData->getToken();
        $newRefreshToken = $newTokenData->getRefreshToken();
        
        // 后续处理逻辑...
    }
}

这种方式不仅避免了死锁,还比HTTP请求高效得多,是最推荐的做法。

2. 必须用HTTP请求时的折中方案

如果因为某些特殊原因(比如必须通过API的中间件、权限校验等)必须走HTTP请求,那就要避免当前进程阻塞:

  • 使用异步队列:把刷新JWT的请求放到Symfony Messenger之类的消息队列里,让独立的消费者进程去发起HTTP请求,当前控制器直接返回结果,不等待请求完成。
  • 调整服务器进程配置:比如增加FPM的pm.max_children数量,确保有足够的空闲进程来处理内部请求,但这只是治标不治本,而且会增加服务器资源消耗,不推荐作为长期方案。

最后再提醒一下:尽量避免在控制器内部调用自身的HTTP接口,这种设计本身就不够优雅,而且很容易引发这类资源阻塞问题。优先直接调用内部服务才是正确的思路~

内容的提问来源于stack exchange,提问作者Thomas Rollet

火山引擎 最新活动