博文结构
反向代理
proxy缓存

nginx优化

一.反向代理(案例)

1、反向代理(Reverse Proxy)方式是指以代理服务器来接受客户端的连接请求,然后将请求转发给网络上的 web 服务器(可能是 apache、nginx、tomcat、iis 等),并将从 web 服务器上得到的结果返回给请求连接的客户端,此时代理服务器对外就表现为一个服务器。

Nginx反向代理及缓存使用_第1张图片

如图可以看出:反向代理服务器代理网站 Web 服务器接收 Http 请求,对请求进行转发。而且nginx作为反向代理服务器可以根据用户请求的内容把请求转发给后端不同的web服务器,例如静动分离,再例如在 nginx 上创建多个虚拟主机,这样就成功的做到了在浏览器中输入不同域名(url)的时候访问后端的不同 web 服务器或 web 群集。

2、反向代理的作用
①保护网站安全:任何来自 Internet 的请求都必须先经过代理服务器

Nginx反向代理及缓存使用_第2张图片

②通过配置缓存功能加速 Web 请求:可以缓存真实 Web 服务器上的某些静态资源,减轻真实 Web 服务器的负载压力

Nginx反向代理及缓存使用_第3张图片

③实现负载均衡:充当负载均衡服务器均衡地分发请求,平衡集群中各个服务器的负载压力;

Nginx反向代理及缓存使用_第4张图片

  • 实验环境

Nginx反向代理及缓存使用_第5张图片

下载nginx软件包

192.168.222.128 nginx服务器
192.168.222.129 web
192.168.222.130 web

  • nginx服务器操作如下:
