转:PHP应用性能优化指南

程序员都喜欢最新的PHP 7,因为它使PHP成为执行最快的脚本语言之一(参考PHP 7 vs HHVM 比较)。但是保持最佳性能不仅需要快速执行代码,更需要我们知道影响性能的问题点,以及这些问题的解决方案。本文涵盖了保障PHP应用平稳高速运行的所有知识点,大量干货来袭,强烈建议收藏。

PHP简史

PHP是由拉斯姆斯·勒多夫于1995年开始开发的。起初,它只是勒多夫为了要维护个人网页,而用c语言开发的一些CGI工具程序集,我们从PHP这个缩写最初的来源“Personal Home Page”(个人主页)就可以看出这一点。然而,随着勒多夫不断地扩充它的功能,PHP逐渐成为了现在的“PHP:超文本预处理器”。

在过去的20年中,PHP的开发团队一直致力于提升PHP的性能,最引人瞩目的是于1999年引入的Zend语法解释器引擎。2000年发布的PHP 4,包含了一个內建的编译器和执行器模型,使得PHP开始有能力开发动态的Web应用。2015年PHP发布了里程碑式的版本PHP 7.0,极大的提升了Zend引擎的性能,并降低了PHP的整体内存使用率。截止到本文发稿为止,目前最新的PHP版本是7.1.4,有兴趣的话可以看看这篇文章PHP7 新特性,改变变化。

怎样才算是高性能的PHP应用?

性能和速度不是一对同义词。实现最佳性能通常需要在速度、准确性和可扩展性之间进行权衡。例如,在开发Web应用时,如果你优先考虑速度,你可能会编写一个将所有内容都载入内存的脚本,而如果从可扩展性出发,可能你就会编写以块为单位将数据载入内存的脚本。

基于phpLens的研究,下图展示了速度与可扩展性之间理论上的权衡关系。

红线表示针对速度进行了优化的脚本,蓝线是可扩展性优先的脚本。当并发连接数低时,红线运行速度更快; 然而,随着并发连接数量的增加,红线变慢。当并发连接数上升时,蓝线也减慢;然而,下降并不那么剧烈,因此,在一定阈值后,速度优先的脚本会比可扩展性优先的脚本慢。然而,在现实当中,一些脚本可能随着运行环境的变化而表现出前后不同的性能差异。你需要仔细的观察用户的使用情况,以及应用的并发请求数量,来适时调整合适的优化策略。

PHP代码优化最佳实践

编写好的PHP代码是创建快速稳定Web应用的关键一步。从一开始就遵循一些最佳实践技巧将节省后期填坑的时间。

1. 尽可能的使用PHP的内置方法

只要可以尽可能的使用PHP的内置方法,而不是自己编写相同功能的方法。花点时间去熟悉和学习PHP的内置方法,不但可以帮助你更快的编写代码,而且可以使你编写的代码更高效的运行。

2. 使用Json替代xml

json_encode()和json_decode() 等PHP的内置方法,运行速度都非常快,所有应该优先使用Json。如果你无法避免使用xml,那么请务必使用正则表达式而不是DOM操作来进行解析。

3. 使用缓存技术

Memcache特别适用于减少数据库负载,而像APC或OPcache这样的字节码缓存引擎在脚本编译时可节省执行时间。

4. 减少不必要的计算

当一个变量会被多次使用时,一开始就计算好,肯定要比每次使用时都计算一遍要更高效。

5. 使用isset()和empty()

与count()、strlen()和sizeof()函数相比,isset()和empty()对于检测一个变量是否为空等场景更加简单和高效。

6. 减少不必要的类

如果你不打算重复使用一个类或者方法,那么它就没什么存在的价值。而如果你必须要定义和使用一个类,则需要合理规划类中的方法,对于不是特别公用的方法,尽量将他们放到子类中去,因为调用子类中的方法,比调用父类方法速度更快。

7. 在生产环境关闭用作调试的相关代码及错误报告

开发时打开错误报告,可以让你避免很多潜藏的Bug,而一些调试代码也有助于你定位Bug,但是当代码部署到生产环境后,这些错误报告和调试代码会拖慢你的程序速度,而且将一些错误报告直接显示给用户,也具有相当的安全风险。因此,在生产环境请关闭它们。

8. 关闭数据库连接

