Loading

nginx_php-fpm调优优化

一、php参数配置

1、phpini的基本设置
(1)safe_mode  这份的配置采用默认的
(2)disable_functions  在默认的基础上,加上eval()函数
(3)expose_php = off
(4)register_globals和magic_quotes_gpc参数都在php5.4.0后被移除了
(5)错误提示以及日志部分采用默认的就行,现在大部分使用的都是框架,
查看框架的错误日志更方便
2、php参数设置
max_execution_time  = 300	//脚本运行的最长时间,超出规定时间,脚本会自动杀死这个请求,为了能上传大文件,所以这个值设置的大一些。
memory_limit = 128M			//每个脚本使用的最大内存
max_inpit_time = 300		//每个脚本等待输入数据的最长时间
upload_max_filesize = 20M	//上传文件的最大许可大小
allow_url_fopen = off		//禁止打开远程地址
post_max_size = 20M			//post上传的大小,要>=upload_max_filesize
;cgi.fix_pathinfo=1			//默认打开,目前高版本的php已经避免了这个漏洞,php-fpm的security.limit_extensions 默认值早就是 .php了。

二、php-fpm参数设置

1、设置子进程数,增加并发量
log_level = notice		//notice级别的日志,默认的
rlimit_files = 4048		//调整最大打开文件数量
process.max = 150		// 最大子进程,设置成和max_children一样就行
pm = dynamic			//pm表示使用那种方式,有两个值可以选择,就是static(静态)或者dynamic(动态)
pm.max_children = 150	//静态方式下开启的php-fpm进程数量,假如一个进程30M,4G内存的话最大为:4048/30 = 135,取150。在动态方式下他限定php-fpm的最大进程数(这里要注意pm.max_spare_servers的值只能小于等于pm.max_children)。
pm.start_servers = 20	//动态方式下的起始php-fpm进程数量。
pm.min_spare_servers = 6	//动态方式空闲状态下的最小php-fpm进程数量。
pm.max_spare_serveres = 30   //动态方式空闲状态下的最大php-fpm进程数量。

需要注意数值大小:min_spare_servers ≤ start_servers ≤ max_spare_servers ≤ max_children

如果dm设置为static,那么其实只有pm.max_children这个参数生效。系统会开启参数设置数量的php-fpm进程。

如果dm设置为dynamic,4个参数都生效。系统会在php-fpm运行开始时启动pm.start_servers个php-fpm进程,然后根据系统的需求动态在pm.min_spare_servers和pm.max_spare_servers之间调整php-fpm进程数。

如果你的内存比较大,那么设置静态的pm = static,这个时候,起作用的只有max_children参数,初始的时候就有max_children个进程,刚开始一个php-fpm进程只占用3M左右内存,我们4GB的机器按照一个进程20M计算,可以设置max_children 为200或者150。如果是专门的php服务器,建议是设置为静态的,性能最佳。

2、防止频繁出现502错误
process_control_timeout = 20		//php-fpm给子进程分配的时间间隔
request_terminate_timeout = 320s	//表示等待320秒后,结束那些没有自动结束的php脚本,以释放占用的资源。设置320s主要是因为php的程序运行时间是300s,所以对于php-fpm来说,这个值应该是大于php脚本规定的运行时间的(因为php脚本的运行可能还会带有mysql服务或者其他的一些服务,这个参数是杀掉这个进程,包括着纯php脚本以及其他服务)。

#表示在emergency_restart_interval所设值内出现SIGSEGV或者SIGBUS错误的php-cgi进程数如果
#超过emergency_restart_threshold个php-fpm就会优雅重启。这两个选项一般保持默认值
emergency_restart_threshold = 30
emergency_restart_interval = 60s	//一分钟内出现30次上述信号即重启php-fpm

pm.max_requests = 1000				//每一个子进程的最大请求服务数量,如果超过了这个值,该子进程会被自动重启。设置很小的话,可能会频繁的重启,遇到502的问题。设置很大的话,可能遇到内存泄漏或者请求转发错误。
3、php-fpm中的慢日志设置

php-fpm也可以开启慢日志,记录执行速度比较慢的php请求