[root@localhost / ]#tar zxf ngx_cache_purge-2.3.tar.gz 
[root@localhost / ]#unzip nginx-sticky-module.zip
[root@localhost / ]#tar zxf nginx-1.14.0.tar.gz 
[root@localhost /]# yum -y install pcre-devel openssl-devel
[root@localhost /]#cd nginx-1.14.0/
[root@localhost nginx-1.14.0]#./configure --prefix=/usr/local/nginx   \
--user=nginx --group=nginx --with-http_stub_status_module --with-http_realip_module --with-http_ssl_module  \
--with-http_gzip_static_module --http-client-body-temp-path=/var/tmp/nginx/client  \
--http-fastcgi-temp-path=/var/tmp/nginx/fcgi  \
--with-pcre  --add-module=../ngx_cache_purge-2.3  \
--add-module=../nginx-sticky-module  \
--with-http_flv_module  \
[root@localhost nginx-1.14.0]# make && make install
[root@localhost nginx-1.14.0]# ln -s /usr/local/nginx/sbin/nginx  /usr/local/sbin/
[root@localhost nginx-1.14.0]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: [emerg] getpwnam("nginx") failed
\\可以看到报错,没有创建nginx用户
[root@localhost nginx-1.14.0]# useradd -s /sbin/nologin -M nginx
[root@localhost nginx-1.14.0]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: [emerg] mkdir() "/var/tmp/nginx/client" failed (2: No such file or directory)
nginx: configuration file /usr/local/nginx/conf/nginx.conf test failed
\\报错显示没有创建目录
[root@localhost nginx-1.14.0]# mkdir -p /var/tmp/nginx/client 
[root@localhost nginx-1.14.0]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@localhost nginx-1.14.0]# nginx
[root@localhost ~]# netstat -anpt | grep nginx
tcp        0      0 0.0.0.0:80              0.0.0.0:           LISTEN      9886/nginx: master  
[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf 
\\在http中添加如下
 upstream backend {
        sticky;
        server 192.168.222.129:80 weight=1 max_fails=2 fail_timeout=10s;    
        server 192.168.222.130:80 weight=1 max_fails=2 fail_timeout=10s;
}
\\
weight : 轮询权值也是可以用在 ip_hash 的,默认值为 1
max_fails :允许请求失败的次数,默认为 1。当超过最大次数时,返回 proxy_next_upstream模块定义的错误。
fail_timeout : 有两层含义,一是在 10s 时间内最多容许 2 次失败;二是在经历了 2 次失败以后,10s 时间内不分配请求到这台服务器。

\\在location添加,可以把以前的localtion注释掉
 location / {
        proxy_pass http://backend;
}
[root@localhost /]# nginx -s reload  //重载nginx服务
  • 模块解释
    nginx-sticky-module 模块:这个模块的作用是通过 cookie 黏贴的方式将来自同一个客户端(浏览器)的请求发送到同一个后端服务器上处理,这样一定程度上可以解决多个 backend servers 的 session 同步的问题 —— 因为不再需要同步,而 RR 轮询模式必须要运维人员自己考虑 session 同步的实现。

load-balance 其它调度方案:

  • 轮询(默认) : 每个请求按时间顺序逐一分配到不同的后端服务器,如果后端某台服务器,故障系统被自动剔除,使用户访问不受影响。Weight 指定轮询权值,Weight 值越大,分配到的访问机率越高,主要用于后端每个服务器性能不均的情况下。
    ip_hash : 每个请求按访问 IP 的 hash 结果分配,这样来自同一个 IP 的访客固定访问一个后端服务器,有效解决了动态网页存在的 session 共享问题。当然如果这个节点不可用了,会发到下个节点,而此时没有 session 同步的话就注销掉了。
    least_conn :请求被发送到当前活跃连接最少的 realserver 上。会考虑 weight 的值。
    url_hash : 此方法按访问 url 的 hash 结果来分配请求,使每个 url 定向到同一个后端服务
    器,可以进一步提高后端缓存服务器的效率。Nginx 本身是不支持 url_hash 的,如果需要使用这种调度算法,必须安装 Nginx 的 hash 软件包 nginx_upstream_hash 。
    fair :这是比上面两个更加智能的负载均衡算法。此种算法可以依据页面大小和加载时间长短智能地进行负载均衡,也就是根据后端服务器的响应时间来分配请求,响应时间短的优先分配。Nginx 本身是不支持 fair 的,如果需要使用这种调度算法,必须下载 Nginx 的upstream_fair 模块。

  • web
[root@localhost ~]# yum -y install httpd
[root@localhost ~]# echo aaaaaaaaaa > /var/www/html/index.html 
[root@localhost ~]# systemctl start httpd
  • 另一台web
[root@localhost ~]# yum -y install httpd
[root@localhost ~]# echo bbbbbbbbbbb > /var/www/html/index.html 
[root@localhost ~]# systemctl start httpd
  • 测试效果如下
[root@localhost ~]# curl 127.0.0.1
aaaaaaaaaaaaaaa
[root@localhost ~]# curl 127.0.0.1
bbbbbbbbbbbb
[root@localhost ~]# curl 127.0.0.1
aaaaaaaaaaaaaaa
[root@localhost ~]# curl 127.0.0.1
bbbbbbbbbbbb
\\可以看到nginx服务器把请求分别给两台web
  • 可以编辑nginx启动脚本
[root@localhost ~]# vim /etc/init.d/nginx 
#!/bin/bash
#chkconfig: 2345 99 20
#description: Nginx Service Control Script
PROG="/usr/local/nginx1.10/sbin/nginx"
PIDF="/usr/local/nginx1.10/logs/nginx.pid"
case "$1" in
        start)
           netstat -anplt |grep ":80" &> /dev/null && pgrep "nginx" &> /dev/null
           if [ $? -eq 0 ]
           then
              echo "Nginx service already running."
           else
              $PROG -t &> /dev/null
              if [ $? -eq 0 ] ; then
                $PROG
                echo "Nginx service start success."
              else
                $PROG -t
              fi
           fi
        ;;
        stop)
           netstat -anplt |grep ":80" &> /dev/null && pgrep "nginx" &> /dev/null
           if [ $? -eq 0 ]
           then
                kill -s QUIT $(cat $PIDF)
                echo "Nginx service stop success."
            else
                echo "Nginx service already stop"
            fi
        ;;
        restart)
                $0 stop
                $0 start
        ;;
        status)
           netstat -anplt |grep ":80" &> /dev/null && pgrep "nginx" &> /dev/null
           if [ $? -eq 0 ]
           then
                echo "Nginx service is running."
           else
                echo "Nginx is stop."
           fi
        ;;
        reload)
           netstat -anplt |grep ":80" &> /dev/null && pgrep "nginx" &> /dev/null
           if [ $? -eq 0 ]
           then
                $PROG -t &> /dev/null
              if [ $? -eq 0 ] ; then
                kill -s HUP $(cat $PIDF)
                echo "reload Nginx config success."
              else
                $PROG -t
              fi
           else
                echo "Nginx service is not run."
           fi   
        ;; 
        *)
                echo "Usage: $0 {start|stop|restart|reload}"
                exit 1
        esac
