使用Rancher在K8S上部署高性能PHP应用程序的教程


Posted in PHP onJuly 10, 2020

介 绍

PHP是网络上最流行的编程语言之一,许多被广泛使用的内容管理系统都使用它开发,如WordPress和Drupal,并为现代服务器端框架(如Laravel和Symfony)提供核心代码。

尽管PHP很受欢迎,但是其缓慢和难以维护也是众所周知的。近几年这两个毛病已经没有那么严重了,但是高性能的PHP应用程序依然会需要两个功能:OPcache和PHP FastCGI进程管理器(PHP-FPM)。

在本文中,你将了解到在Kubernetes上如何使用自定义OPcache和PHP-FPM配置部署一个PHP应用程序以提高其性能。你将使用Rancher来部署一个PHP应用程序,该应用程序使用自定义环境变量来动态配置OPcache和PHP-FPM。我们将展示如何在你的Docker镜像中构建PHP-FPM配置选项并在容器中使用环境变量调整它们。

在PHP中的性能

首先,了解PHP应用程序中如何处理网络请求将对本文接下来的内容很有帮助。

PHP通常运行在web服务器旁边,处理请求并将它们发送到PHP应用程序中。你可以使用PHP-FPM或mod_PHP来运行你的应用程序,但在本文中我们将使用PHP-FPM,因为其性能优势并且NGINX是最常与PHP-FPM一起使用的web服务器。

使用Rancher在K8S上部署高性能PHP应用程序的教程

OPcache介绍

OPcache通过在首次调用脚本时将脚本存储在内存中来加速PHP应用程序。进而,随后的请求将从内存而不是文件系统加载,这可以使你的速度提高74%。

OPcache提供了一些设置,你可以调整这些设置来提高应用程序的性能和可靠性。在本篇教程中,你将了解到如何设置一个PHP Docker镜像,该镜像可以调整OPcache的内存限制、缓存文件数量以及重新验证缓存频率。

PHP-FPM介绍

PHP-FPM(FastCGI进程管理器)会启动一个或多个进程以运行你的PHP应用程序。与mod_PHP(将PHP捆绑为Apache模块)不同,PHP-FPM使你可以精确控制服务器(或容器)运行的进程数量,以及它们应该如何启动和停止。

找到一个理想的PHP-FPM配置高度依赖于你的应用程序以及它所服务的请求数量和容器中的内存和CPU限制。我推荐你阅读Hayden James关于这个主题的文章(链接已放在文末)并且在负载测试环境下测试几种不同的配置。

在K8S上部署一个PHP应用程序

前期准备

在你进行本篇教程之前,你需要做好以下准备:

  • 在你本地机器上安装好的Docker
  • Docker Hub或其他Docker镜像仓库上的账号
  • Rancher部署(如果你还没部署,可以按照Quick start进行)
  • 通过Rancher管理的Kubernetes集群

在本教程中使用的所有代码都可以在Github中获取,或者你可以按照以下步骤从头开始构建应用程序。

PHP应用程序

你将要使用的应用程序是一个显示当前日期的PHP文件。创建一个新文件并将其命名为index.php

<?php
echo 'The current date is ' . date('F jS, Y');

创建Dockerfile和配置文件

在Docker Hub上,你可以获得很多PHP Docker镜像,但它们都没有提供使用环境变量来修改OPcache或PHP-FPM配置的简便方法。使用环境变量的优势在于,您无需每次要调整PHP-FPM或OPcache设置时都需要重建PHP映像。这可以让你快速调整你的应用程序以提升性能。

首先,创建一个名为opcache.ini的新文件。你将复制该文件到PHP镜像中并在Dockerfile中为每个环境变量添加默认值。

# See https://www.php.net/manual/en/opcache.configuration.php for all available configuration options.
[opcache]
opcache.enable=${PHP_OPCACHE_ENABLE}
opcache.memory_consumption=${PHP_OPCACHE_MEMORY_CONSUMPTION}
opcache.max_accelerated_files=${PHP_OPCACHE_MAX_ACCELERATED_FILES}
opcache.revalidate_freq=${PHP_OPCACHE_REVALIDATE_FREQUENCY}
opcache.validate_timestamps=${PHP_OPCACHE_VALIDATE_TIMESTAMPS}

接下来,创建另一个名为www.conf的新文件。该文件将存储PHP-FPM配置选项,你可以通过环境变量对其进行更新:

