Nginx网站服务优化与防盗链

227 阅读14分钟

一、Nginx

Nginx 是开源、高性能、高可靠的 Web 和反向代理服务器,而且支持热部署,几乎可以做到 7 * 24 小时不间断运行,即使运行几个月也不需要重新启动,还能在不间断服务的情况下对软件版本进行热更新。

对HTTP并发连接的处理能力高,单台物理服务器可支持30000~50000个并发请求。

2、 Nginx和Apache的差异

Apache: 创建多个进程或线程,而每个进程或线程都会为其分配cpu和内存(线程要比进程小的多,所以worker支持比perfork高的并发),并发过大会榨干服务器资源。

Nginx: 采用单线程来异步非阻塞处理请求(管理员可以配置Nginx主进程的工作进程的数量),不会为每个请求分配cpu和内存资源,节省了大量资源,同时也减少了大量的CPU的上下文切换。所以才使得Nginx 支持更高的并发。

NginxApache
nginx是一个基于事件的web服务器apache是一个基于流程的服务器
所有请求都由一个线程处理单个线程处理单个请求
nginx避免子进程的概念apache是基于子进程的
nginx类似于速度apache类似于功率
nginx在内存消耗和连接方面比较好apache在内存消耗和连接上没有提高
nginx在负载均衡方面表现较好当流量到达进程极限时,apache将拒绝新的连接。
nginx不支持IBMI和openvms一样的osapache支持更多的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是异步的,多个连接(上万级别)可以对应一个进程