当使用完毕后,注销变量和关闭数据库连接,可以释放珍贵的内存资源。

9. 使用聚合函数减少数据库查询

查询数据库时,使用聚合函数,可以减少检索数据库的频率,并且使程序运行的更快。

10. 使用强大的字符串操作函数

举个例子,str_replace()比preg_replace()要快,而strtr()函数则比str_replace()函数快四倍。

11. 尽量使用单引号

如果可能,尽量使用单引号替代双引号。程序运行时,会检查双引号中的变量,这会拖慢程序的性能。

12. 尝试使用恒等运算符

由于“===”仅检查闭合范围,因此比使用“==”进行比较速度更快。

PHP代码之外的性能瓶颈因素

优化代码当然能够提高PHP的性能。但是,还有一些代码之外的因素也会成为PHP的性能瓶颈。这就是为什么程序员需要了解代码部署的整个服务器环境,这有助于他们在编写代码时有一定的心理准备,并能够在性能出现问题时,快速识别和定位性能瓶颈。以下是你遇到性能瓶颈时需要检查的点。

1. 网络带宽

如果网络带宽不够,其传输的总数据量将会受到严重影响,使其成为最明显的性能瓶颈。

2. CPU

如果只是传输一些纯静态的HTML,则不需要消耗很多CPU资源,但是PHP毕竟创建的是动态的应用程序,根据应用的需要,你可能至少需要一台具备多核处理器的服务器来提升PHP代码的运行效率。

3. 共享内存

缺少共享内存可能会影响进程间通信,从而影响程序性能。

4. 文件系统

随着时间推移,你的文件系统可能会出现大量磁盘碎片。如果内存足够,利用内存作为文件缓存可以加快磁盘的访问速度。

5. 进程管理

检查服务器的进程,确保里面没有非必要的进程。移除哪些不需要的网络协议、病毒扫描软件、邮件服务以及硬件驱动。将PHP代码运行在多线程模式,也能提高程序的响应时间。

6. 相关的其它服务

如果你的应用程序还依赖于一些外部服务,那这些外部服务的性能瓶颈也有可能拖慢你的应用。虽然这种情况下你能做的事情不多,但你仍然可以通过你这一边的操作来减轻外部服务性能瓶颈对你的影响,例如切换到备用服务上等。

更多PHP性能优化建议

1. 发挥OPCache的优势

由于默认情况下,PHP代码在执行时都会重新编译为可执行的中间代码OPCode,因此可以及时看到修改的代码所带来的变化,而不必频繁的重启PHP服务。不幸的是,如果每次在你的网站上运行时,都重新编译相同的代码会严重影响服务器的性能,这就是为什么opcode缓存或OPCache 非常有用。

OPCache是一个将编译好的代码保存到内存中的扩展。因此,下一次代码执行时,PHP将检查时间戳和文件大小,以确定源文件是否已更改。如果没有,则直接运行缓存的代码。

下图显示了运行无缓存的PHP应用程序,OPcache和eAccelerator(另一个PHP缓存工具)三者的执行时间和内存使用情况的差异。

 

图片来源: Prestashop

 

2. 识别数据库响应延迟

如上所述,性能问题并不总是由代码引起的。大多数瓶颈都出现在应用程序必须访问资源的时候。由于PHP应用程序的数据访问层可能占用最高90%的执行时间,因此你应该采取的第一步是查看代码中访问数据库的所有实例。

确保打开SQL的慢日志,以帮助你识别和处理慢SQL,然后评估这些查询的执行效率。如果你发现查询过多,或者在单次执行过程中发现相同的查询被多次进行,你可以通过减少数据库访问时间进行调整,从而提高应用程序的性能。

3. 清理文件系统

清理文件系统,并确保没有使用文件系统来存储Session。最重要的是,请注意file_exists(),filesize()或filetime()等触发文件统计信息的代码。将任何这些功能置于循环中可能会导致性能问题。

4. 监控外部API接口

大部分对外部系统有依赖关系的应用都会调用远程API。虽然这些远程API接口你无法直接控制,但你仍可以采取一些措施来减轻源自远程API的性能问题。例如,你可以缓存API输出的数据,或者可以在后台调用这些API。为API请求设置合理的超时时间,并且如果可能的话,随时做好API没有响应的情况下的显示输出。

