使用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+java实现自动新闻滚动窗口
Oct 09 PHP
PHP 中的批处理的实现
Jun 14 PHP
php提示undefined index的几种解决方法
May 21 PHP
PHP数组排序函数合集 以及它们之间的联系分析
Jun 27 PHP
分享一个php 的异常处理程序
Jun 22 PHP
php中多维数组按指定value排序的实现代码
Aug 19 PHP
php查询ip所在地的方法
Dec 05 PHP
PHP批量查询WordPress留言者E-mail地址实现方法
Feb 15 PHP
php中使用websocket详解
Sep 23 PHP
PHP解耦的三重境界(浅谈服务容器)
Mar 13 PHP
laravel框架 laravel-admin上传图片到oss的方法
Oct 13 PHP
浅谈PHP7中的一些小技巧
May 29 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和js如何通过json互相传递数据相关问题探讨
2013/02/26 PHP
php遍历解析xml字符串的方法
2016/05/05 PHP
JavaScript数组对象赋值用法实例
2015/08/04 Javascript
详解JavaScript中的构造器Constructor模式
2016/01/14 Javascript
Bootstrap轮播插件简单使用方法介绍
2016/06/21 Javascript
jQuery实现的自定义弹出层效果实例详解
2016/09/04 Javascript
js中获取键盘事件的简单实现方法
2016/10/10 Javascript
jQuery通过ajax快速批量提交表单数据
2016/10/25 Javascript
基于Vue.js实现tab滑块效果
2017/07/23 Javascript
js实现日期显示的一些操作(实例讲解)
2017/07/27 Javascript
用node-webkit把web应用打包成桌面应用(windows环境)
2018/02/01 Javascript
jquery+php后台实现省市区联动功能示例
2019/05/23 jQuery
Vue CLI3基础学习之pages构建多页应用
2019/06/02 Javascript
ES6中new Function()语法及应用实例分析
2020/02/19 Javascript
微信小程序12行js代码自己写个滑块功能(推荐)
2020/07/15 Javascript
Python3简单实例计算同花的概率代码
2017/12/06 Python
Python 利用高德地图api实现经纬度与地址的批量转换
2019/08/14 Python
python爬虫 猫眼电影和电影天堂数据csv和mysql存储过程解析
2019/09/05 Python
基于python的BP神经网络及异或实现过程解析
2019/09/30 Python
详解python 降级到3.6终极解决方案
2020/02/06 Python
TensorFlow2.1.0最新版本安装详细教程
2020/04/08 Python
python基于socket函数实现端口扫描
2020/05/28 Python
什么是python的必选参数
2020/06/21 Python
解决python和pycharm安装gmpy2 出现ERROR的问题
2020/08/28 Python
深入剖析webstorage[html5的本地数据处理]
2016/07/11 HTML / CSS
The Outnet亚太地区:折扣设计师时装店
2019/12/05 全球购物
高中毕业生个人自我鉴定
2013/11/24 职场文书
军人违纪检讨书
2014/02/04 职场文书
读书活动实施方案
2014/03/10 职场文书
感恩祖国演讲稿
2014/09/09 职场文书
健康教育主题班会
2015/08/14 职场文书
组织委员竞选稿
2015/11/21 职场文书
2019最新公司租房合同(例文)
2019/07/18 职场文书
vue项目两种方式实现竖向表格的思路分析
2021/04/28 Vue.js
Python 可迭代对象 iterable的具体使用
2021/08/07 Python
Vue3中的Refs和Ref详情
2021/11/11 Vue.js