[TOC]
# 內存優化
> **memory_limit**
> 用于設定單個 PHP 進程可以使用的系統內存最大值。
默認值為 128M。適用于大多數中小型PHP應用,對于微信PHP應用,可以降低此值來節省系統資源。如果運行的是內存集中型 PHP 應用,可以增加這個值。
為PHP分配多少內存,以及能負擔起多少個 PHP-FPM 進程,根據以下維度信息進行判斷:
1. 一共可以分配給 PHP 多少內存?以一個 2G 內存的 VPS 為例,這臺設備中可能還運行了其他進程,如 MySQL、Nginx 等,那么留 512M 給 PHP 是合適的。
2. 每個 PHP 進程平均耗費多少內存?這個要監控進程的內存使用量,可以使用命令行命令top,也可以在 PHP 腳本中調用 [memory_get_peak_usage()](https://www.php.net/manual/zh/function.memory-get-peak-usage.php) 函數,不管使用哪種方式,都要多次運行同一個腳本,然后取內存消耗的平均值。
~~~text
memory_get_peak_usage — 返回分配給 PHP 內存的峰值
~~~
3. 能負擔起多少個 PHP-FPM 進程?假設我給 PHP 分配了 512M 內存,每個 PHP 進程平均耗費 15M 內存,那么可以負擔起 34 個 PHP-FPM 進程。
# 開啟Zend OPcache 性能加速
> PHP屬于解釋型語言,在執行代碼過程中,翻譯器并不產生目標機器代碼,而是產生易于執行的中間代碼,這種中間代碼每執行一次就翻譯一次,通常會導致執行效率較低,而在PHP7中可以直接開啟Opcache來進行性能優化和加速。
> PHP 5.5+版本以上的,可以使用PHP自帶的opcache開啟性能加速(默認是關閉的),PHP5.5之后opcache可以直接--enable-opcache。對于PHP 5.5以下版本的,可以使用APC來進行緩存。
## 配置OPcache

~~~text
zend_extension=opcache.so
opcache.enable=1
~~~
設置多少內存緩存opcode,單位M。如果內存不夠用,就會出現一些php文件緩存不到的情況
~~~text
opcache.memory_consumption=128
~~~
最大允許緩存多少個php文件,需要根據項目的文件數來定。這個值一定要比 PHP 應用中的文件數大。最大支持100萬個文件
~~~text
opcache.max_accelerated_files=4000
~~~
這個設置的值為1時,經過一段時間后 PHP 會檢查 PHP 腳本的內容是否有變化,檢查的時間間隔由opcache.revalidate_freq設置指定。如果這個設置的值為0,PHP 不會檢查 PHP 腳本的內容是否有變化,我們必須自己動手清除緩存的操作碼。建議在開發環境中設置為1,生產環境中設置為0。
~~~
opcache.validate_timestamps=0
~~~
驗證時間戳的頻率。單位是秒。;此選型依賴于opcache.vilidate_timestamps=1(開啟檢查機制),才生效
~~~
opcache.revalidate_freq = 60
~~~
字符串駐留技術使用多少內存,設置為8M,這是默認值。
~~~
opcache.interned_strings_buffer = 16
~~~
快速釋放內存,推薦開啟,節省資源。php-7.2.0開始,不需要配置,已集成在php引擎中
~~~
opcache.fast_shutdown=1
~~~
是不是只使用文件來緩存opcode,不使用內存緩存。建議:關掉。最好內存和文件都同時使用
~~~
opcache.file_cache_only=false
~~~
將內存中緩存的opcdoe,備份到磁盤文件中。這樣好處,重啟服務器時,可以避免重新生成了。注意目錄的權限要設對,設置php引擎所屬linux用戶能夠寫入。實測,若權限不夠,并不會報錯,只是緩存不進去
~~~
opcache.file_cache=/apps/php-7.1.7/opcode_file_cache
~~~
# 文件上傳
> 如果你的應用允許上傳文件,最好設置最大能上傳的文件大小。除此之外,最好還要設置最多能同時上傳多少個文件
~~~
file_uploads = 1
upload_max_filesize = 10M
max_file_uploads = 3
~~~
默認情況下,PHP 允許在單次請求中上傳 20 個文件,上傳的文件最大為 2MB。
*注:如果非要上傳大文件,Web 服務器的配置也要做相應調整。除了在 php.ini 中設置之外,還要調整 Nginx 虛擬主機配置中的 client_max_body_size 設置。*
上傳特大文件,我建議使用Webuploader專門的上傳組件,前端對大文件進行切片,后端php對分片數據進行合并還原文件
# 執行時間
> max_execution_time 用于設置單個PHP進程在終止之前最長 可運行時間。默認是 30 秒,建議將其設置為 5 秒:
~~~
max_execution_time = 5
~~~
*注:在 PHP 腳本中可以調用set_limit_time()函數覆蓋這個設置。
假設我們想要生成報告,并把結果制作成 PDF 文件,這個任務可能要花 10 分鐘才能完成,而我們肯定不想讓 PHP 請求等待 10 分鐘,我們應該單獨編寫一個 PHP 文件,讓其在單獨的后臺進程中執行,Web 應用只需幾毫秒就可以派生一個單獨的后臺進程,然后返回 HTTP 響應。
實際上,我們在跑需要消耗大量時間來完成的任務,一般采用后臺進程方式,比如我們可以使用PHP的swoole擴展來生成報表、批量發送郵件耗時長的任務。*
# 處理會話
> PHP 默認的會話處理程序會拖慢大型應用,因為這個處理程序會把會話數據存儲在硬盤中,需要創建不必要的磁盤 I/O,浪費時間。我們應該把會話數據保存在內存中,例如可以使用 Memcached 或 Redis。
> 這么做還有個額外好處 —— 以后便于伸縮。如果會話數據存儲在硬盤中,不便于增加額外的服務器,如果把會話數據存放在 Memcached 或 Redis 里,任何一臺分布式 PHP-FPM 服務器都能訪問會話數據。
~~~
session.save_handler = 'redis'
session.save_path = '127.0.0.1:6379'
~~~
# 緩沖輸出
> 如果是在較少的塊中發送更多數據,而不是在較多的塊中發送較少的數據,那么網絡的效率會更高,也就是說,在較少的片段中把內容傳遞給訪問者的瀏覽器,能減少 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 = passthru,system,chroot,scandir,chgrp,chown,shell_exec,proc_open,proc_get_status,popen,ini_alter,ini_restore,dl,openlog,syslog,readlink,symlink,popepassthru,stream_socket_server
~~~
~~~
expose_php = Off; #不會再header頭輸出PHP版本信息
display_errors = Off; #生產環境中,應該禁止錯誤提示
log_errors = On; #在關閉display_errors后能夠把錯誤信息記錄下來,便于查找服務器運行的原因
error_log = ''; #設置PHP錯誤日志存放的目錄。
~~~
- PHP
- PHP 核心架構
- PHP 生命周期
- PHP-FPM 詳解
- PHP-FPM 配置優化
- PHP 命名空間和自動加載
- PHP 運行模式
- PHP 的 Buffer(緩沖區)
- php.ini 配置文件參數優化
- 常見面試題
- 常用函數
- 幾種排序算法
- PHP - 框架
- Laravel
- Laravel 生命周期
- ThinkPHP
- MySQL
- 常見問題
- MySQL 索引
- 事務
- 鎖機制
- Explain 使用分析
- MySQL 高性能優化規范
- UNION 與 UNION ALL
- MySQL報錯:sql_mode=only_full_group_by
- MySQL 默認的 sql_mode 詳解
- 正則表達式
- Redis
- Redis 知識
- 持久化
- 主從復制、哨兵、集群
- Redis 緩存擊穿、穿透、雪崩
- Redis 分布式鎖
- RedisBloom
- 網絡
- 計算機網絡模型
- TCP
- UDP
- HTTP
- HTTPS
- WebSocket
- 常見幾種網絡攻擊方式
- Nginx
- 狀態碼
- 配置文件
- Nginx 代理+負載均衡
- Nginx 緩存
- Nginx 優化
- Nginx 配置 SSL 證書
- Linux
- 常用命令
- Vim 常用操作命令
- Supervisor 進程管理
- CentOS與Ubuntu系統區別
- Java
- 消息隊列
- 運維
- RAID 磁盤陣列
- 邏輯分區管理 LVM
- 業務
- 標準通信接口設計
- 業務邏輯開發套路的三板斧
- 微信小程序登錄流程
- 7種Web實時消息推送方案
- 用戶簽到
- 用戶注冊-短信驗證碼
- SQLServer 刪除同一天用戶重復簽到
- 軟件研發完整流程
- 前端
- Redux
- 其他
- 百度云盤大文件下載
- 日常報錯記錄
- GIT
- SSL certificate problem: unable to get local issuer certificate
- NPM
- reason: connect ECONNREFUSED 127.0.0.1:31181
- SVN
- SVN客戶端無法連接SVN服務器,主機積極拒絕
- Python
- 基礎
- pyecharts圖表
- 對象
- 數據庫
- PySpark
- 多線程
- 正則
- Hadoop
- 概述
- HDFS