5. 使用工具评估检测你的PHP代码

使用OPcache和监控外部API接口应该足以使大多数应用程序运行顺利;但是,如果你发现系统负载不断增加,那么可能需要使用工具来对你的PHP代码进行检测评估。完整的PHP代码检测评估虽然可能很耗时,但它可以为你提供有关应用程序性能的深入信息。幸运的是,有几个开源程序可以用于分析你的PHP代码,如Xdebug。

监控PHP性能的重要性

如果你没有做好准备,你的Web应用可能前一分钟还在正常运行,但是下一分钟,一波突然激增的流量就会导致你的应用程序崩溃。 当然,优化和重构总是需要时间、精力和资金,而且投入是否值得的也很难说。因此,做出明智决策的最佳方式是不断收集数据

PHP性能监控软件可以帮助你立即测量所做的任何更改的影响。当然,知道要监测什么同样重要。速度和内存使用被认为是性能的最佳指标,因为它们影响到页面加载时间,这对Web应用程序至关重要。

虽然数据收集很重要,但是当你不需要监控系统时,你应该关闭监控系统,因为大量日志同样也会对性能造成影响。当然,这样的日志可以提供有关如何提高性能的有用信息,因此你应该在高峰期间定期监控。

未来的PHP性能

PHP仍在不断进化中,在目前正在开发的PHP 8版本中,最新的功能是即时编译或JIT,它将可以为我们创建更快的Web应用。随着技术的不断进步,用户的期望也随之增加。因此,开发人员必须始终关注未来的变化。

在构建Web应用程序时,请记住,今年的工作可能在明年不起作用。你可能需要进行调整才能持续保持优秀的PHP性能。在开发过程中,应该持续重点关注如何构建适用于高并发场景的Web应用和网站,保证它们的高可用性。

参考文章

Using a PHP CDN Setup
How to Install Nginx PHP

转载于:https://www.cnblogs.com/dasn/articles/6857673.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/395778.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java 运行异常处理_Java编程异常处理和I/O流

重点:  1.在编写程序时,要正确地使用捕获例外和声明抛出异常的两种例外处理的方法。2.遇到实际问题时,要根据需要正确使用各种输入/输出流,特别是对中文使用适当的字符输入流。3.正…

反射练习