[root@localhost ~]#  chmod +x /etc/init.d/nginx 
[root@localhost ~]# chkconfig --add nginx
[root@localhost ~]# service nginx start
Nginx service start success.
[root@localhost ~]# service nginx status
Nginx service is running.

二.nginx缓存使用

缓存也就是将 js、css、image 等静态文件从后端服务器缓存到 nginx 指定的缓存目录下,既可以减轻后端服务器负担,也可以加快访问速度,但这样缓存及时清理成为了一个问题,所以需要 ngx_cache_purge 这个模块来在过期时间未到之前,手动清理缓存。
nginx的web缓存功能只要就是由proxy_cache、fastcgi_cache指令集和相关指令集完成:

proxy_cache:负责反向代理缓存后端服务器的静态内容;
fastcgi_cache:主要用来处理fastcgi动态进程缓存;

  • 在nginx主配置文件中添加如下
[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf
…………    //省略部分内容
log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"'
                      '"$upstream_cache_status"';            //记录缓冲命中率,注意这是一个整段,所以只在末尾有一个分号
//以上内容原本已经存在,只需添加最后一行即可!
    access_log  logs/access.log  main;
     proxy_buffering on;        //代理时,开启缓冲后端服务器的响应
    proxy_temp_path /usr/local/nginx/proxy_temp;        //定义缓存临时目录
    proxy_cache_path /usr/local/nginx/proxy_cache levels=1:2 keys_zone=my-cache:100m inactive=600m max_size=2g;
//定义缓存目录,具体信息已在配置文件外部进行说明
…………    //省略部分内容
        location ~/purge(/.*) {                 //定义缓存清除策略
                allow 127.0.0.1;
                allow 192.168.222.0/24;
                deny all;
                proxy_cache_purge my-cache $host$1$is_args$args;
        }

        location / {
                proxy_pass http://lzj;            //请求转向lzj定义的服务器列表
                proxy_redirect off;            指定是否修改被代理服务器返回的响应头中的 location 头域跟 refresh 头域数值
#例如:
 设置后端服务器“Location”响应头和“Refresh”响应头的替换文本。 假设后端服务器返回的
 响应头是 “Location: http://localhost:8000/two/some/uri/”,那么指令proxy_redirect  
# http://localhost:8000/two/ http://frontend/one/;将把字符串改写为 “Location: 
# http://frontend/one/some/uri/”。                               
                proxy_set_header Host $host;    //允许重新定义或者添加发往后端服务器的请求头
#Host 的含义是表明请求的主机名,nginx 反向代理服务器会向后端真实服务器发送请求,
#并且请求头中的host字段重写为proxy_pass指令设置的服务器。因为nginx作为反向代理使
#用,而如果后端真实的服务器设置有类似防盗链或者根据 http 请求头中的 host 字段来进行
#路由或判断功能的话,如果反向代理层的nginx不重写请求头中的host字段,将会导致请求失败。                                
                proxy_set_header X-Real-IP $remote_addr;
                                //web 服务器端获得用户的真实 ip 但是,实际上要获得用户的真实 ip,也可以通过下面的X-Forward-For

                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                                #后端的 Web服务器可以通过 X-Forwarded-For 获取用户真实 IP,X_Forward_For 字段
#表示该条 http 请求是有谁发起的?如果反向代理服务器不重写该请求头的话,那么后端
#真实服务器在处理时会认为所有的请求都来自反向代理服务器,如果后端有防护策略
#的话,那么机器就被封掉了。因此,在配置用作反向代理的 nginx 中一般会增加两条配置,以便修改 http 的请求头部
                proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
                                #增加故障转移,如果后端的服务器返回 502、504、执行超时等错误,
#自动将请求转发到upstream 负载均衡池中的另一台服务器,实现故障转移。
                proxy_cache my-cache;
                add_header Nginx-Cache $upstream_cache_status;
                proxy_cache_valid 200 304 301 302 8h;
                proxy_cache_valid 404 1m;
                proxy_cache_valid any 1d;
                proxy_cache_key $host$uri$is_args$args;
                expires 30d;
        }
[root@localhost ~]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
//检测配置文件没有问题
[root@localhost ~]# nginx -s reload            //重新加载nginx配置文件
  • 访问如下:

Nginx反向代理及缓存使用_第6张图片

刷新一下显示如:

Nginx反向代理及缓存使用_第7张图片

  • 清除缓存

Nginx反向代理及缓存使用_第8张图片

  • 再重新访问192.168.222.128时,如下:可以看到已经清楚缓存了

Nginx反向代理及缓存使用_第9张图片