之前讲到了Nginx服务是目前主流的http服务和反向代理服务器,以及如何安装nginx服务,Nginx服务中有非常强大的优化性能,如反向解析、日志切割、IO多路复用、隐藏版本、rewrite等等,这些优化大都是在nginx主配置文件/usr/local/nginx/conf/nginx.conf中配置的,所以需要熟悉了解nginx的配置文件。
[root@TTTTT ~]# vim /usr/local/nginx/conf/nginx.conf
#user nobody; #运行用户,若编译时未指定则默认为 nobody,一般改为nginx
worker_processes 4; #工作进程数量,可配置成服务器内核数 *2,如果网站访问量不大,一般设为1就够用了
#error_log logs/error.log; #错误日志文件的位置
#pid logs/nginx.pid; #PID 文件的位置
events {
use epoll; #使用 epoll 模型,2.6及以上版本的系统内核,建议使用epoll模型以提高性能
worker_connections 4096; #每个进程处理 4096 个连接
}
如提高每个进程的连接数还需执行“ulimit -n 65535”命令临时修改本地每个进程可以同时打开的最大文件数。
在Linux平台上,在进行高并发TCP连接处理时,最高的并发数量都要受到系统对用户单一进程同时可打开文件数量的限制(这是因为系统为每个TCP连接都要创建一个socket句柄,每个socket句柄同时也是一个文件句柄)。
可使用ulimit -a命令查看系统允许当前用户进程打开的文件数限制。/etc/security/limits.conf
epoll是Linux内核为处理大批句柄而作改进的poll,是Linux下多路复用IO接口select/poll的增强版本,它能显著的减少程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率。
若工作进程数为 8,每个进程处理 4 096 个连接,则允许 Nginx 正常提供服务的连接数已超过 3 万个(4096×8=32768),当然具体还要看服务器硬件、网络带宽等物理条件的性能表现。
使用“http { }”界定标记,包括访问日志、HTTP 端口、网页目录、默认字符集、连接保持,以及后面要讲到的虚拟 Web 主机、PHP 解析等一系列设置,其中大部分配置语句都包含在子界定标记“server { }”内。
http {
##文件扩展名与文件类型映射表
include mime.types;
##默认文件类型
default_type application/octet-stream;
##日志格式设定
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
##访问日志位置
#access_log logs/access.log main;
##支持文件发送(下载)
sendfile on;
##此选项允许或禁止使用socket的TCP_CORK的选项(发送数据包前先缓存数据),此选项仅在使用sendfile的时候使用
#tcp_nopush on;
##连接保持超时时间,单位是秒
#keepalive_timeout 0;
keepalive_timeout 65;
##gzip模块设置,设置是否开启gzip压缩输出
#gzip on;
##Web 服务的监听配置
server {
##监听地址及端口
listen 80;
##站点域名,可以有多个,用空格隔开
server_name www.kgc.com;
##网页的默认字符集
charset utf-8;
##根目录配置
location / {
##网站根目录的位置/usr/local/nginx/html
root html;
##默认首页文件名
index index.html index.php;
}
##内部错误的反馈页面
error_page 500 502 503 504 /50x.html;
##错误页面配置
location = /50x.html {
root html;
}
}
}
日志格式设定:
r e m o t e a d d r 与 remote_addr与 remoteaddr与http_x_forwarded_for用以记录客户端的ip地址;
$remote_user:用来记录客户端用户名称;
$time_local: 用来记录访问时间与时区;
$request: 用来记录请求的url与http协议;
$status: 用来记录请求状态;成功是200;
$body_bytes_sent :记录发送给客户端文件主体内容大小;
$http_referer:用来记录从哪个页面链接访问过来的;
$http_user_agent:记录客户浏览器的相关信息;
通常web服务器放在反向代理的后面,这样就不能获取到客户的IP地址了,通过$remote_add拿到的IP地址是反向代理服务器的iP地址。反向代理服务器在转发请求的http头信息中,可以增加x_forwarded_for信息,用以记录原有客户端的IP地址和原来客户端的请求的服务器地址。
location常见配置指令,root、alias、proxy_pass
root——根路径配置,用于访问文件系统,在匹配到location配置的URL路径后,指向root配置的路径,并把location配置路径附加到其后。
alias——别名配置,用于访问文件系统,在匹配到location配置的URL路径后,指向alias配置的路径。
proxy_pass——反向代理配置,用于代理请求,适用于前后端负载分离或多台机器、服务器负载分离的场景,在匹配到location配置的URL路径后,转发请求到proxy_pass配置的URL,是否会附加location配置路径与proxy_pass配置的路径后是否有"/“有关,有”/"则不附加。
前文提到,Nginx服务有非常强大的性能,那如何实现这些性能需要在配置文件中进行编辑。
隐藏Nginx版本号可以有效避免安全漏洞,不同版本的Nginx服务都有不同的安全漏洞,所以为了避免这些漏洞被利用攻击,所以我们一般都会把版本号给隐藏。
修改配置Nginx隐藏版本号:
[root@TTTTTTT nginx-1.22.0]# vim /usr/local/nginx/conf/nginx.conf
修改完成后重新加载nginx服务
Nginx 运行时进程需要有用户与组的支持,以实现对网站文件读取时进行访问控制。
Nginx 默认使用 nobody 用户账号与组账号,一般也要进行修改。
当Nginx将网页数据返回给客户端后,可设置缓存的时间,以方便在日后进行相同内容的请求时直接返回,避免重复请求,加快了访问速度。
[root@TTTTTTT nginx-1.22.0]# vim /usr/local/nginx/conf/nginx.conf
http {
……
server {
……
location / {
root html;
index index.html index.htm;
}
##########新添加##########
location ~ \.(gif|jpg|jepg|png|bmp\ico)$ { #location 以图片作为缓存对象
root html;
expires 1d; #指定缓存时间为1天(s=秒m=分钟h=小时)
}
##########################
}
}
修改完之后可以在/usr/local/nginx/html的目录下放入照片可以查看,改文件的缓存时间为86400秒,即一天:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ufMJ3fwM-1658674946030)(https://s2.loli.net/2022/07/24/CyJREGaWeH2UzKP.png)]
web服务器会出现大量的访问日志和错误日志,所以我们要对日志进行切割,方便管理人员的查询,一些并不重要的记录,可以规定日志中不显示这些。
#创建一个新的脚本作为周期计划任务来进行日志切割
[root@TTTTTTT html]# vim /root/fenge.sh
#!/bin/bash
#显示前一天的时间
day=$(date -d "-1 day" "+%Y%m%d")
#创建日志文件目录
nginx_logs="/var/log/nginx"
nginx_path="/usr/local/nginx/logs/nginx/pid"
#移动并重命名日志文件
mv /usr/local/nginx/logs/access.log ${nginx_logs}/access.logs_$day
#重建新日志文件
kill -USR1 $(cat $nginx_path)
#删除30天之前的日志文件
find $nginx_path -mtime +30 -exec rm -rf {} \;
[root@TTTTTTT html]# chmod 777 /root/fenge.sh
#添加计划任务
[root@TTTTTTT html]# crontab -e
#每天1点自动执行脚本
0 1 * * * /root/fenge.sh
如上图所示,这样同一天的日志信息就会被放在同一个文档中,便于作业。
http协议中有一个keepAlive模式,它告诉web服务器在处理完一个请求后保持这个TCP链接的打开状态。若接收到来自同一客户端的其他请求,服务端会利用这个未被关闭的链接,而不需要再建立一个链接。
而在一段时间内始终保持打开的状态,它们会在这段时间内占用资源,当占用资源过多时,就会影响服务的性能。所以需要为这个保持链接的时间做一个限制,当链接超过这个时间,就会使链接超时并自动断开链接。
[root@TTTTTTT ~]# vim /usr/local/nginx/conf/nginx.conf
http {
……
#指定TCP三次握手的时间,nginx默认是65秒;第二个参数180秒,指定响应头keepalivetimeout中的time,能够让一些浏览器主动关闭链接,没有这个参数nginx不会发送keep-alive响应头(可选)
keepalive_timeout 65 180;
#等待客户端发送请求头的超时时间,超时则发送408错误
client_header_timeout 80;
#设置客户端发送请求体的超时时间
client_body_timeout 80;
……
}
在高并发的场景中,需要启动更多的nginx进程来保证快速响应,以便处理用户的请求,避免造成栓塞。
#首先需要查看cpu的核数
[root@TTTTTTT ~]# cat /proc/cpuinfo |grep -c "physical id"
4 #表示4核
[root@TTTTTTT ~]# vim /usr/local/nginx/conf/nginx.conf
1
2 user nginx nginx;
3 worker_processes 2; #使用线程/进程数,修改为核数相同或2倍
4 worker_cpu_affinity 01 10; #设置上一条设置中的每个进程由不同的cpu处理,如若上一条设置是4的话,则此条数值则为0001 0010 0100 1000以此类推
nginx的ngx_http_gzip_module压缩模块提供对文件内容压缩的功能。允许nginx服务器将输出内容在发送客户端之前进行压缩,以节约网络带宽,提升用户的访问体验,该模块默认已经安装。
在主配置文件中加入相应的压缩功能参数对压缩性能进行优化:
[root@TTTTTTT ~]# vim /usr/local/nginx/conf/nginx.conf
http {
……
gzip on; #取消注释,开启gzip压缩功能
gzip_min_length 1k; #最小压缩文件大小
gzip_buffers 4 64k; #压缩缓冲区,大小为4个64k缓冲区
gzip_http_version 1.1; #压缩版本,默认1.1
gzip_comp_level 6; #压缩比例,1最小,速度最快
gzip_vary on; #支持前端缓存服务器存储压缩页面
gzip_types text/plain text/javascript application/x-javascript text/css text/xml application/xmlapplication/xml+rss image/jpg image/jpeg image/png image/gif application/x-httpd-php application/javascriptapplication/json; #压缩类型,表示哪些网页文档启用压缩功能
……
}
[root@TTTTTTT html]# vim index.html #网页中插入图片
<html>
<head>
</head>
<body>
<img src="1.jpg"/>
</body>
</html>
[root@TTTTTTT html]# nginx -s reload
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2vFIMlGV-1658674946031)(https://s2.loli.net/2022/07/24/eKn6TuAobryhmPx.png)]
防止其他的网站大量使用自己网站里的一些图片,流量跑的是自己的网站,造成带宽的浪费,防止图片被盗用。
[root@TTTTTTT ~]# vim /usr/local/nginx/conf/nginx.conf
http {
……
server {
……
#表示以jpg、gif、swf结尾的文件
location ~* \.(jpg|gif|swf)$ {
#valid_referers:设置信任的网站,可以正常使用图片
#none:允许没有http_refer的请求访问资源(根据referer的定义,它的作用是指示一个请求是从哪里链接过来的,如果直接在浏览器的地址栏中输入一个资源的URL地址,那么这种请求是不会包含referer字段的)
#blocked:允许不是http://开头的,不带协议的请求访问资源
#*.XXX.com:只允许来自指定域名的请求访问资源
valid_referers none blocked *.XXX.com XXX.com;
#如果链接的来源域名不在valid_referer所列出的列表中,$invalid_referer为ture,则重写或返回403页面
if ( $invalid_referer ) {
rewrite ^/ http://www.XXX.com/error.jpg;
#return 403
}
}
}
}
除了以上优化以外,nginx还有很多别的进阶版的优化,如I/O多路复用,错误也个性化,访问控制,流量监控,基于外部的端口、进程监控,stubstatus模块监控,虚拟目录,负载均衡,动静分离,反向代理等等,留到下一章再说。
END