AuthenticationMiddleware.php 中的 process() 函数有时耗时过长

process() function in AuthenticationMiddleware.php takes sometimes too long

有些页面需要简单的重新加载,有时需要很长时间 [4 到 45 秒之间]。不幸的是,延迟是不可预测的。起初我认为这当然是我做错了,但经过进一步调查,我发现了延迟功能。


vendor/cakephp/authentication/src/Middleware/AuthenticationMiddleware.php函数中process()运行这段代码$service->authenticate($request);

public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
    $service = $this->getAuthenticationService($request);

    try {
        $result = $service->authenticate($request);
        ^^^^^^^^ This call needs between 0.01 and 45 seconds
    } catch (AuthenticationRequiredException $e) {
        $body = new Stream('php://memory', 'rw');

这些是我的执行时间测量的一些示例转储:

/api/shop 的转储,执行时间较长;向右滚动以查看每次快照之间的增量时间:

[2020-11-01T16:58:02+00:00] /api/shop/ - /vendor/cakephp/authentication/src/Middleware/AuthenticationMiddleware.php :0103 - Delta time:0.04342
[2020-11-01T16:58:14+00:00] /api/shop/ - /vendor/cakephp/authentication/src/Middleware/AuthenticationMiddleware.php :0107 - Delta time:11.81272
[2020-11-01T16:58:14+00:00] /api/shop/ - /vendor/cakephp/authentication/src/Middleware/AuthenticationMiddleware.php :0121 - Delta time:11.81295  

然后,17秒后[没有变化,只是重新加载页面]没有延迟:

[2020-11-01T16:58:31+00:00] /api/shop/ - /vendor/cakephp/cakephp/src/Http/Runner.php                                :0071 - Delta time:0.03756
[2020-11-01T16:58:31+00:00] /api/shop/ - /vendor/cakephp/authentication/src/Middleware/AuthenticationMiddleware.php :0103 - Delta time:0.04211
[2020-11-01T16:58:31+00:00] /api/shop/ - /vendor/cakephp/authentication/src/Middleware/AuthenticationMiddleware.php :0107 - Delta time:0.04506

知道是什么原因吗?这非常令人沮丧,因为它是完全不可预测的。如上面所示的真实示例,在几秒钟内有一个巨大的延迟,然后它工作了 3-4 次,然后突然又延迟了。如前所述,我什么都没做;正在重新加载页面。

CakePHP 4.1.4

我也在CakePHP Github Issues. The CakePHP member othercorey下发了这个案例给了我检查Authentication\Authenticator\SessionAuthenticator的建议,在这里我找到了原因:

vendor/cakephp/cakephp/src/Http/Session.php
--> 在函数中 start()
--> 调用 if (!session_start()) {

完整代码:

    if (!session_start()) {
        throw new RuntimeException('Could not start the session');
    }

那么解决方法就很简单了。我正在使用 SSE,这就是这些不可预测的延迟的原因。在 SSE 函数中调用 session_write_close() 后,页面加载 <2 秒。

有时间我会检查存储在数据库中的会话是否可能是另一种解决方案。