; See https://www.php.net/manual/en/install.fpm.configuration.php for all available configuration options

; Required user, group, and port options
[www]
user = www-data
group = www-data
listen = 127.0.0.1:9000

; Process manager options
pm = ${PHP_FPM_PM}
pm.max_children = ${PHP_FPM_MAX_CHILDREN}
pm.start_servers = ${PHP_FPM_START_SERVERS}
pm.min_spare_servers = ${PHP_FPM_MIN_SPARE_SERVERS}
pm.max_spare_servers = ${PHP_FPM_MAX_SPARE_SERVERS}
pm.max_requests = ${PHP_FPM_MAX_REQUESTS}

你需要复制这些文件到你的Docker镜像中并且设置默认的环境变量值,因此请在项目的根目录中创建一个新的Dockerfile。添加以下步骤:

FROM php:7.4-fpm

# OPcache defaults
ENV PHP_OPCACHE_ENABLE="1"
ENV PHP_OPCACHE_MEMORY_CONSUMPTION="128"
ENV PHP_OPCACHE_MAX_ACCELERATED_FILES="10000"
ENV PHP_OPCACHE_REVALIDATE_FREQUENCY="0"
ENV PHP_OPCACHE_VALIDATE_TIMESTAMPS="0"

# Install opcache and add the configuration file
RUN docker-php-ext-install opcache
ADD opcache.ini "$PHP_INI_DIR/conf.d/opcache.ini"

# PHP-FPM defaults
ENV PHP_FPM_PM="dynamic"
ENV PHP_FPM_MAX_CHILDREN="5"
ENV PHP_FPM_START_SERVERS="2"
ENV PHP_FPM_MIN_SPARE_SERVERS="1"
ENV PHP_FPM_MAX_SPARE_SERVERS="2"
ENV PHP_FPM_MAX_REQUESTS="1000"

# Copy the PHP-FPM configuration file
COPY ./www.conf /usr/local/etc/php-fpm.d/www.conf

# Copy the PHP application file
COPY ./index.php /var/www/public/index.php
RUN chown -R www-data:www-data /var/www/public

Dockerfile将OPCache配置、PHP-FPM配置以及PHP应用程序文件复制到镜像中,并确保包含PHP代码的var/www/public目录为PHP-FPM用户所有。ENV 声明设置了默认的PHP_OPCACHE_...PHP_FPM_...环境变量,但你可以在运行这个镜像时随时覆盖它们。这将使实际部署中的性能调整变得更加容易。

构建并推送到DockerHub

至此,你的项目中已经有了一个单文件PHP应用程序、一个OPcache配置文件、一个PHP-FPM配置文件和一个Dockerfile。你现在可以构建你的Docker镜像:

docker build -t <YOUR_USERNAME>/php-fpm .

接下来,将镜像推送到Docker Hub:

docker push <YOUR_USERNAME>/php-fpm

部署一个PHP-FPM工作负载

既然你的自定义PHP-FPM镜像在Docker Hub上已经可以获取,你可以将其作为工作负载的一部分部署在Kubernetes集群上。使用Rancher UI,创建一个新的deployment,将其命名为php-fpm,并使用<YOUR_USERNAME>/php-fpm作为Docker镜像。你可以修改以上Dockerfile中使用的任何PHP_OPCACHE _...PHP_FPM _...环境变量。

使用Rancher在K8S上部署高性能PHP应用程序的教程

在设置Nginx工作负载以服务于PHP-FPM deployment之前,请检查你的PHP-FPM和OPcache设置是否已正确添加到容器中。在Rancher UI中,单击PHP deployment旁边的三个点,然后单击“ Execute Shell”:

使用Rancher在K8S上部署高性能PHP应用程序的教程

要检查OPcache模块是否已启用,请键入php-fpm -i。这将输出整个PHP .ini配置。浏览一下OPcache上的部分,你应该会看到类似以下内容(更改的任何值都会反映出来):