request_slowlog_timeout = 2   # 记录超过2s的请求
slowlog = /var/log/php-fpm/www-slow.log	#慢日志路径
#用sort/uniq命令分析汇总php-fpm慢日志:
grep -v “^$” www.log.slow.tmp | cut -d ” ” -f 3,2 | sort | uniq -c | sort -k1,1nr | head -n 50

sort: 对单词进行排序
uniq -c: 显示唯一的行,并在每行行首加上本行在文件中出现的次数
sort -k1,1nr: 按照第一个字段,数值排序,且为逆序
head -10: 取前10行数据

4、php-fpm中的backlog是干啥的?
listen.backlog = 1024 #2的n次幂

如果worker进程不够用,master进程会prefork更多进程,如果prefork达到了pm.max_children上限,worker进程又全都繁忙,这时master进程会把请求挂起到连接队列backlog里,而backlog默认值是511,除了加大pm.max_children,调整backlog也是有必要的。

也就说这个backlog是在优化高并发的时候必须要设置的,这个值的大小和fpm的qps也有关。backlog太大,fpm处理不过来照样会报错504(超时)。这个对于目前的机器来说,我设置的max_children = 150,然而backlog的默认值是511,所以在短期内是完全够用的,不过也可以在php-fpm.conf里面显式的制定backlog的值,比如制定:listen.backlog = 1024 #2的n次幂

三、nginx设置

1、nginx中的一些层级关系

一般打开nginx配置文件,会发现有http,server,location等,那么他们的层级关系是什么样的呢?

答案是: 一个http里面可以有多个server,一个server里面可以有多个location。

我们配置的时候,各个server共用的部分可以配置在http模块里面。每个server自己特有的一些部分,按照各自的需求配置在server模块里面。同样的,对于location是分的更细的,按照每个server的每个location需求来配置。

其次是如果在conf.d文件夹下有其他的配置文件,那么我们的nginx.conf就是公用的配置文件了,一些公用的部分都可以配置在nginx.conf文件中,各个站点特殊的配置就放在conf.d文件下。

参考:
nginx短篇(4):模块、配置指令、块之间的关系