1.反射 一种计算机处理方式。是程序可以访问、检测和修改它本身状态或行为的一种能力。 新建一个Person类: public class Person { private int age; private String name; public int getAge() { return age; } public void setAge(int age) { this.age age; } pu…

开源 物联网接入_我们刚刚推出了开源产品。 那么接下来会发生什么呢?

开源 物联网接入by Victor F. Santos由Victor F.Santos 我们刚刚推出了开源产品。 那么接下来会发生什么呢? (We just launched an open source product. So what happens next?) Last month me and the ninja god Pedro launched GitShowcase, a plug-and-play p…

Class? getClass()

getClass()方法属于Object的一部分,它将产生对象的类,并且在打印该类时,可以看到该类类型的编码字符串,前导"["表示这是一个后满紧随的类型的数组,而紧随的"I"表示基本类型int, //: initialization/OptionalTrailingArgrments.java package object;import …

log4j使用说明

1.log4j代码中修改输出级别:如: protected final Logger logger LoggerFactory.getLogger(Test.class); 将其转成实现类,修改输出级别即可System.out.println(logger.isDebugEnabled()?"debug is true":"debug is false&quo…

java list集合增删改_Java中集合类list的增删改查

今天给大家带来的是Java中list类的使用,java.util 包提供了list类来对线性数据操作List接口是Collection接口的子接口,List有一个重要的实现类--ArrayList类,List中的元素是有序排列的而且可重复,所以被称为是序列List可以精确的控…

IIS6、IIS7和IIS8各版本的差别

一、写在前面 目前市面上所用的IIS版本估计都是>6.0的.所以我们主要以下面三个版本进行讲解 服务器版本IIS默认版本server20036.0server20087.0server20128.0二、IIS6的请求过程 由图可知,所有的请求会被服务器中的http.sys组件监听到,它会根据IIS中的 Metabase 查看基于该 …

Android Studio 插件的使用

1、GsonFormat https://github.com/zzz40500/GsonFormat 2、Android SelectorChapek http://blog.csdn.net/weifei554287925/article/details/41727541

函数式编程基础_在收件箱中免费学习函数式编程的基础

函数式编程基础by Preethi Kasireddy通过Preethi Kasireddy 在收件箱中免费学习函数式编程的基础 (Learn the fundamentals of functional programming — for free, in your inbox) If you’re a software developer, you’ve probably noticed a growing trend: software ap…

安卓Java虚拟机大小_虚拟机为安卓流畅度背锅,是因为关系数十万程序员饭碗?...

导读:虚拟机相当于应用程序在不同运行环境中的翻译。说起谷歌安卓系统的“虚拟机”,很多人爱拿它和苹果iOS做比较,结果,安卓的很多短腿儿都让虚拟机背了锅,比如安卓手机运存容量是iPhone的两到三倍,流畅度却…

Redis PHP连接操作

安装 要在PHP程序中使用Redis,首先需要确保 Redis 的PHP驱动程序和 PHP 安装设置在机器上。可以查看 PHP教程 教你如何在机器上安装PHP。现在,让我们来看看一下如何设置 Redis 的PHP驱动程序。 需要从 github 上资料库: https://github.com/n…

AppCompatActivity实现全屏的问题

前言:我的 Activity 是继承 BaseActivity , 而 BaseActivity 继承 AppCompatActivity 。 BaseActivity 的继承 /*** 应用程序的基类**/ public class BaseActivity extends AppCompatActivity {}HomeActivity 的继承 public class HomeActivity extends BaseActivit…

aws cognito_使用AWS Cognito的用户管理—(1/3)初始设置

aws cognitoby Kangze Huang黄康泽 使用AWS Cognito的用户管理—(1/3)初始设置 (User Management with AWS Cognito — (1/3) Initial Setup) 完整的AWS Web样板-教程1A (The Complete AWS Web Boilerplate — Tutorial 1A) Main Table of Contents Click Here主要目录请点击这…

java建一个conversion_Scala中的JavaConverters和JavaConversions之间有什么区别?

JavaConversions 提供了一系列隐式方法,可以在Java集合和最接近的相应Scala集合之间进行转换,反之亦然 . 这是通过创建实现Scala接口的包装器并将调用转发到底层Java集合或Java接口,将调用转发到底层Scala集合来完成的 .JavaConverters 使用p…

flexbox:1.0.0_了解Flexbox:您需要了解的一切

flexbox:1.0.0This article will cover all the fundamental concepts you need to get good with the CSS Flexbox model. It’s a long one, so I hope you’re ready for it.本文将介绍您熟悉CSS Flexbox模型所需的所有基本概念。 这是一个很长的时间,所以希望您…

10.Object类

在JAVA中,所有的类都直接或间接继承了Java.lang.Object类Object是一个特殊的类,他是所有类的父类,是Java类层中的最高层类。当创建一个类时,他总是在继承,除非某个类已经指定要从其他类继承,否则他就是从ja…

RecyclerView的下拉刷新和加载更多 动画

下拉刷新和加载更多 1、https://github.com/jianghejie/XRecyclerView 2、http://blog.csdn.net/jabony/article/details/44780187 动画 1、https://github.com/wasabeef/recyclerview-animators

java中显示动态信息的方法_java里的动态表单技术

最近的一个项目,由于客户的需求等信息不确定,为了降低以后修改的成本及产品的推广考虑到动态表单技术,之前也一直在考虑到动态表单技术,毕竟在delphi里已经实现过了,由于我们采用的hibernate的执久层的原故&#xff0c…

Cinder 组件详解 - 每天5分钟玩转 OpenStack(47)

本节我们将详细讲解 Cinder 的各个子服务。 cinder-api cinder-api 是整个 Cinder 组件的门户,所有 cinder 的请求都首先由 nova-api 处理。cinder-api 向外界暴露若干 HTTP REST API 接口。在 keystone 中我们可以查询 cinder-api 的 endponits。 客户端可以将请…

中国移动 全球通、 动感地带、神州行 的区别

1、全球通 1、主要面向商务人士可以享受机场VIP俱乐部的尊贵、1860专席的高质量服务、个性化账单、客户积分奖励以及大客户经理贴心服务,更有尊贵资费套餐优惠,但它价格也是最贵的。 2、全球通面对事业成功的人士,进取。 3、全球通&#xff…