...
opcache.blacklist_filename => no value => no value
opcache.consistency_checks => 0 => 0
opcache.dups_fix => Off => Off
opcache.enable => On => On
opcache.enable_cli => Off => Off
opcache.enable_file_override => Off => Off
opcache.error_log => no value => no value
opcache.file_cache => no value => no value
opcache.file_cache_consistency_checks => 1 => 1
opcache.file_cache_only => 0 => 0
opcache.file_update_protection => 2 => 2
opcache.force_restart_timeout => 180 => 180
opcache.huge_code_pages => Off => Off
opcache.interned_strings_buffer => 8 => 8
opcache.lockfile_path => /tmp => /tmp
opcache.log_verbosity_level => 1 => 1
opcache.max_accelerated_files => 10000 => 10000
opcache.max_file_size => 0 => 0
opcache.max_wasted_percentage => 5 => 5
opcache.memory_consumption => 256 => 256
opcache.opt_debug_level => 0 => 0
opcache.optimization_level => 0x7FFEBFFF => 0x7FFEBFFF
opcache.preferred_memory_model => no value => no value
opcache.preload => no value => no value
opcache.preload_user => no value => no value
opcache.protect_memory => 0 => 0
opcache.restrict_api => no value => no value
opcache.revalidate_freq => 0 => 0
opcache.revalidate_path => Off => Off
opcache.save_comments => 1 => 1
opcache.use_cwd => On => On
opcache.validate_permission => Off => Off
opcache.validate_root => Off => Off
opcache.validate_timestamps => Off => Off
...

每当你重新部署PHP-FPM工作负载时,PHP-FPM都会重新启动并重置OPcache,因此,当你在Kubernetes上运行PHP-FPM时,你通常不必担心重置OPcache。如果确实要手动刷新缓存,最简单的方法是从Rancher UI重新部署工作负载。

为了确保PHP-FPM配置更改可以生效,请在shell中键入php-fpm -tt。你应该看到所有PHP-FPM选项的列表,包括进程管理器更新的部分(该管理器添加到www.conf文件并使用环境变量进行设置):

NOTICE: pm = dynamic
NOTICE: pm.max_children = 10
NOTICE: pm.start_servers = 2
NOTICE: pm.min_spare_servers = 1
NOTICE: pm.max_spare_servers = 2
NOTICE: pm.process_idle_timeout = 10
NOTICE: pm.max_requests = 1000

部署Nginx工作负载

