本番環境で使用される PHP は、PHP 自体のパフォーマンスを向上させるために最適化する必要があります。PHP コードの作成に加えて、php-fpm と php.ini のチューニングも構成する必要があります。この記事では、メモリ、OPcache、アップロード、セッション、セキュリティの側面から php.ini の設定チューニングについて説明します。
#他のコンパイル言語と比較した場合、PHP の最大の欠点は、各リクエストで何らかのモジュール解析が行われ、実際に実行されるのは作業プロセスであることです。作業プロセスの開始にはより多くのリソースが必要です。同時に、リクエストごとに一部のコードが再解析され、解析が繰り返されることになります。
PHP の最適化では、この側面に焦点を当てて最適化を検討できます。
PHP を実行するときは、各 PHP プロセスが使用するメモリの量に注意する必要があります。php.ini の memory_limit
設定単一の PHP プロセスが使用できるシステム メモリの最大量を決定するために使用されます。
この設定のデフォルト値は 128M で、ほとんどの中小規模の PHP アプリケーションに適しています。ただし、マイクロ PHP アプリケーションを実行している場合は、この値を下げてシステム リソースを節約できます。逆に、メモリを大量に消費する PHP アプリケーションを実行している場合は、この値を増やすことができます。この値のサイズは、利用可能なシステム メモリによって決まります。PHP に割り当てる値の量を決定するのは技術です。PHP に割り当てるメモリの量と、許容できる PHP-FPM プロセスの数を決定するときは、次の基準に基づいて判断できます。次の次元情報について:
PHP に割り当てられるメモリの量はどれくらいですか? 2G メモリを備えた VPS を例にとると、このデバイスでは MySQL、Nginx などの他のプロセスも実行できるため、PHP 用に 512M を残しておくのが適切です。
各 PHP プロセスは平均してどのくらいのメモリを消費しますか?プロセスのメモリ使用量を監視するには、コマンド ライン コマンド top
を使用するか、PHP スクリプトで memory_get_peak_usage()
関数を呼び出すことができます。同じスクリプトを実行し、平均メモリ消費量を取得します。
PHP-FPM プロセスをいくつまで実行できるでしょうか? 512M のメモリを PHP に割り当て、各 PHP プロセスが平均 15M のメモリを消費すると仮定すると、34 個の PHP-FPM プロセスを用意できます。
; 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
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: この設定の値が 1 の場合、PHP は一定期間後に PHP スクリプトの内容が変更されたかどうかをチェックします。チェックの時間間隔は次のとおりです。 opcache.revalidate_freq の指定によって設定されます。この設定の値が 0 の場合、PHP は PHP スクリプトの内容が変更されたかどうかをチェックしないため、キャッシュされたオペコードを自分でクリアする必要があります。開発環境では 1 に設定し、運用環境では 0 に設定することをお勧めします。
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视频教程》
以上がPHP を最適化して高い同時実行性を向上させるにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。