Phalcon 在我使用 HttpResponse::send 时非常慢


Phalcon very slow when I use HttpResponse::send

我构建了一个Micro应用程序,一切正常。但性能测试显示出令人沮丧的结果。应用程序非常慢:

ab -n 1000 -c 50 http://myproject.net/

正常结果:

Concurrency Level:      100
Time taken for tests:   58.083 seconds
Complete requests:      1000
Failed requests:        0
Non-2xx responses:      1000
Total transferred:      578000 bytes
HTML transferred:       189000 bytes
Requests per second:    17.22 [#/sec] (mean)
Time per request:       5808.272 [ms] (mean)
Time per request:       58.083 [ms] (mean, across all concurrent requests)
Transfer rate:          9.72 [Kbytes/sec] received

在我评论$response->send()之后;测试结果变得更好:

Concurrency Level:      100
Time taken for tests:   7.960 seconds
Complete requests:      1000
Failed requests:        0
Total transferred:      166000 bytes
HTML transferred:       0 bytes
Requests per second:    125.62 [#/sec] (mean)
Time per request:       796.048 [ms] (mean)
Time per request:       7.960 [ms] (mean, across all concurrent requests)
Transfer rate:          20.36 [Kbytes/sec] received

在索引文件中,我将响应对象定义为共享服务:

$di->setShared(System::RESPONSE, new App'Http'Response());
App''Http''Response

是一个扩展 ''Phalcon''Http''Response 的类,允许我添加应用程序中所需的一些标头

namespace App'Http;
class Response extends 'Phalcon'Http'Response
{
    public function getDefaultErrorMessages()
    {
        return $this->defaultErrorMessages;
    }
    public function setDefaultErrorMessages($messages)
    {
        $this->defaultErrorMessages = $messages;
    }
    public function setErrors(array $messages)
    {
       $this->validationErrors = $messages;
    }
    public function setErrorContent('Exception $e, $developerInfo = false)
    {
        $errorCode = $e->getCode();
        $statusCode = 500;
        $message = 'Unspecified error';
        $error = [];
        if ($this->validationErrors) {
            $error['errors'] = $this->validationErrors;
        }

        $this->setJsonContent(['error' => $error]);
        $this->setStatusCode($statusCode);
    }

    public function setJsonContent($content, $jsonOptions = 0, $depth = 512)
    {
        parent::setJsonContent($content, $jsonOptions, $depth);
        $this->setHeader('Access-Control-Allow-Origin', '*');
        $this->setHeader('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
        $this->setHeader(
            'Access-Control-Allow-Headers',
            'Content-Type, X-Requested-With, X-Authorization'
        );
        $this->setContentType('application/json');
    }
}

我的所有代码都包装在索引文件中的 try-catch 语句中。我试图犯一个错误来抛出一个异常,如果异常是由 Zephir 抛出的,测试显示快速的结果,而如果它是由我们的代码抛出的,测试显示同样缓慢的结果。

当我使用"ab"的-k修饰符时,结果会变得更好:

ab -k -n 1000 -c 50 http://myproject.net/

您是否禁用了视图组件?当响应在代码的其他部分发送时,为什么要发送响应?

在我的一个项目中,我确实有一个 API 模块。此 API 模块已全局禁用视图:

app/modules/api/Module.php

    public function registerServices($di)
    {
        // ....
        $di->getView()->disable();
    }

在那之后,我相信这里不会构建任何与视图相关的服务。在 API 控制器命名空间中,我有我的基础

app/modules/api/controllers/controllerBase.php

<?php
namespace Application'Api'Controllers;
use 'Phalcon'Mvc'Controller;
class ControllerBase extends Controller {
    /**
     * Captures method result and tries to make a JSON response out of it.
     * 
     * @param 'Phalcon'Mvc'Dispatcher $dispatcher
     * @return 'Phalcon'Http'Response
     */
    protected function afterExecuteRoute($dispatcher) {
        $content = $dispatcher->getReturnedValue();
        // some logic for prematurely generated content (debugs/warnings)
        // ...
        if(is_object($content)) {
            if(is_callable(array($content, 'toArray'))) {
                $content = $content->toArray();
            } else {
                $content = (array) $content;
            }
        }

        $this->response->setContentType('application/json', 'UTF-8');
        $this->response->setJsonContent($frame);
        return $this->response->send();
    }
}

因此,我从操作中返回的是具有正确结果的数组。

为什么要返回响应?因为你一开始就省略了很多逻辑。此外,发送操作本身正在执行一些重载,因此最好的方法是:

        // from previous code frame
        $this->response->setJsonContent($frame);
        return $this->response; // no send() here
    }
}

索引中.php

echo $application->handle() // returning instance of Response
         ->getContent(); // getting content to echo

请检查您的代码,因为这不是第一次有人因为send()方法而出现 Phalcon 变慢的问题。如果你开始更改代码,你可能会很幸运地找到原因。我的猜测是视图生成。