现在,你有一个PHP-FPM工作负载,但是没有Web服务器可以访问它。你可以使用许多NGINX Docker镜像来为你的PHP应用程序提供服务,但是我通常使用这个NGINX镜像(https://www.shiphp.com/blog/2018/nginx-php-fpm-with-env ),它允许你通过使用环境变量将一个镜像用于任意数量的PHP-FPM工作负载。

在Rancher UI中创建新的工作负载,该负载与PHP-FPM工作负载在相同的集群上。将其命名为nginx,使用Docker镜像shiphp / nginx-env,将容器上的端口80映射到集群上的开放端口,并添加环境变量NGINX_HOST = php-fpm

使用Rancher在K8S上部署高性能PHP应用程序的教程

如果你把PHP-FPM工作负载命名为php-fpm以外的名字,或者你想为第二个工作负载提供服务,你可以使用NGINX_HOST环境变量来连接它,这也允许你在同一个集群上运行多个PHP-FPM和Nginx工作负载。这也允许你在同一个集群上运行多个PHP-FPM和Nginx工作负载。

一旦你的Nginx工作负载可用,点击它所在的端口链接,打开Web应用程序。你应该看到你的PHP脚本生成的当前日期。

使用Rancher在K8S上部署高性能PHP应用程序的教程

结 论

现在,你已经将PHP-FPM工作负载部署到了Kubernetes集群中,你可以开始真正的性能调优工作了。幸运的是,现在更新 PHP-FPM 和 OPcache设置就像更改环境变量和重新部署 Workload 一样简单。这将允许你尝试新的设置,并比重新构建镜像更快获得反馈。

从Web应用程序中获得最佳性能是一个反复的过程,但希望本教程中的Kubernetes部署能帮助你构建更高性能的PHP应用程序。

参考链接:

PHP性能提升:
https://gbksoft.com/blog/php-5-vs-php-7-performance-comparison/

PHP-FPM性能优势:
https://www.cloudways.com/blog/php-fpm-on-cloud/

NGINX
http://nginx.org/en/

OPcache配置设置:
https://www.php.net/manual/en/opcache.configuration.php

提升性能以及你的OPcache应用程序可靠性:
https://tideways.com/profiler/blog/fine-tune-your-opcache-configuration-to-avoid-caching-suprises

Hayden James的PHP-FPM调整文章:
https://haydenjames.io/php-fpm-tuning-using-pm-static-max-performance/

PHP-FPM配置测试:
https://speakerdeck.com/erictendian/performance-testing-and-optimization-with-laravel-and-lumen

到此这篇关于使用Rancher在K8S上部署高性能PHP应用程序的文章就介绍到这了,更多相关Rancher部署K8s PHP应用程序内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

PHP 相关文章推荐
PHP中实现进程间通讯
Oct 09 PHP
html中select语句读取mysql表中内容
Oct 09 PHP
php下HTTP Response中的Chunked编码实现方法
Nov 19 PHP
php生成excel列名超过26列大于Z时的解决方法
Dec 29 PHP
PHP设计模式之观察者模式实例
Feb 22 PHP
PHP使用PHPExcel删除Excel单元格指定列的方法
Jul 06 PHP
PHP在innodb引擎下快速代建全文搜索功能简明教程【基于xunsearch】
Oct 14 PHP
使用一个for循环将N*N的二维数组的所有值置1实现方法
May 29 PHP
php利用云片网实现短信验证码功能的示例代码
Nov 18 PHP
php实现二叉树中和为某一值的路径方法
Oct 14 PHP
PHP实现的文件浏览器功能简单示例
Sep 12 PHP
PHP高并发和大流量解决方案整理
Dec 24 PHP
PHP实现简易用户登录系统
Jul 10 #PHP
PHP二维数组分页2种实现方法解析
Jul 09 #PHP
详解阿里云视频直播PHP-SDK接入教程
Jul 09 #PHP
PHP利用curl发送HTTP请求的实例代码
Jul 09 #PHP
PHP使用POP3读取邮箱接收邮件的示例代码
Jul 08 #PHP
phpmyadmin在宝塔面板里进不去的解决方案
Jul 06 #PHP
详解PHP中的8个魔术常量
Jul 06 #PHP
You might like
php实现可逆加密的方法
2015/08/11 PHP
YII框架中搜索分页jQuery写法详解
2016/12/19 PHP
如何优雅的使用 laravel 的 validator验证方法
2018/11/11 PHP
同一页面多个商品倒计时JS 基于面向对象的javascript
2012/02/16 Javascript
关于全局变量和局部变量的那些事
2013/01/11 Javascript
document.addEventListener使用介绍
2014/03/07 Javascript
js获取当前时间显示在页面上并每秒刷新
2014/12/24 Javascript
JavaScript原生对象之Date对象的属性和方法详解
2015/03/13 Javascript
JS中prototype的用法实例分析
2015/03/19 Javascript
zepto与jquery的区别及zepto的不同使用8条小结
2016/07/28 Javascript
Canvas实现放射线动画效果
2017/02/15 Javascript
详解vue+vueRouter+webpack的简单实例
2017/06/17 Javascript
CheckBox多选取值及判断CheckBox选中是否为空的实例
2017/10/31 Javascript
详解如何在微信小程序开发中正确的使用vant ui组件
2018/09/13 Javascript
vue中多个倒计时实现代码实例
2019/03/27 Javascript
vue中nextTick用法实例
2019/09/11 Javascript
js实现固定区域内的不重叠随机圆
2019/10/24 Javascript
python实现2048小游戏
2015/03/30 Python
Python 中pandas.read_excel详细介绍
2017/06/23 Python
解决python使用open打开文件中文乱码的问题
2017/12/29 Python
Python解决两个整数相除只得到整数部分的实例
2018/11/10 Python
Python Opencv实现图像轮廓识别功能
2020/03/23 Python
python实现广度优先搜索过程解析
2019/10/19 Python
python paramiko远程服务器终端操作过程解析
2019/12/14 Python
python对文件的操作方法汇总
2020/02/28 Python
Python基于DB-API操作MySQL数据库过程解析
2020/04/23 Python
PyCharm中配置PySide2的图文教程
2020/06/18 Python
详解pycharm配置python解释器的问题
2020/10/15 Python
详解win10下pytorch-gpu安装以及CUDA详细安装过程
2021/01/28 Python
CSS3实现瀑布流布局与无限加载图片相册的实例代码
2016/12/22 HTML / CSS
Java程序员面试90题
2013/10/19 面试题
廉洁校园实施方案
2014/05/25 职场文书
企业员工辞职信范文
2015/05/12 职场文书
保护环境建议书作文400字
2015/09/14 职场文书
交通安全教育心得体会
2016/01/15 职场文书
Python借助with语句实现代码段只执行有限次
2022/03/23 Python