在symfony3中加载私有图像需要太长时间

时间:2017-03-09 21:22:17

标签: nginx symfony

我通过控制器提供受保护的图像,以便我可以在需要时从公共视图中禁用其中一些图像。因此,我使用BinaryFileResponse,实际上直接从Nginx提供图像 这是控制器:

public function getPictureAction(Request $request, $id)
{
        $image = $this->getDoctrine()
                      ->getRepository('AppBundle:Images')
                      ->getOneById($id);

        $dir = $this->get('kernel')->getRootDir() . '/';

        // Serving image by using Nginx's 'XSendfile'
        $request->headers->set('X-Sendfile-Type', 'X-Accel-Redirect');
        $request->headers->set('X-Accel-Mapping', $dir . '=/images-internal/');
        BinaryFileResponse::trustXSendfileTypeHeader();

        $path = $dir . 'images/image.jpg';
        $response = new BinaryFileResponse($path);

        $response->setContentDisposition(ResponseHeaderBag::DISPOSITION_INLINE);

        return $response;
}

启用了X-Accel-Redirect的nginx配置的一部分:

location /images-internal/ {
    internal;
    alias   /home/vagrant/Sites/Symfony/app/;
}

路由在routing.yml:

picture_path:
    path: /images/{id}
    defaults: {_controller: AppBundle:Pages/Home:getPicture, _format: html}
    methods: [GET]
    options:
        expose: true

在Twig模板中,我像这样加载图像:

<img src="{{ path('picture_path', {'id': imageId}) }}">

使用此设置, 53KB 图像的平均加载时间约为 700ms

出于测试目的,我使用来自公共网站目录的Twig的AssetExtension加载了相同的图像:

<img src="{{ asset('bundles/img/image.jpg') }}">

加载时间 30ms

通过控制器加载图像需要这么长时间是正常的,还是我做错了什么?

1 个答案:

答案 0 :(得分:2)

这取决于其他控制器的加载时间。我的意思是控制器返回常规响应,而不是二进制。如果它们的加载时间是700毫秒或更长,这是正常的。

从公共网站目录加载图片很快,因为只涉及网络服务器(nginx)。

通过控制器加载图像涉及web-server(nginx),php,symfony。因此,ussualy需要与常规控制器的请求相同的时间。

X-Accel-Redirect在这种情况下没有多大帮助,它通常用于大文件来释放php进程。 Php进程发送此头并终止处理,然后nginx读取并发送文件。

如果你想加快图片加载尝试安装php opcache或在没有symfony的纯php上编写脚本来处理图像下载。