博主接手了一個祖傳項目,用php的laravel框架開發的,Php本身是同步的特性,對高並發天生不支持,加上laravel框架本身性能也比較差(經過接口基准測試得出),還有之前的開發同學主要是做前端,后端的代碼並不注重性能,能用即可,項目即將大規模應用,因此急需對其進行性能調優。
參考資料:https://www.jianshu.com/p/b7c12a824044?from=groupmessage
6個大方向:
(1)php本身的性能優化,主要圍繞編譯緩存、運行時內存、php-fpm配置
其中編譯緩存(開啟opcache)、運行時內存主要是調整php.ini配置文件,如下:
memory_limit=4094M
[opcache]
opcache.enable=1
opcache.memory_consumption=128
opcache.validate_timestamps=0
zend_extension="opcache.so"
php-fpm是可以看做nginx與php服務的中間件,nginx請求php-fpm執行php腳本,nginx是多進程的,因此php-fpm的進程數量、每個進程允許的內存占用都是需要根據機器的硬件資源進行最優分配。
參考示例:2核4GB情況下,php-fpm的進程數可以設置為:
pm = dynamic 自動伸縮fpm進程數量
pm.max_children = 50 最大進程數量
接口tps提升2.5倍,效果非常明顯。
(2)Laravel框架調優,主要是路由緩存、關閉debug、提升日志打印級別
其中路由緩存的命令是:php artisan route:cache
修改.env文件:
APP_DEBUG=false APP_LOG_LEVEL=warn
路由緩存對高並發時接口的錯誤率降低非常有效,自從博主開啟了路由緩存,即便tps比較低,也不會出現接口返回錯誤了。
(3)nginx調優,目前主流的部署結構是nginx+php-fpm來啟動一個php服務,那么nginx的配置對性能的影響也是至關重要的
nginx配置如下(主要是最開始的幾個auto配置,不要使用默認的值):
user root;
worker_processes auto;
worker_cpu_affinity auto;
error_log nginx.log notice;
worker_rlimit_nofile 51200;
events
{
use epoll;
worker_connections 51200;
}
http
{
include mime.types;
default_type application/octet-stream;
log_format main
'{"@timestamp":"$time_iso8601",'
'"host":"$hostname",'
'"server_ip":"$server_addr",'
'"client_ip":"$remote_addr",'
'"xff":"$http_x_forwarded_for",'
'"domain":"$host",'
'"url":"$uri",'
'"referer":"$http_referer",'
'"args":"$args",'
'"upstreamtime":"$upstream_response_time",'
'"responsetime":"$request_time",'
'"request_method":"$request_method",'
'"status":"$status",'
'"size":"$body_bytes_sent",'
'"request_body":"$request_body",'
'"request_length":"$request_length",'
'"protocol":"$server_protocol",'
'"upstreamhost":"$upstream_addr",'
'"file_dir":"$request_filename",'
'"http_user_agent":"$http_user_agent"'
'}';
access_log /var/log/nginx/access.log main;
gzip on;
gzip_buffers 4 8k;
gzip_comp_level 2;
gzip_http_version 1.1;
gzip_min_length 1;
gzip_proxied any;
gzip_types text/plain text/xml text/css text/javascript application/javascript application/json application/x-javascript application/xml application/xml+rss application/vnd.syncml+xml;
gzip_vary on;
gzip_disable "MSIE [1-6] \.";
# 配置classmind2負載可用節點
upstream classmind2_servers{
server 172.24.128.3:8084;
}
server
{
listen 8060;
server_name classmind2.com;
location / {
proxy_pass http://classmind2_servers;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 90;
proxy_send_timeout 180;
proxy_read_timeout 180;
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
proxy_temp_file_write_size 256k;
}
access_log /var/log/nginx/classmind2serverLog.log main;
}
}
(4)業務代碼中,ORM的使用帶來的性能降低,可以在評估過后(性能重要還是業務編碼方便重要),決定是否采用DB庫直連數據庫的方式。
(5)開發同學編寫的代碼導致性能問題,特別是逐條查詢這種,調整成批量查詢,還有接口的設計要遵循接口設計的六大原則:單一職責原則、里氏替換原則、依賴倒置原則、接口隔離原則、迪米特法則、開閉原則。
(6)web服務大部分情況下都是無狀態服務,條件允許的情況下,可以通過nginx做反向代理服務器(負載均衡)部署多個服務來提升接口的TPS。