2、nginx.conf 实例及解释
user www-data;
worker_processes auto;					#自动检测设置为CPU的核数,最优值取决于许多因素,包括(但不限于)CPU核的数量、存储数据的硬盘数量及负载模式
worker_rlimit_nofile 65535;				#worker进程的最大打开文件数限制,规避"too many open files"
error_log   /var/log/nginx/error.log;
include /etc/nginx/modules-enabled/*.conf;
pid /run/nginx.pid;

events {
	worker_connections  10240;			#子进程最大连接数,总连接数:worker_processes * worker_connections
	use epoll;					#使用epoll模型
}

http {
	include       mime.types;			#文件扩展名与文件类型映射表
	default_type  application/octet-stream; 	#这个类型会让浏览器认为响应是普通的文件流,并提示用户下载文件

	log_format  main  '$remote_addr $host $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_accept_language" "$request_time" '
                      '"$upstream_response_time" "$upstream_addr" "$upstream_status" "$http_x_real_ip" "$proxy_add_x_forwarded_for"';	#记录都有哪些变量可以记录到log_format

	sendfile        on; 	 			#立即将数据从磁盘读到OS缓存
	tcp_nopush      on;  				#告诉nginx在一个数据包里发送所有头文件,而不一个接一个的发送
	tcp_nodelay     on;  				# 告诉nginx不要缓存数据,而是一段一段的发送
    
	access_log 		off;			#是否将存储访问日志。关闭这个选项可以让读取磁盘IO操作更快
	error_log /var/log/nginx/error.log crit; 	#只能记录严重的错误
	
	keepalive_timeout  30; 				#客户端分配keep-alive链接超时时间,服务器将在这个超时时间过后关闭链接
	client_header_timeout 30;			#设置请求头的超时时间
	client_body_timeout 30;				#设置请求体的超时时间
	reset_timeout_connection on;			#告诉nginx关闭不响应的客户端连接
	send_timeout 10; 				#指定客户端的响应超时时间
	
	limit_conn_zone $binary_remote_addr zone=addr:5m; 	#设置用于保存各种key(比如当前连接数)的共享内存的参数。5m就是5兆字节,这个值应该被设置的足够大以存储(32K*5)32byte状态或者(16K*5)64byte状态。
	limit_conn addr 100;				#为给定的key设置最大连接数。这里key是addr,我们设置的值是100,也就是说我们允许每一个IP地址最多同时打开有100个连接。
	
	types_hash_max_size 2014;
	
	#resolver xxx;					#用于解析上游服务器名称的名称服务器配置到地址中
	gzip_static on;					#压缩资源前,先查询是否有预先压缩过的资源,nginx就不用再压缩
	gzip  on;					#启用压缩的形式发送数据,减少我们发送的数据量
	gzip_disable "MSIE [1-6]\.(?!.*SV1)";		#指定的客户端禁用gzip功能,IE6
	gzip_http_version 1.1;
	gzip_vary off;
	gzip_min_length 1000;				#小于1000字节不压缩,影响处理请求速度
	gzip_comp_level 4;  				#数据的压缩等级,9是最慢但是压缩比最大的
	gzip_proxied off;				#允许或者禁止压缩基于请求和响应的响应流 off|any
	gzip_buffers 16 8k;

	gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/hero-res;	#设置需要压缩的数据格式

	client_max_body_size 20m;  			#设置网页上传文件的最大值,和php.ini中的上传设置保持一致
	server_names_hash_max_size 2048;  		#保存服务器名字的hash表
	
	open_file_cache max=100000 inactive=20s; 	#打开缓存的同时也指定了缓存最大数目,以及缓存的时间,不活动超过20秒后清除掉
	open_file_cache_valid 30s; 			#在open_file_cache中指定检测正确信息的间隔时间
	open_file_cache_min_uses 2; 			#定义了open_file_cache中指令参数不活动时间期间里最小的文件数
	open_file_cache_errors on; 			#指定了当搜索一个文件时是否缓存错误信息,也包括再次给配置中添加文件

	include /etc/nginx/client.conf;
	include /etc/nginx/conf.d/*.conf;
}

(1)worker_rlimit_nofile

更改worker进程的最大打开文件数限制。

查看当前进程可以打开的文件数:

ulimit-n			
//结果:65535

查看当前系统可以打开的最大文件数:

cat /proc/sys/fs/file-max
813544

(2)log_format中的内容

参考官网:https://nginx.org/en/docs/http/ngx_http_core_module.html#var_status

remote_addr:	对应客户端的地址
remote_user:	是请求客户端请求认证的用户名,如果没有开启认证模块的话是值为空。
time_local:		表示nginx服务器时间
request:		表示request请求头的行
status:			表示response的返回状态
body_bytes_sent:表示从服务端返回给客户端的body数据大小
http_referer:	表示请求的上一级页面
http_user_agent:表示agent信息
http_x_forwarded_for:会记录每一级请求中信息
3、对于conf.d文件夹中的配置

配置实例代码

server{
	listen IP:80;
    server_name localhost;
    access_log  /var/log/nginx/access.log;  #access日志

    fastcgi_intercept_errors on; #支持nginx404重定向

    index index.php index.html  index.htm;

    root /product/ucool/production/manage/htdocs/backend/web/;

	send_timeout 15;
	#客户端与服务器建立连接后发送request body的超时时间(小于keepalive_timeout)
	client_body_timeout 20;
    #客户端向服务器发送一个完整的request header的超时时间(小于keepalive_timeout)
	client_header_timeout 20;
	fastcgi_connect_timeout         300;    #指定连接到后端FastCGI的超时时间
	fastcgi_send_timeout            300;    #指定向FastCGI传送请求的超时时间
	fastcgi_read_timeout            300;    #指定接收FastCGI应答的超时时间
	fastcgi_buffer_size 64k;               #指定读取FastCGI应答第一部分需要用多大的缓冲区
	fastcgi_buffers 4 64k;                 #定本地需要用多少和多大的缓冲区来缓冲FastCGI的应答请求


	location ~* ^.+\.(git|svn|sql|bak|old|rar|tgz|7z|bz2|tar|idea)$ {
		return 404;
	}
	location ~ \.php$ {
                fastcgi_pass unix:/var/run/php/php5.6-fpm.sock;
                fastcgi_index index.php;
                fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
                include fastcgi_params;
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
	}
		location ~ /\.git { deny all; }
}

关于send_timeout

send_timeout 15;
#客户端与服务器建立连接后发送request body的超时时间(小于keepalive_timeout)
client_body_timeout 20;
#客户端向服务器发送一个完整的request header的超时时间(小于keepalive_timeout)
client_header_timeout 20;

这几个参数最好是再小一些,包括keepalive_timeout,小一些的话,能处理更多的有效请求,有利于提升nginx的处理性能,大佬们的设置如下:

client_body_timeout 12;
client_header_timeout 12;
keepalive_timeout 15;
send_timeout 10;
4、保存编辑之后检查配置文件的正确性

(1)检查配置文件是否正确

# sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

返回successful并且没有报错信息的话,说明配置文件里面的语法是没问题的,如果报错了那就是语法出错了,导致配置无法正常读取。

(2)检查子级配置文件是否正确

nginx -t -c /etc/nginx/conf.d/xxx.conf

四、影响程序超时的参数

php.ini中有max_execution_time 参数。
php-fpm中有request_terminate_timeout参数
nginx.conf中有 fastcgi_connect_timeout 等参数。
1、关于php和php-fpm超时时间的设置

首先是max_execution_time 这个值限定了脚本的最大执行时间,但是仅限于php脚本,对于脚本中的流操作和数据库操作等耗费的时间是不算进去的。而php-fpm的request_terminate_timeout 代表单个请求的超时中止时间,并不会受其他脚本影响,定义10s结束,那么10s就准时结束该php脚本的运行。所以配置超时时间的时候,request_terminate_timeout 可以比max_execution_time 稍微大一些。

还有一种说法,在服务器正常运行的时候,php-fpm.conf中的request_terminate_timeout 会覆盖php.ini中的max_execution_time,所以request_terminate_timeout 的值更代表我们对于脚本执行时间的预期。如果服务器性能足够好,可以设置request_terminate_timeout = 0代表永不超时。

当程序运行时间大于规定的参数的时候,php-fpm会终止该php子进程。

2、nginx中的超时设置

nginx的fastcgi_connect_timeout 操作影响的是ningx的超时,一般来说,如果是php或者php-fpm超时,那么报错502 Bad Gateway(网关错误) 。如果是nginx超时的话,报错是:504 Gateway Time-out (网关超时) ,到时候我们可以根据这个报错信息来定位问题。一般来说,为防止频繁的出现超时错误,设置fastcgi_connect_timeout 相关时间为300s是合适的。

假如设置fastcgi_read_timeout=10,test.php执行时间100秒,则10秒后webserver会关闭和PHP的连接。也就是说当程序运行时间大于规定的参数的时候,webserver会关闭和PHP的连接,出现超时错误。所以这个fastcgi的超时时间最好是和php-fpm中的request_terminate_timeout 保持一致。

3、nginx中的keepalive_timeout

keepalive_timeout参数是一个请求完成之后还要保持连接多久,不是请求时间多久,目的是保持长连接,减少创建连接过程给系统带来的性能损耗,类似于线程池,数据库连接池。

五、模板

nginx配置模板,以供参考

server{
	listen 80;
        listen 443 ssl;
	server_name yyszy.xx.com;

        charset utf-8;
	add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;	
        ssl_certificate     /etc/nginx/key/xx.com.pem;
        ssl_certificate_key /etc/nginx/key/xx.com.key;
        ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers         HIGH:!aNULL:!MD5;
        ssl_session_cache   shared:SSL:10m;
        ssl_session_timeout 10m;
        set_real_ip_from 0.0.0.0/0;
        real_ip_header X-Forwarded-For;
    
        large_client_header_buffers 4 16k;
        client_max_body_size 30m;
        client_body_buffer_size 128k;
    
        proxy_connect_timeout 1000;
        proxy_read_timeout 1000;
        proxy_send_timeout 1000;
        proxy_buffer_size 64k;
        proxy_buffers   8 64k;
        proxy_busy_buffers_size 128k;
        proxy_temp_file_write_size 64k;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_ignore_client_abort on;	

	access_log /var/log/nginx/access-yyszy-user.log main;

	location / {
		proxy_pass http://172.16.0.132:6280;
	}

        location ^~ /bmsserv/ {
                proxy_pass http://172.16.0.132:6235/;
        }
}

参考:

https://www.jb51.net/article/95041.htm
http://www.codebaoku.com/tech/tech-yisu-689816.html
posted @ 2022-05-31 16:09  萝卜青菜~  阅读(329)  评论(0编辑  收藏  举报