首页 > 解决方案 > 仅在使用本地资源时从 HTML 生成 PDF 需要很长时间

问题描述

我使用KnpSnappyBundle 1.6.0wkhtmltopdf 0.12.5从 PHP 中的 HTML 生成 PDF,如下所示:

$html = $this->renderView(
    'pdf/template.html.twig',
    [ 'entity' => $entity, ]
);

return new PdfResponse($snappy->getOutputFromHtml($html,
    ['encoding' => 'UTF-8', 'images' => true]), 'file'.$entity->getUniqueNumber().'.pdf'
);

我的问题:在我的生产服务器上,当我引用托管在与我的代码相同的服务器上的资产(图像或 CSS)时,生成 PDF 大约需要 40-50 秒。即使我只使用托管在同一台服务器上的小图像,也需要 40 秒。我可以使用托管在另一台服务器上的更大的图像,并且会立即生成 PDF。

一般来说,我的服务器在提供资产或文件方面并不慢。如果我只是将 HTML 呈现为一个页面,它会立即发生(有或没有资产)。当我在本地(在我的笔记本电脑上)从我的生产服务器请求资产以生成 PDF 时,它也会立即发生。

我在需要呈现为 PDF 的 HTML 中需要的资产都具有绝对 URL,这是 wkhtmltopdf 工作所必需的。例如:<img src="https://www.example.com/images/logo.png">困难的是,一切正常,但速度很慢。没有指向会导致超时的不存在的资产。

我首先认为它可能与wkhtmltopdf有关,所以我尝试了不同的版本和不同的设置,但这并没有改变任何东西。我还尝试指向同一服务器上的另一个域,问题仍然存在。我尝试不使用 KnpSnappyBundle,但问题仍然存在。

所以我现在的猜测是这是一个服务器问题(或与 wkhtmltopdf 的组合)。我正在运行Nginx-1.16.1并通过 SSL 提供所有内容。我安装了OpenSSL 1.1.1d 10 Sep 2019(库:OpenSSL 1.1.1g 21 Apr 2020),我的操作系统是Ubuntu 18.04.3 LTS。其他一切都在此服务器上按预期工作。

当我查看 Nginx 访问日志时,我可以看到在使用来自同一服务器的资产时,我自己的 IP 地址发出了一个获取请求。我不明白为什么这要花这么长时间,而且我已经不知道接下来要尝试什么了。任何想法表示赞赏!

我将为我的域添加我的 Nginx 配置(以防它可能有帮助):

server {
        root /var/www/dev.example.com/public;
        index index.php index.html index.htm index.nginx-debian.html;

        server_name dev.example.com www.dev.example.com;

        location / {
        # try to serve file directly, fallback to index.php
        try_files $uri /index.php$is_args$args;     
    }

        location ~ ^/index\.php(/|$) {
        fastcgi_pass unix:/var/run/php/php7.3-fpm.sock;
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        fastcgi_param DOCUMENT_ROOT $realpath_root;
        internal;
    }

  location ~ \.(?:jpg|jpeg|gif|png|ico|woff2|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc|js|css)$ {
        gzip_static on;

        # Set rules only if the file actually exists.
        if (-f $request_filename) {
        expires max;
        access_log off; 
        add_header Cache-Control "public";
    }
            try_files $uri /index.php$is_args$args;     
 }

    error_log /var/log/nginx/dev_example_com_error.log;
    access_log /var/log/nginx/dev_example_com_access.log;

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/dev.example.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/dev.example.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

server {
    if ($host = dev.example.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

    server_name dev.example.com www.dev.example.com;
    listen 80;
    return 404; # managed by Certbot
}

Udate 2020 年 8 月 5 日:我尝试了 wkhtmltopdf 0.12.6,但这给了我完全相同的问题。几个月前我发布的作为我的问题的答案的“解决方案”远非完美,这就是我寻找新建议的原因。任何帮助表示赞赏。

标签: phppdfnginxwkhtmltopdf

解决方案


这对我来说听起来像是一个 DNS 问题。我会尝试添加一个条目,/etc/hosts例如:

127.0.0.1     example.com
127.0.0.1     www.example.com

并指向您的图像以使用该域


推荐阅读