我正在将一些系统从 PHP 5.5(直接安装在 AWS EC2 上)升级到 Docker 中的 PHP 7.4(使用 Docker Compose 在 AWS EC2 上运行)。使用 ImageMagick 调整图像大小的性能下降了很多。
测试脚本
为了诊断该问题,我编写了以下简单脚本,以 5MB JPEG 作为输入:
<?php
$image_name = "imgbench.jpeg";
$image_size = 4000;
$image_quality = 50;
$image = new Imagick();
$image->readImage($image_name);
$image->stripImage();
$image->resizeImage($image_size, $image_size, Imagick::FILTER_LANCZOS, 1, true);
$image->setImageCompressionQuality($image_quality);
$image->setInterlaceScheme(Imagick::INTERLACE_JPEG);
$image_blob = $image->getImageBlob();
测量
resizeImage()
从我的测量结果来看,和调用似乎getImageBlob()
占用了大部分执行时间,正如预期的那样。我在新旧系统上运行了此脚本 5 次(通过带有 php-fpm 的 nginx),发现以下平均执行时间:
- 旧系统(PHP 5.5):平均 2.5 秒
- 新系统(Docker 中的 PHP 7.4):平均 14.8 秒
换句话说,PHP 7.4 设置是慢 6 倍比旧的 PHP 5.5 设置更快!(时间是从 PHP 脚本内部测量的,因此 nginx/php-fpm 不应该发挥作用。)
对于其他类型的请求,新设置表现良好(比旧设置稍快,这可能是 PHP 7 的预期)。两个系统都使用相同类型的 EC2 实例,并且新系统中没有为 Docker 容器设置明确的资源限制。因此,我预计这次调整大小不会比以前慢。
有谁知道是什么原因导致的这种情况,更重要的是,如何在新系统中提高性能?
系统使用情况
运行测试脚本时使用的是旧系统,但其 CPU/内存可用空间充足。运行测试脚本时,其 CPU 使用率达到 300% 以上(根据top
)。
top
新系统在运行测试脚本时未被使用,因此也有足够的 CPU/内存可用。然而,根据和 的说法,这里的 CPU 使用率只上升到 150-180% docker stats
。
设置
旧系统
在旧系统上(使用 x64 Amazon Linux AMI 版本 1),PHP 设置如下:
sudo yum install php55-pecl-imagick ...
显示以下信息:
$ php -i
phpinfo()
PHP Version => 5.5.38
(...)
imagick
imagick module => enabled
imagick module version => 3.4.4
imagick classes => Imagick, ImagickDraw, ImagickPixel, ImagickPixelIterator
Imagick compiled with ImageMagick version => ImageMagick 6.7.8-9 2016-06-22 Q16 http://www.imagemagick.org
Imagick using ImageMagick library version => ImageMagick 6.7.8-9 2016-06-22 Q16 http://www.imagemagick.org
新系统
新系统使用 Docker(sudo yum install docker
在 x64 Amazon Linux 2 上)和以下用于 PHP 容器的 Dockerfile:
FROM php:7.4-fpm
COPY --from=mlocati/php-extension-installer /usr/bin/install-php-extensions /usr/bin/
RUN install-php-extensions imagick
imagick
(安装 PHP 扩展和libmagickwand-dev
手动安装时也存在同样的性能问题,没有mlocati/php-extension-installer
。)
这提供了以下信息:
$ docker-compose exec php php -i
phpinfo()
PHP Version => 7.4.13
(...)
imagick
imagick module => enabled
imagick module version => 3.4.4
imagick classes => Imagick, ImagickDraw, ImagickPixel, ImagickPixelIterator, ImagickKernel
Imagick compiled with ImageMagick version => ImageMagick 6.9.10-23 Q16 x86_64 20190101 https://imagemagick.org
Imagick using ImageMagick library version => ImageMagick 6.9.10-23 Q16 x86_64 20190101 https://imagemagick.org
答案1
我可以通过使用图像来解决这个问题php:alpine
。
具体原因尚不清楚,有关更多详细信息,请参阅以下问题:https://github.com/docker-library/php/issues/1100