PHP, das in Produktionsumgebungen verwendet wird, muss optimiert werden, damit PHP selbst eine bessere Leistung erbringt. Zusätzlich zum Schreiben von PHP-Code müssen auch PHP-FPM und php.ini-Tuning konfiguriert werden. In diesem Artikel wird die Konfigurationsoptimierung von php.ini unter den Aspekten Speicher, OPcache, Upload, Sitzung und Sicherheit erläutert.
Im Vergleich zu anderen kompilierten Sprachen besteht der größte Nachteil von PHP darin, dass jede Anfrage eine Modulanalyse erfordert und der Arbeitsprozess tatsächlich ausgeführt wird. Der Beginn des Arbeitsprozesses erfordert mehr Ressourcen. Gleichzeitig werden bei jeder Anfrage einige Codes erneut analysiert, was zu einer wiederholten Analyse führt.
Bei der Optimierung von PHP können Sie sich auf diesen Aspekt konzentrieren, um eine Optimierung in Betracht zu ziehen.
Beim Ausführen von PHP müssen Sie darauf achten, wie viel Speicher jeder PHP-Prozess verwendet. Die Einstellung memory_limit
in php.ini wird verwendet, um den maximalen Systemspeicher festzulegen, den ein einzelner Prozess verwendet PHP-Prozess kann verwenden. memory_limit
设置用于设定单个 PHP 进程可以使用的系统内存最大值。
这个设置的默认值是 128M,这对于大多数中小型 PHP 应用来说或许合适,不过,如果运行的是微型 PHP 应用,可以降低这个值,以便节省系统资源,反之,如果运行的是内存集中型 PHP 应用,可以增加这个值。这个值的大小由可用的系统内存决定,确定给 PHP 分配多少值是一门艺术,决定给 PHP 分配多少内存,以及能负担起多少个 PHP-FPM 进程时,可以根据以下维度信息进行判断:
一共可以分配给 PHP 多少内存?以一个 2G 内存的 VPS 为例,这台设备中可能还运行了其他进程,如 MySQL、Nginx 等,那么留 512M 给 PHP 是合适的。
每个 PHP 进程平均耗费多少内存?这个要监控进程的内存使用量,可以使用命令行命令top
,也可以在 PHP 脚本中调用 memory_get_peak_usage()
函数,不管使用哪种方式,都要多次运行同一个脚本,然后取内存消耗的平均值。
能负担起多少个 PHP-FPM 进程?假设我给 PHP 分配了 512M 内存,每个 PHP 进程平均耗费 15M 内存,那么可以负担起 34 个 PHP-FPM 进程。
有足够的系统资源吗?最后还需要确认有足够的系统资源运行 PHP 应用并处理预期的流量。具体的PHP配置信息可以参考php-fpm.config配置文件。
; Time limit for child processes to wait for a reaction on signals from master. ; Available units: s(econds), m(inutes), h(ours), or d(ays) ; Default Unit: seconds ; Default Value: 0 ;process_control_timeout = 0 ; The maximum number of processes FPM will fork. This has been designed to control ; the global number of processes when using dynamic PM within a lot of pools. ; Use it with caution. ; Note: A value of 0 indicates no limit ; Default Value: 0 ; process.max = 128 ; Specify the nice(2) priority to apply to the master process (only if set) ; The value can vary from -19 (highest priority) to 20 (lowest priority) ; Note: - It will only work if the FPM master process is launched as root ; - The pool process will inherit the master process priority ; unless specified otherwise ; Default Value: no set ; process.priority = -19 ; Send FPM to background. Set to 'no' to keep FPM in foreground for debugging. ; Default Value: yes daemonize = no
php-fpm有三种运行模式,分别是固定进程数、按需进程数、完全动态进程数。
按需进程数,默认初始化几个进程数,如果进去量过大,动态创建一些新的进程数,等请求结束之后,新创建的进程数在销毁掉。
固定进程数,默认固定几个进程,如果进程数不够的情况时,新的请求处于等待中,直到其他的进程处理完毕才会处理新的请求。
完全动态进程数,表示完全由请求量控制,来一个请求创建一个进程,处理完毕在销毁掉。
确定要分配多少内存后,就可以配置 PHP 的 Zend OPcache 扩展。OPcache主要是将一些代码解析成字节码,在后续的请求中就无需重复去解析、编译这部分代码。减少编译、解析的过程,也能提高PHP的处理速度。
PHP5.5.0+内置了这个扩展,下面罗列几项必要的配置信息:
opcache.memory_consumption = 64
:为操作码缓存分配的内存(单位是MB),分配的内存量应该可以保存应用中所有 PHP 脚本编译得到的操作码,这个值根据应用的体量可以设置成不同大小的值。
opcache.interned_strings_buffer = 16
:用来存储驻留字符串的内存量(单位是MB),什么是驻留字符串呢?PHP 解释器在背后会找到相同字符串的多个实例,把这个字符串保存在内存中,如果再次使用相同的字符串,PHP 解释器会使用指针,这么做的目的是节省内存。默认情况下,PHP 驻留字符串会隔离在各个 PHP 进程中,这个设置能让 PHP-FPM 进程池把所有进程驻留字符串存储到共享的缓冲区中,以便在 PHP-FPM 进程池中的多个进程之间引用驻留字符串,这样能节省更多内存。
opcache.max_accelerated_files = 4000
:操作码缓存中最多能存储多少个 PHP 脚本,这个值的区间是 2000 到 100000 之间,这个值一定要比 PHP 应用中的文件数大。
opcache.validate_timestamps = 1
top
verwenden oder die Funktion memory_get_peak_usage()
in einem PHP-Skript aufrufen, egal welche Methode verwendet wird, führen Sie dasselbe Skript mehrmals aus und ermitteln Sie den Durchschnittsspeicherverbrauch. 🎜file_uploads = 1 upload_max_filesize = 10M max_file_uploads = 3
opcache.memory_consumption = 64
: Der für den Opcode-Cache zugewiesene Speicher (Einheit ist MB), zugewiesen Die Speichermenge sollte in der Lage sein, die von allen PHP-Skripten in der Anwendung kompilierten Opcodes zu speichern. Dieser Wert kann je nach Größe der Anwendung auf unterschiedliche Größen eingestellt werden. 🎜🎜opcache.interned_strings_buffer = 16
: Die Menge an Speicher, die zum Speichern residenter Strings verwendet wird (Einheit ist MB). Hinter den Kulissen findet der PHP-Interpreter mehrere Instanzen derselben Zeichenfolge und speichert die Zeichenfolge im Speicher. Wenn dieselbe Zeichenfolge erneut verwendet wird, verwendet der PHP-Interpreter einen Zeiger. Standardmäßig werden PHP-residente Zeichenfolgen in jedem PHP-Prozess isoliert. Diese Einstellung ermöglicht es dem PHP-FPM-Prozesspool, alle prozessresidenten Zeichenfolgen in einem gemeinsamen Puffer zu speichern, damit sie im PHP-FPM-Prozesspool verarbeitet werden können werden zwischen mehreren Prozessen referenziert, was mehr Speicher spart. 🎜🎜opcache.max_accelerated_files = 4000
: Die maximale Anzahl von PHP-Skripten, die im Opcode-Cache gespeichert werden können. Der Bereich dieses Werts liegt zwischen 2000 und 100000. Dieser Wert muss größer sein als die Anzahl von Dateien in der PHP-Anwendung. 🎜🎜opcache.validate_timestamps = 1
: Wenn der Wert dieser Einstellung 1 ist, prüft PHP nach einer gewissen Zeit, ob sich der Inhalt des PHP-Skripts geändert hat. Das Prüfintervall wird vom Opcache festgelegt .revalidate_freq-Einstellung. Wenn der Wert dieser Einstellung 0 ist, prüft PHP nicht, ob sich der Inhalt des PHP-Skripts geändert hat, und wir müssen die zwischengespeicherten Opcodes selbst löschen. Es wird empfohlen, ihn in der Entwicklungsumgebung auf 1 und in der Produktionsumgebung auf 0 zu setzen. 🎜opcache.revalidate_freq = 0
:设置多久(单位是秒)检查一次 PHP 脚本内容是否有变化。设置为0秒的含义是仅当opcache.validate_timestamps设置为1时,才会在每次请求时都重新验证 PHP 文件,因此,在开发环境中每次都会重新验证 PHP 文件,在生产环境中则不验证。
opcache.fast_shutdown = 1
:这么设置能让操作码使用更快的停机步骤,把对象析构和内存释放交给 Zend Engine 的内存管理器完成。
如果你的应用允许上传文件,最好设置最大能上传的文件大小。除此之外,最好还要设置最多能同时上传多少个文件:
file_uploads = 1 upload_max_filesize = 10M max_file_uploads = 3
默认情况下,PHP 允许在单次请求中上传 20 个文件,上传的文件最大为 2MB,这里我设置为单次请求最多只能上传 3 个文件,每个文件最大为 10MB,这个值不要设置太大,否则会出现超时。
注:如果非要上传大文件,Web 服务器的配置也要做相应调整。除了在 php.ini 中设置之外,还要调整 Nginx 虚拟主机配置中的 client_max_body_size
设置。
此外,如果是上传特大文件,我建议使用Webuploader专门的上传组件,前端对大文件进行切片,后端php对分片数据进行合并还原文件。有关WebUploader应用请参考本站文章:功能强大的文件上传组件-WebUploader。
max_execution_time 用于设置单个 PHP 进程在终止之前最长可运行时间。这个设置默认是 30 秒,建议将其设置为 5 秒:
max_execution_time = 5
在 PHP 脚本中可以调用set_limit_time()
函数覆盖这个设置。
假设我们想要生成报告,并把结果制作成 PDF 文件,这个任务可能要花 10 分钟才能完成,而我们肯定不想让 PHP 请求等待 10 分钟,我们应该单独编写一个 PHP 文件,让其在单独的后台进程中执行,Web 应用只需几毫秒就可以派生一个单独的后台进程,然后返回 HTTP 响应。
实际上,我们在跑需要消耗大量时间来完成的任务,一般采用后台进程方式,比如我们可以使用PHP的swoole扩展来生成报表、批量发送邮件耗时长的任务。
PHP默认的情况是将会话产生的信息存在磁盘中,例如所谓的session信息。在创建和读取session时,都会对磁盘进行I/O操作,读写磁盘其实是比较耗时的一个操作。并且session不方便做分布式应用的会话机制处理。推荐可以放在Redis、memcached这样的内存性服务中,读写速度快,并且可以做分布式会话机制处理。
下面举例将session这样的信息,存储在memcached内存中。
session.save_handler = "memcached" session.save_path = "服务地址:端口号"
如果是在较少的块中发送更多数据,而不是在较多的块中发送较少的数据,那么网络的效率会更高,也就是说,在较少的片段中把内容传递给访问者的浏览器,能减少 HTTP 请求总数。
因此,我们要让 PHP 缓冲输出,默认情况下,PHP 已经启用了输出缓冲功能,PHP 缓冲 4096 字节的输出之后才会把内容发送给 Web 服务器,推荐配置如下:
output_buffering = 4096 implicit_flush = false
如果想要修改输出缓冲区的大小,确保使用的值是4(32位系统)或8(64位系统)的倍数。
open_basedir
:使用open_basedir选项能够控制PHP脚本只能访问指定的目录,这样能够避免PHP脚本访问不应该访问的文件,一定程度上限制了phpshell的危害。我们一般可以设置为只能访问网站目录:
open_basedir = /data/www
disable_functions
:一般我们要禁止系统函数和禁止任何文件和目录的操作,如:
disable_functions = '.....'
expose_php = Off
:将此项设置为false即不会再header头输出PHP版本信息。
display_errors = Off
:生产环境中,我们应该禁止错误提示,如果是本地开发环境,可以设置为On。
log_errors = On
:建议在关闭display_errors后能够把错误信息记录下来,便于查找服务器运行的原因。
error_log
:设置PHP错误日志存放的目录。
推荐学习:《PHP视频教程》
Das obige ist der detaillierte Inhalt vonWie kann PHP optimiert werden, um eine hohe Parallelität zu verbessern?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!