在 Docker 中使用 OPcache 加速 PHP
发布日期:作者: Paul Redmond
如果您使用的是 Docker for Mac 或 Docker for Windows,您可能会注意到一些明显的延迟和首字节时间 (TTFB),具体取决于您的应用程序的设置。提高性能最重要的事情之一是启用 OPCache 模块(无论开发环境如何)。还有其他一些方法,例如卷缓存(如果可能),但 OPcache 是您在运行 PHP 应用程序的 **任何** 环境中都想要获得的优势。
OPcache 设置
启用 OPCache 模块后,您需要考虑一些事项,以确保您的配置适合开发,同时如果计划在生产环境中使用 Docker,则可以为生产环境做好准备。
以下是您在开发过程中最终获得的粗略配置
[opcache]opcache.enable=1; 0 means it will check on every request; 0 is irrelevant if opcache.validate_timestamps=0 which is desirable in productionopcache.revalidate_freq=0opcache.validate_timestamps=1opcache.max_accelerated_files=10000opcache.memory_consumption=192opcache.max_wasted_percentage=10opcache.interned_strings_buffer=16opcache.fast_shutdown=1
请注意,我们已对这些值进行了硬编码,这在不同环境之间缺乏灵活性。我们稍后会回来使其更灵活!
开发中最重要的一项设置是 opcache.validate_timestamps=1
,它允许我们对代码进行更改。如果您使用的是 Docker 卷,这意味着 OPcache 会尊重文件时间戳,您的更改将立即反映出来。在生产环境中,这并不理想,这就是我们的动态配置稍后将发挥作用的地方。
您不应在不了解它们的功能的情况下直接复制/粘贴这些设置。该配置主要来自 Steve Corona 的文章 最佳 Zend OpCache 设置/调整/配置,这是一份了解这些值含义的优秀资源。有关性能(包括 OPcache)的另一个优秀资源是 Chris Fidao 的 扩展 Laravel。
在 Dockerfile 中复制 INI 设置
以下是用于安装 OPcache 模块并在其中复制 INI 文件以配置 OPCache 的粗略 Dockerfile
FROM php:7.2-apache-stretch RUN docker-php-ext-install opcache COPY docker/php/conf.d/opcache.ini /usr/local/etc/php/conf.d/opcache.iniCOPY . /var/www/html
我没有展示完整的 PHP 应用程序工作示例。Laravel 的文档根目录需要是 /var/www/html/public
,但我只是试图在这篇文章中演示如何设置 OPcache。有关完整示例,您应查看我的课程 Docker for PHP 开发人员。
Dockerfile 假设以下文件夹结构用于组织您的 Docker 文件
├── app├── bootstrap├── config├── database├── docker│ └── php│ └── conf.d├── public├── resources├── routes├── storage├── tests└── vendor
请注意,在实际项目中,您可能会使用一个基础镜像,而不是将所有这些内容放在您的项目中,但我在这里展示了这些内容,以便您可以遵循 OPcache 的特定配置。
构建 Dockerfile
以下是可以运行的构建命令,用于尝试配置 OPcache
docker build --pull -t opcache-demo -f docker/Dockerfile .docker run --rm -it opcache-demo bash# In a running container:/var/www/html# php -m | grep OPcacheZend OPcache
使用环境进行灵活配置
我们已启用 OPcache,但如果我们想使此配置更灵活,可以使用环境变量来配置 INI 设置
[opcache] opcache.enable=1opcache.revalidate_freq=0opcache.validate_timestamps=${PHP_OPCACHE_VALIDATE_TIMESTAMPS}opcache.max_accelerated_files=${PHP_OPCACHE_MAX_ACCELERATED_FILES}opcache.memory_consumption=${PHP_OPCACHE_MEMORY_CONSUMPTION}opcache.max_wasted_percentage=${PHP_OPCACHE_MAX_WASTED_PERCENTAGE}opcache.interned_strings_buffer=16 opcache.fast_shutdown=1
现在我们有了环境驱动的 INI 文件,让我们在 Dockerfile 中为我们的项目提供一些默认值
FROM php:7.2-apache-stretch ENV PHP_OPCACHE_VALIDATE_TIMESTAMPS="0" \ PHP_OPCACHE_MAX_ACCELERATED_FILES="10000" \ PHP_OPCACHE_MEMORY_CONSUMPTION="192" \ PHP_OPCACHE_MAX_WASTED_PERCENTAGE="10" RUN docker-php-ext-install opcache COPY docker/php/conf.d/opcache.ini /usr/local/etc/php/conf.d/opcache.iniCOPY . /var/www/html
请注意,默认情况下,我们将禁用时间戳,因此我们需要在开发中覆盖此环境值。在这篇文章中,我们将不讨论使用 Docker Compose 设置环境,但以下是您可以运行的粗略命令,以确保在开发过程中验证时间戳
# Rebuild the image firstdocker build --pull -t opcache-demo -f docker/Dockerfile . docker run --rm -d \ -p 8080:80 \ -e "PHP_OPCACHE_VALIDATE_TIMESTAMPS=1" \ opcache-demo
在 Apache 容器在后台运行的情况下,您可以通过在容器中验证来确认 OPcache 时间戳设置是否为 1
# get the container iddocker psdocker exec -it 6002d83c6d24 bash # In a running container:/var/www/html# php -i | grep validate_timestampsopcache.validate_timestamps => On => On
如您所见,我们的配置现在由环境变量动态驱动!在 Docker 中,您的代码默认情况下将使用 OPCache 进行缓存,并且不会由于时间戳验证被禁用而更新。请注意,如果您使用的是 Nginx + PHP-FPM,您需要确保您的 FPM 池(可能是 www
)中包含 clear_env = no
[www]clear_env = no
您也可以手动将环境变量添加到池中,如果您不想将整个环境提供给 PHP。
了解更多
虽然本文中介绍的思路并非 Docker 独有,但 OPcache 在开发中提供的额外帮助非常有用,而且不会影响您更新代码的能力。
如果您想了解更多关于使用 Docker 和 PHP(包括 Laravel)开发 PHP 应用程序的信息,请查看我的课程 Docker for PHP 开发人员。
包含的链接是联盟链接,这意味着如果您决定购买,Laravel News 会获得一小部分收益,以帮助运行此网站。