博主接手了一个祖传项目,用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。