一、Nginx
Nginx 是开源、高性能、高可靠的 Web 和反向代理服务器,而且支持热部署,几乎可以做到 7 * 24 小时不间断运行,即使运行几个月也不需要重新启动,还能在不间断服务的情况下对软件版本进行热更新。
对HTTP并发连接的处理能力高,单台物理服务器可支持30000~50000个并发请求。
2、 Nginx和Apache的差异
Apache: 创建多个进程或线程,而每个进程或线程都会为其分配cpu和内存(线程要比进程小的多,所以worker支持比perfork高的并发),并发过大会榨干服务器资源。
Nginx: 采用单线程来异步非阻塞处理请求(管理员可以配置Nginx主进程的工作进程的数量),不会为每个请求分配cpu和内存资源,节省了大量资源,同时也减少了大量的CPU的上下文切换。所以才使得Nginx 支持更高的并发。
| Nginx | Apache |
|---|---|
| nginx是一个基于事件的web服务器 | apache是一个基于流程的服务器 |
| 所有请求都由一个线程处理 | 单个线程处理单个请求 |
| nginx避免子进程的概念 | apache是基于子进程的 |
| nginx类似于速度 | apache类似于功率 |
| nginx在内存消耗和连接方面比较好 | apache在内存消耗和连接上没有提高 |
| nginx在负载均衡方面表现较好 | 当流量到达进程极限时,apache将拒绝新的连接。 |
| nginx不支持IBMI和openvms一样的os | apache支持更多的os |
| nginx只具有核心功能 | apache提供了比nginx更多的功能 |
| nginx的性能和可伸缩性不依赖于硬件 | apache依赖于cpu和内存等硬件组件 |
| Nginx支持热部署 | Apache不支持热部署 |
3、Nginx和Apache的优缺点比较
(1)nginx相对于apache的优点∶
- 轻量级,同样起web服务,比apache占用更少的内存及资源
- 抗并发,nginx处理请求是异步非阻塞的,而apache是阻塞型的在高并发下,nginx能保持低资源低消耗高性能
- 高度模块化的设计,编写模块相对简
- 支持热部署,平滑升级
(2)apache相对于nginx的优点∶
- Rewrite比nginx的rewrite强大 (rewrite的主要功能就是实现统一资源定位符URL的跳转)
- 模块多,基本想到的都可以找到
- 少bug, nginx的bug相对较多
- 超稳定
- Nginx处理动态请求是弱项,动态请求要Apache去做。
总结:一般来说,需要性能的web服务,用Nginx. 如果不需要性能只求稳定,那就Apache。Nginx处理动态请求是弱项,一般动态请求要Apache去做,Nginx只适处理静态网页或反向代理。
4、Nginx的进程
Apache和Nginx的默认端口都是80,如果其中一个已经启动了,那么再启动另一个会报错。如果想要同时使用,可以修改其中一个的端口号。
Nginx有两个进程:
master process:主进程(守护进程),用来管理工作进程。
worker process:工作进程,用来处理用户的请求。
二、Nginx优化服务
优化一:打开长连接配置
通常Nginx作为代理服务,负责分发客户端的请求,那么建议开启HTTP长连接,用户减少握手的次数,降低服务器损耗,具体如下:
upstream xxx {
# 长连接数
keepalive 32;
# 每个长连接提供的最大请求数
keepalived_requests 100;
# 每个长连接没有新的请求时,保持的最长时间
keepalive_timeout 60s;
}
优化二、开启零拷贝技术
零拷贝这个概念,在大多数性能较为不错的中间件中都有出现,例如Kafka、Netty等,而Nginx中也可以配置数据零拷贝技术
零拷贝读取机制与传统资源读取机制的区别:
传统方式:硬件-->内核-->用户空间-->程序空间-->程序内核空间-->网络套接字
零拷贝方式:硬件-->内核-->程序内核空间-->网络套接字
从上述这个过程对比,很轻易就能看出两者之间的性能区别。
sendfile on; # 开启零拷贝机制
优化三、更改进程数
在高并发场景,需要启动更多的Nginx进程以保证快速响应,以处理用户的请求,避免造成阻塞
cat /proc/cpuinfo | grep -c "physical id" #查看cpu核数
ps aux | grep nginx #查看nginx主进程中包含几个子进程
vim /usr/local/nginx/conf/nginx.conf
worker_processes 2; #修改为核数相同或者2倍
worker_cpu_affinity 01 10; #设置每个进程由不同cpu处理,进程数配为4时0001 0010 0100 1000
systemctl restart nginx
优化四、配置网页压缩
Nginx的ngx_http_gzip_module压缩模块提供对文件内容压缩的功能
允许Nginx服务器将输出内容在发送客户端之前进行压缩,以节约网站带宽,提升用户的访问体验,默认已经安装
可在配置文件中加入相应的压缩功能参数对压缩性能进行优化
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,前端如果是squid2.5请使用1.0)
gzip_comp_level 6; #压缩比率 1:压缩比最小,速度最快;9:压缩比最大,传输速度最快,但处理也最慢,也比较的消耗CPU资源
gzip_vary on; #支持前端缓存服务器存储压缩页面
gzip_types text/plain text/javascript application/x-javascript text/css text/xml application/xml application/xml+rss image/jpg image/jpeg image/png image/gif application/x-httpd-php application/javascript application/json; #压缩类型,表示哪些网页文档启用压缩功能
......
}
cd /usr/local/nginx/html
先将game.jpg文件传到/usr/local/nginx/html目录下
vim index.html
......
<img src="game.jpg"/> #网页中插入图片
</body>
</html>
systemctl restart nginx
在Linux系统中,打开火狐浏览器,右击点查看元素
选择 网络 ---> 选择 HTML、WS、其他
访问 http://192.168.80.10 ,双击200响应消息查看响应头中包含 Content-Encoding: gzip
优化五、配置防盗链
在企业网站服务中,一般都要配置防盗链功能,以避免网站内容被非法盗用,造成经济损失,也避免了不必要的带宽浪费。
Nginx 的防盗链功能也非常强大,在默认情况下,只需要进行很简单的配置,即可实现防盗链处理。
配置盗链网站
切换到站点目录
cd /usr/local/nginx/html
配置首页文件,图片盗用Web源主机中的图片资源
vim index.html
<html>
<body>
<h1>test</h1>
<img src="http://www.apple.com/a.png"/>
</body>
</html>
添加IP和域名的映射关系
echo "192.168.132.6 www.djq.com" >> /etc/hosts
echo "192.168.132.7 www.123.com" >> /etc/hosts
在盗图网站主机上进行浏览器查看
设置防盗链
vim /usr/local/nginx/conf/nginx.conf
http {
......
server {
......
不是由djq.com域名请求的图片资源,重写到盗链图片error.png
location ~* .(jpg|gif|swf)$ {
root html;
expires 1d;
valid_referers none blocked *.djq.com djq.com;
if ( $invalid_referer ) {
rewrite ^/ http://www.djq.com/error.png;
}
}
......
}
}
systemctl restart nginx
优化六、fpm参数优化
vim /usr/local/php/etc/php-fpm.conf
pid = run/php-fpm.pid
vim /usr/local/php/etc/php-fpm.d/www.conf
--96行--
pm = dynamic #fpm进程启动方式,动态的
--107行--
pm.max_children=20 #fpm进程启动的最大进程数
--112行--
pm.start_servers = 5 #动态方式下启动时默认开启的进程数,在最小和最大之间
--117行--
pm.min_spare_servers = 2 #动态方式下最小空闲进程数
--122行--
pm.max_spare_servers = 8 #动态方式下最大空闲进程数
kill -USR2 `cat /usr/local/php/var/run/php-fpm.pid` #重启php-fpm
netstat -anpt | grep 9000
优化七、nginx之系统内核参数优化
默认的Linux内核参数考虑的是最通用的场景,这明显不符合用于支持高并发访问的Web服务器的定义,所以需要修改Linux内核参数,使得Nginx可以拥有更高的性能。
以下配置都可以在/etc/sysctl.conf配置,可以用sysctl -p生效****
· net.ipv4.tcp_max_tw_buckets
对于tcp连接,当服务端和客户端通信完成之后状态就会变成timewait,假如某台服务器非常繁忙,连接数非常多的话,那么这个值就会越来越大。
就应该设置一个数值,当超过这个数值,系统就会删除最早的连接。
centos7中可以用命令sysctl -a|grep tw_buckets来查看它的值。
sysctl -a|grep tw_buckets
net.ipv4.tcp_max_tw_buckets = 8192 #我的默认值为8192
查看time_wait:
ss -an
· net.ipv4.tcp_tw_recycle = 1
该参数的作用是快速回收timewait状态的连接,上面是删除,但是回收的话就可以再利用,和下面的参数一起使用:
net.ipv4.tcp_tw_reuse =1 //这个参数表示重新用于新的连接。\
· net.ipv4.tcp_syncookies = 1
tcp三次握手中,客户端向服务器发起syn请求,服务端收到后,也会给客户端发起syn请求同时连带ack确认,假如客户端发送请求后直接断开连接和服务端的连接,不接收服务端发起的这个请求,服务端会重试多次,这个重试的过程会持续一段时间(通常高于30s),当这种状态连接量非常大时,服务器会消耗很大的资源,从而造成瘫痪。 正常的连接进不来,这种恶意的半连接行为叫做syn flood攻击。
开启该参数后,服务端接收客户端的ack后,再向客户端附送ack+syn之前会要求client在短时间内回应一个序号,如果客户端不能提供序号或者提供的序号不会,则认为不合法,不会发syn+ack给客户端,更不会重试。
· net.ipv4.tcp_max_syn_backlog
该参数定义系统能接受的最大半连接的tcp连接数,客户端发送了syn之后,服务端会记录以下,该参数决定最多记录多少个,在centos7中,默认256,当有syn flood攻击时,这个数值太小则很容易导致服务器瘫痪,实际上此时并没有消耗太多服务器的资源,所以可以适当调大一些,比如30000。
· net.ipv4.tcp_syn_retries
该参数适用于客户端,它定义发起syn的最大重试次数,默认为6,建议为2。
· net.ipv4.tcp_synack_retries
该参数适用于服务端,它定义发起syn+ack的最大重试次数,默认为5,建议改为2,可以适当预防syn flood攻击。
· net.ipv4.ip_local_port_range
该参数定义端口范围,系统默认保留端口为1024及以下,以上部分为自定义端口,这个参数适用于客户端。当客户端和服务端建立连接时,不如说访问服务端的80端口,客户端随机开启了一个端口和服务端发起连接,默认为32768-61000,建议调整1050-61000.
· net.ipv4.tcp_fin_timeout
tcp连接的状态中,客户端上有一个时fin-wait-2状态,它是状态变迁为timewait前一个状态。该参数定义不属于任何进程的超时时间,默认值为60,建议调整为6.
· net.ipv4.tcp_keepalive_time
tcp连接状态里,有一个时established状态,只有在这个状态下,客户端和服务端才能通信。正常情况下,当通信完毕,客户端或服务端会告诉对方要关闭连接,此状态就会变成timewait,如果客户端没有告诉服务端,并且服务端也没有告诉客户端关闭的话(比如,客户端断网),此时需要改参数来判定。就需要每隔一段时间去发一个探测包去确认。默认7200秒,建议设置30s。
· net.ipv4.tcp_keepalive_intvl
该参数和上面参数是一起的,服务端在规定时间内发起了探测,查看客户端是否在线,如果客户端没有却惹,此时服务端还不能认定为对方不在线,而是要尝试多次,该参数定义重新发送探测的时间,即第一次发现对方有问题后,过多久再次发起探测。默认为75,可以改为3秒。
· net.ipv4.tcp_keepalive_proves
该参数是上面两个参数的补充,之前规定了合适发起探测和探测多久后再次发起探测,但并没有定义一共探测几次才算结束。该参数定义了发起探测包的数量,默认为9,建议设置为2。
优化八、设置连接超时时间
HTTP有一个KeepAlive模式,它告诉web服务器在处理完一个请求后保持这个TCP连接的打开状态。若接收到来自同一客户端的其它请求,服务端会利用这个未被关闭的连接,而不需要再建立一个连接。
KeepAlive 在一段时间内保持打开状态,它们会在这段时间内占用资源。占用过多就会影响性能。
在企业网站中,为了避免同一个客户长时间占用连接,造成资源浪费,可设置相应的连接超时参数,实现控制连接访问时间。可以修改配置文件 nginx.conf,设置 keepalive_timeout超时。
vim /usr/local/nginx/conf/nginx.conf
http {
......
keepalive_timeout 65 180; 设置连接超时时间
client_header_timeout 80;
client_body_timeout 80;
......
}
重启服务
systemctl restart nginx
优化九、日志分割
随着Nginx运行时间的增加,产生的日志也会逐渐增加,为了方便掌握Nginx的运行状态,需要时刻关注Nginx日志文件。太大的日志文件对监控是一个大灾难,不便于分析排查,需要定期的进行日志文件的切割
编写脚本来管理分割日志
vim fenge.sh
#!/bin/bash
# nginx日志分割,按时间分割
#显示前一天的时间
day=$(date -d "-1 day" "+%Y%m%d")
#旧日志文件目录
logs_path="/var/log/nginx"
#nginx进程的PID
pid_path="/usr/local/nginx/logs/nginx.pid"
#如果旧日志目录不存在,则创建日志文件目录
[ -d $logs_path ] || mkdir -p $logs_path
#将日志移动到旧日志目录,并重命名日志文件
mv /usr/local/nginx/logs/access.log ${logs_path}/tt.com-access.log-$day
#重建新日志文件
kill -USR1 $(cat $pid_path)
#删除30天之前的日志文件
find $logs_path -mtime +30 -exec rm -rf {} ;
赋予执行权限,执行脚本。查看日志文件目录。
chmod +x /usr/local/nginx/nginx_log.sh
/opt/fenge.sh
ls /var/log/nginx/ //旧日志文件已被移动到设置好的目录
apple.com-access.log-20221003
ls /usr/local/nginx/logs/ //已重建新日志文件
access.log error.log nginx.pid
编写计划任务,每天定点执行
crontab -e
0 1 * * * fenge.sh
复制代码
优化十、修改缓存时间
修改nginx的配置文件
vim /usr/local/nginx/conf/nginx.conf
http {
......
server {
......
location / {
root html;
index index.html index.htm;
}
#加入新的 location,以图片作为缓存对象
location ~* .(gif|jpg|jepg|bmp|ico)$ {
root html;
expires 1d; #指定缓存时间,1天
#访问测试
Linux系统中,打开火狐浏览器,访问 www.nmixx.com/1.jpg
右击点查看元素
选择 网络 ---> 选择 HTML、WS、其他
双击响应消息查看响应头中包含 Cahce-Control:max-age=86400 表示缓存时间是 86400 秒。
也就是缓存一天的时间,一天之内浏览器访问这个页面,都是用缓存中的数据,而不需要向 Nginx 服务器重新发出请求,减少了服务器的使用带宽。
优化十一、隐藏响应头中的版本号
修改配置文件
vim /usr/local/nginx/conf/nginx.conf
http {
include mime.types;
default_type application/octet-stream;
server_tokens off; 添加这一行,关闭版本号
......
}
---------重启服务
systemctl restart nginx
---------访问测试
curl -I http://www.xxx.com
复制代码
优化十二、修改响应头中的版本号
修改源码文件
vim /opt/nginx-1.22.0/src/core/nginx.h
#define NGINX_VERSION "2.2.2" 修改版本号
#define NGINX_VER "IIS" NGINX_VERSION 修改服务器类型
重新编译安装
cd /opt/nginx-1.22.0/
./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_stub_status_module
make && make install
将配置文件中的版本号启用
vim /usr/local/nginx/conf/nginx.conf
http {
include mime.types;
default_type application/octet-stream;
server_tokens on;
......
}
systemctl restart nginx
curl -I http://IP地址或域名
优化十三、修改运行用户与组
方法一:
./configure \
--prefix=/usr/local/nginx \ 指定nginx的安装路径
--user=nginx \ 指定用户名(运行用户)
--group=nginx \ 指定组名
--with-http_stub_status_module 启用http_stub_status_module模块以支持状态统计
方法二:
修改配置文件文件
vim /usr/local/nginx/conf/nginx.conf
user nginx nginx; 取消注释,修改用户为nginx,组为nginx
重启服务
systemctl restart nginx
查看是否修改成功。可以看到主进程由root创建,子进程由nginx创建
ps aux | grep nginx
三、总结
1、Nginx与httpd以静态页面处理+动态页面转发的功能上比较类似,但是Nginx优势在于“1.抗高频发,2.轻量级,3.新能稳定”
2、Nginx的配置文件中包含的模块从全局--->具体的匹配的URL,分为一下几种全局模块。
在此模块中定义的内容,会生效于所有配置。
a.http
应用于用户以http 的方式来访问Nginx的整个过程,
b.server服务
适用于通过端口、ip、域名的访问方式的请求
c.location——>www.nmixx.com/index.html
Nginx与Apache两者的核心区别在于
Apache是同步多进程模型,一个连接对应一个进程,二Nginx是异步的,多个连接(上万级别)可以对应一个进程