Nginx反向代理缓存服务器构建

Nginx反向代理缓存服务器构建

代理服务可简单的分为正向代理和反向代理:

正向代理:

用于代理内部网络对 Internet 的连接请求(如 VPN/NAT),客户端指定代理服务器,并将本来要直接发送给目标Web服务器的HTTP请求先发送到代理服务器上, 然后由代理服务 器去访问 Web 服务器, 并将 Web 服务器的 Response 回传给客户端

反向代理:

与正向代理相反,如果局域网向Internet提供资源,并让Internet上的其他用户可以 访问局域网内资源, 也可以设置一个代理服务器, 它提供的服务就是反向代理. 反向代理服 务器接受来自 Internet 的连接,然后将请求转发给内部网络上的服务器,并将 Response 回传给 Internet 上请求连接的客户端

一、nginx 反向代理:Web 服务器的调度器

1、反向代理方式

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

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

2、反向代理的作用
(1)保护网站安全:

任何来自 Internet 的请求都必须先经过代理服务器
Nginx反向代理缓存服务器构建插图(1)

(2)通过配置缓存功能加速 Web 请求:

可以缓存真实 Web 服务器上的某些静态资源,减轻真 实 Web 服务器的负载压力
Nginx反向代理缓存服务器构建插图(2)

(3)实现负载均衡:

充当负载均衡服务器均衡地分发请求,平衡集群中各个服务器的负载压力
Nginx反向代理缓存服务器构建插图(3)

二、什么是 nginx:

1、nginx简介

Nginx 是一款轻量级的网页服务器、反向代理器以及电子邮件代理服务器。因它的稳定性、 丰富的功能集、示例配置文件和低系统资源的消耗而闻名。Nginx(发音同 engine x),它是 由俄罗斯程序员 Igor Sysoev 所开发的。起初是供俄国大型的门户网站及搜索引擎 Rambler (俄语:Рамблер)使用。此软件 BSD-like 协议下发行,可以在 UNIX、GNU/Linux、 BSD、Mac OS X、Solaris,以及 Microsoft Windows 等操作系统中运行

2、Nginx 的应用现状:

Nginx 已经在俄罗斯最大的门户网站── Rambler Media(www.rambler.ru)上运行,同时俄 罗斯超过 20%的虚拟主机平台采用 Nginx 作为反向代理服务器

在国内,已经有 淘宝、新浪博客、新浪播客、网易新闻、六间房、56.com、Discuz!、水木 社区、豆瓣、YUPOO、海内、迅雷在线 等多家网站使用 Nginx 作为 Web 服务器或反向代 理服务器

3、Nginx 的核心特点:
(1)跨平台:

Nginx 可以在大多数 OS 编译运行,而且也有 Windows 的版本

(2)配置异常简单:

非常容易上手

(3)非阻塞、高并发连接:

官方测试能够支撑 5 万并发连接,在实际生产环境中跑到 2~3 万并发连接数。(这得益于 Nginx 使用了最新的 epoll 模型)

注:

对于一个 Web 服务器来说,首先看一个请求的基本过程:建立连接—接收数据—发送数据, 在系统底层看来 :上述过程(建立连接—接收数据—发送数据)在系统底层就是读写事件。

如果采用阻塞调用的方式,当读写事件没有准备好时,那么就只能等待,当前线程被挂起,等事件准备好了,才能进行读写事件。

如果采用非阻塞调用的方式:事件马上返回,告诉你事件还没准备好呢,过会再来吧。过一 会,再来检查一下事件,直到事件准备好了为止,在这期间,你就可以先去做其它事情,然 后再来看看事件好了没。虽然不阻塞了,但你得不时地过来检查一下事件的状态,你可以做 更多的事情了,但带来的开销也是不小的。非阻塞调用指在不能立刻得到结果之前,该调用 不会阻塞当前线程

(4)事件驱动:

通信机制采用 epoll 模型,支持更大的并发连接

阻塞通过不断检查事件的状态来判断是否进行读写操作,这样带来的开销很大,因此就有 了异步非阻塞的事件处理机制。这 种机制让你可以同时监控多个事件,调用他们是非阻塞的, 但可以设置超时时间,在超时时间之内,如果有事件准备好了,就返回。这种机制解决了上 面阻塞调用与非阻塞调用的两个问题。

以 epoll 模型为例:

当事件没有准备好时,就放入 epoll(队列)里面。如果有事件准备好了, 那么就去处理;当事件没有准备好时,才在 epoll 里面等着。这样,我们就可以并发处理大 量的并发了,当然,这里的并发请求,是指未处理完的请求。线程只有一个,所以同时能处 理的请求当然只有一个了,只是在请求之间进行不断地切换而已,切换也是因为异步事件未 准备好,而主动让出的。这里的切换是没有任何代价,你可以理解为循环处理多个准备好的 事件。

多线程方式相比,这种事件处理方式是有很大的优势的,不需要创建线程,每个请求占用的 内存也很少,没有上下文切换, 事件处理非常的轻量级,并发数再多也不会导致无谓的资 源浪费(上下文切换)。对于 apache 服务器,每个请求会独占一个工作线程,当并发数上到 几千时,就同时有几千的线程在处理请求了。这对操作系统来说,是个不小的挑战:因为线 程带来的内存占用非常大,线程的上下文切换带来的 cpu 开销很大,自然性能就上不 去, 从而导致在高并发场景下性能下降严重

总结:通过异步非阻塞的事件处理机制,Nginx 实现由进程循环处理多个准备好的事件,从 而实现高并发和轻量级

(5)Master/Worker 结构:

一个 master 进程,生成一个或多个 worker 进程
Nginx反向代理缓存服务器构建插图(4)
注:

Master-Worker 设计模式主要包含两个主要组件 Master 和 Worker,Master 维护着 Worker 队列,将请求下发到多个 Worker 并行执行,Worker 主要进行实际逻辑计算,并将结果返回 给 Maste

nginx 采用这种进程模型有什么好处?采用独立的进程,可以让互相之间不会影响,一个进 程退出后,其它进程还在工作,服务不会中断,Master 进程则很快重新启动新的 Worker进程。当然,Worker 进程的异常退出,肯定是程序有 bug 了,异常退出,会导致当前 Worker 上的所有请求失败,不过不会影响到所有请求,所以降低了风险

(6)内存消耗小:

处理大并发的请求内存消耗非常小。在 3 万并发连接下,开启的 10 个 Nginx 进程才消耗 150M 内存(15M*10=150M)

(7)内置的健康检查功能:

如果 Nginx 代理的后端的某台 Web 服务器宕机了,不会影响 前端访问

(8)节省带宽:

支持 GZIP 压缩,可以添加浏览器本地缓存的 Header 头

(9)稳定性高:

用于反向代理,宕机的概率微乎其微

三、Nginx+apache构筑 Web 服务器集群的负载均衡

nginx 配置反向代理

配置 nginx 作为反向代理和负载均衡,同时利用其缓存功能,将静态页面在 nginx 缓存,以达到降低后端服务器连接数的目的并检查后端 web 服务器的健康状况Nginx反向代理缓存服务器构建插图(5)

1、安装nginx

环境:

OS centos7.5
nginx 192.168.1.20
apache1 192.168.1.30
apache2 192.168.1.40
(1)安装 zlib-devel、pcre-devel 等依赖包
[root@nginx ~]# yum -y install gcc gcc-c++ make libtool zlib zlib-devel pcre pcre-devel opensll openssl-devel

注:

结合 proxy 和 upstream 模块实现后端 web 负载均衡

使用 proxy 模块实现静态文件缓存

结合 nginx 默认自带的 ngx_http_proxy_module 模块和ngx_http_upstream_module 模块实现后端服务器的健康检查,也可以使用第三方模块 nginx_upstream_check_module

使用 nginx-sticky-module 扩展模块实现 Cookie 会话黏贴(保持会话)

使用 ngx_cache_purge 实现更强大的缓存清除功能

上面提到的 2 个模块都属于第三方扩展模块,需要提前下好源码,然后编译时通过–add-moudle=src_path 一起安装

(2)安装nginx

添加nginx组

[root@nginx ~]# groupadd nginx

创建nginx的运行账户nginx,加入到nginx组中,不允许nginx直接登录系统

[root@nginx ~]# useradd -g nginx nginx -s /sbin/nologin

所需要的软件包

nginx-1.14.0.tar.gz

ngx_cache_purge-2.3.tar.gz

nginx-sticky-module.zip

软件链接

提取码:tfax

[root@nginx ~]# tar zxf nginx-1.14.0.tar.gz -C /usr/src/
[root@nginx ~]# tar zxf ngx_cache_purge-2.3.tar.gz -C /usr/src/
[root@nginx ~]# unzip nginx-sticky-module.zip -d /usr/src/
[root@nginx ~]# cd /usr/src/nginx-1.14.0/
[root@nginx nginx-1.14.0]# ./configure --prefix=/usr/local/nginx1.14 \
>  --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-proxy-temp-path=/var/tmp/nginx/proxy \
>  --http-fastcgi-temp-path=/var/tmp/nginx/fcgi --with-pcre --with-http_flv_module \
>  --add-module=/usr/src/nginx-sticky-module \
>  --add-module=/usr/src/ngx_cache_purge-2.3
[root@nginx nginx-1.14.0]# make && make install

注:nginx 的所有模块必须在编译的时候添加,不能再运行的时候动态加载

相关参数解释:

–with-http-stub-status-module:

通过网页监控nginx的状态

–with-http-realip-module:

获取客户端的真实IP地址

–with-http-ssl module:

开启nginx的加密传输功能

–with-httpgzipstaticmodule:

开启压缩功能

–http-client-body-temp-path=/var/tmp/nginx/client:

客户端访问数据临吁存放路径

–with-pcre:

支持正则匹配表达式

–add-module=/usr/src/ngx_cache_purge-2.3:

添加nginx的第三方模块语法为—add-module=第三方模块路径

–with-http flv module:

支持flv视频流

2、优化 nginx 程序的执行路径
[root@nginx nginx-1.14.0]# ln -s /usr/local/nginx1.14/sbin/nginx /usr/local/sbin/
[root@nginx nginx-1.14.0]# nginx -t
nginx: the configuration file /usr/local/nginx1.14/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/nginx1.14/conf/nginx.conf test failed

这里会报错,根据提示创建相应的目录即可

[root@nginx nginx-1.14.0]# mkdir -p /var/tmp/nginx/client
[root@nginx nginx-1.14.0]# chown -R nginx:nginx /var/tmp/nginx/
[root@nginx nginx-1.14.0]# nginx -t
nginx: the configuration file /usr/local/nginx1.14/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx1.14/conf/nginx.conf test is successful
3、编写nginx服务脚本
[root@nginx ~]# cat /etc/init.d/nginx 
#!/bin/bash 
# chkconfig: 2345 99 20 
# description: Nginx Service Control Script 
PROG="/usr/local/nginx1.14/sbin/nginx"
PIDF="/usr/local/nginx-1.14/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/nul
   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/nul
   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@nginx ~]# chmod +x /etc/init.d/nginx 
[root@nginx ~]# chkconfig --add nginx
[root@nginx ~]# chkconfig nginx on
[root@nginx ~]# /etc/init.d/nginx start
Nginx service start success.
[root@nginx ~]# netstat -anput | grep 80
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      6162/nginx: master

注:如果你想在已安装好的 nginx 上添加第三方模块,依然需要重新编译,但为了不覆盖你原有的配置,请不要 make install,而是直接拷贝可执行文件:

[root@localhost nginx-1.14.0]#./configure --add-module=…… #你的第三方模块

[root@localhost nginx-1.14.0]# make 后不要 make install,改为手动拷贝,先备份

[root@localhost nginx-1.14.0]# cp /usr/local/nginx-1.14/sbin/nginx /usr/local/nginx-1.14/sbin/nginx.bak

[root@localhost nginx-1.14.0]# cp objs/nginx /usr/local/nginx-1.14/sbin/nginx

四、开启nginx网页界面认证

1、安装httpd-tools软件包
[root@nginx ~]# yum -y install httpd-tools
2、使用htppasswd命令生成账号密码
[root@nginx ~]# /usr/bin/htpasswd -c /usr/local/nginx1.14/nginx.passwd admin
New password: 
Re-type new password: 
Adding password for user admin
3、添加配置文件:
[root@nginx ~]# vim /usr/local/nginx1.14/conf/nginx.conf
        location /auth {
            root   html;
            index  index.html index.htm;
            auth_basic  "提示语句";
            auth_basic_user_file  /usr/local/nginx1.14/nginx.passwd;
        }
4、创建文件夹及网页
[root@nginx ~]# mkdir /usr/local/nginx1.14/auth
[root@nginx ~]# cat /usr/local/nginx1.14/auth/index.html
This is a test file!
5、重载nginx,访问测试

[root@nginx ~]# nginx -s reload
Nginx反向代理缓存服务器构建插图(6)
输入用户名密码就可以访问了

五、配置 nginx 反向代理:反向代理+负载均衡+健康探测

查看 nginx 加载的模块

[root@nginx ~]# nginx -V
nginx version: nginx/1.14.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC) 
built with OpenSSL 1.0.2k-fips  26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx1.14 --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-proxy-temp-path=/var/tmp/nginx/proxy --http-fastcgi-temp-path=/var/tmp/nginx/fcgi --with-pcre --with-http_flv_module --add-module=/usr/src/nginx-sticky-module --add-module=/usr/src/ngx_cache_purge-2.3

nginx 的所有模块必须在编译的时候添加,不能再运行的时候动态加载

1、nginx-sticky-module 模块:

这个模块的作用是通过 cookie 黏贴的方式将来自同一个客户端(浏览器)的请求发送到同一个后端服务器上处理,这样一定程度上可以解决多个 backend servers 的 session 同步的问题 —— 因为不再需要同步,而 RR 轮询模式必须要运维人员自己考虑 session 同步的实现另外内置的 ip_hash 也可以实现根据客户端 IP 来分发请求,但它很容易造成负载不均衡的情况,而如果 nginx 前面有 CDN 网络或者来自同一局域网的访问,它接收的客户端 IP 是一样的,容易造成负载不均衡现象。nginx-sticky-module 的 cookie 过期时间,默认浏览器关闭就过期

这个模块并不合适不支持 Cookie 或手动禁用了 cookie 的浏览器,此时默认 sticky 就会切换成 RR。它不能与 ip_hash 同时使用

upstream backend {
        server 192.168.31.141:80 weight=1;
	        server 192.168.31.250:80 weight=1;
        sticky;
	}

配置起来超级简单,一般来说一个 sticky 指令就够了

相关信息可以查看官方文档

2、load-balance 其它调度方案:

这里顺带介绍一下 nginx 的负载均衡模块支持的其它调度算法:

轮询(默认):

每个请求按时间顺序逐一分配到不同的后端服务器,如果后端某台服务器宕机,故障系统被自动剔除,使用户访问不受影响。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 模块

3、负载均衡与健康检查:

严格来说,nginx 自带是没有针对负载均衡后端节点的健康检查的,但是可以通过默认自带的 ngx_http_proxy_module 模块和 ngx_http_upstream_module 模块中的相关指令来完成当后端节点出现故障时,自动切换到下一个节点来提供访问

修改配置文件:(vim /usr/local/nginx-1.14/conf/nginx.config)

# http模块下添加
upstream backend {
        server 192.168.1.30:80 max_fails=2 fail_timeout=10s;
        server 192.168.1.40:80 max_fails=2 fail_timeout=10s;
        sticky;
}
# location模块添加
        location / {
            root   html;
            index  index.html index.htm;
            proxy_pass http://backend;
        }
[root@nginx ~]# nginx -s reload
[root@nginx ~]# curl 127.0.0.1
apache1
[root@nginx ~]# curl 127.0.0.1
apache2
# 访问nginx服务器,nginx就代理了后端两台apache服务,并进行轮询

weight :

轮询权值也是可以用在 ip_hash 的,默认值为 1

max_fails :

允许请求失败的次数,默认为 1。当超过最大次数时,返回proxy_next_upstream 模块定义的错误

fail_timeout :

有两层含义,一是在 10s 时间内最多容许 2 次失败;二是在经历了 2 次 失败以后,10s 时间内不分配请求到这台服务器

4、nginx的proxy缓存的使用

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

proxy 模块中常用的指令是 proxy_pass 和 proxy_cache

nginx 的 web 缓存功能的主要是由 proxy_cache、fastcgi_cache 指令集和相关指令集完成, proxy_cache 指令负责反向代理缓存后端服务器的静态内容,fastcgi_cache 主要用来处理 FastCGI 动态进程缓存

在配置文件中添加修改:注:在添加文件前请查看文件中是否有,如果没有再添加

    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;
    proxy_buffering on;
    proxy_temp_path /usr/local/nginx1.14/proxy_temp;
    proxy_cache_path /usr/local/nginx1.14/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.1.0/24;
            deny all;
            proxy_cache_purge my-cache $host$1$is_args$args;
        }
    
        location / {
            root   html;
            index  index.html index.htm;
            proxy_pass http://backend;
            proxy_redirect off;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_next_upstream error timeout invalid_header http_500 http_502 http_504;
            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;
        }
[root@nginx ~]# nginx -s reload

相关选项说明:

proxy_buffering on:

代理的时候,开启或关闭缓冲后端服务器的响应

当开启缓冲时,nginx 尽可能快地从被代理的服务器接收响应,再将它存入缓冲区中

proxy_temp_path:

缓存临时目录。后端的响应并不直接返回客户端,而是先写到一个临 时文件中,然后被 rename 一下当做缓存放在 proxy_cache_path 。0.8.9 版本以后允许 temp 和 cache 两个目录在不同文件系统上(分区),然而为了减少性能损失还是建议把它们设成 一个文件系统上

proxy_cache_path:

设置缓存目录,目录里的文件名是 cache_key 的 MD5 值。 levels=1:2 keys_zone=my-cache:50m 表示采用 2 级目录结构,第一层目录只有一个字符,是 由levels=1:2设置,总共二层目录,子目录名字由二个字符组成。Web缓存区名称为my-cache, 内存缓存空间大小为 100MB,这个缓冲 zone 可以被多次使用。文件系统上看到的缓存文件 名类似于 /usr/local/nginx1.14/proxy_cache/c/29/b7f54b2df7773722d382f4809d65029c 。 inactive=600 max_size=2g 表示 600 分钟没有被访问的内容自动清除,硬盘最大缓存空间为 2GB,超过这个大学将清除最近最少使用的数据

proxy_cache:

用前面定义的缓存区 my-cache

proxy_cache_key:

定义如何生成缓存的键,设置 web 缓存的 key 值,nginx 根据 key 值 md5 哈希存储缓存

proxy_cache_valid:

为不同的响应状态码设置不同的缓存时间,比如 200、302 等正常结果 可以缓存的时间长点,而 404、500 等缓存时间设置短一些,这个时间到了文件就会过期, 而不论是否刚被访问过

add_header:

指令来设置 response header, 语法: add_header name value;

$upstream_cache_status:

这个变量来显示缓存的状态,我们可以在配置中添加一个 http 头来显示这一状态

$upstream_cache_status 包含以下几种状态:

MISS 未命中,请求被传送到后端

HIT 缓存命中

EXPIRED 缓存已经过期请求被传送到后端 

UPDATING 正在更新缓存,将使用旧的应答 

STALE 后端将得到过期的应答

expires:

在响应头里设置 Expires:或 Cache-Control:max-age,返回给客户端的浏览器缓存失 效时间

5、访问测试Nginx反向代理缓存服务器构建插图(7)

查看这个文件,里面就有了缓存文件

[root@nginx ~]# ll /usr/local/nginx1.14/proxy_cache/d/a0/
总用量 4
-rw-------. 1 nginx nginx 622 6月  11 11:22 d5bd6fad23957bb6e6023525d18aba0d

如果在缓存时间之内需要更新被缓存的静态文件怎么办呢,这时候就需要手动来清除缓存了

浏览器访问 192.168.1.20/purge/来清除缓存

备注:

  • purge 是 ngx_cache_pure 模块指令
  • index.html是要清除的缓存文件 URL 路径
    Nginx反向代理缓存服务器构建插图(8)

缓存数据已经没有了

[root@nginx ~]# ll /usr/local/nginx1.14/proxy_cache/d/a0/
总用量 0

六、开启gzip压缩输出,减少网络传输

    #keepalive_timeout 0;
    keepalive_timeout  65;

    gzip  on;
    gzip_comp_level 6;
    gzip_http_version 1.1;
    gzip_proxied any;
    gzip_min_length 1k;
    gzip_buffers 16 8k;
    gzip_types text/plain text/css text/javascript application/json application/javascript application/x-javascript application/xml;
     gzip_vary on;
     client_max_body_size   10m;
     client_body_buffer_size   128k;
     proxy_connect_timeout   75;
     proxy_send_timeout   75;
     proxy_read_timeout   75;
     proxy_buffer_size   4k;
     proxy_buffers   4 32k;
     proxy_busy_buffers_size   64k;
     proxy_temp_file_write_size  64k;
[root@nginx ~]# nginx -s reload

相关解释:

proxy_busy_buffers_size 64k:

高负荷下缓冲大小(默认大小是 proxy_buffers 指令设置单块缓冲大小的 2 倍)

proxy_temp_file_write_size 64k :

当缓存被代理的服务器响应到临时文件时,这个选项限制每次写临时文件的大小

gzip on :

开启 gzip 压缩输出,减少网络传输

gzip_min_length 1k:

置允许压缩的页面最小字节数,页面字节数从 header 头得 content-length 中进行获取。建议设置成大于 1k 的字节数,小于 1k 可能会越压越大

gzip_buffers 16 8k:

设置系统获取几个单位的缓存用于存储 gzip 的压缩结果数据流。16 8k 代表以8k 为单位,按照原始数据大小以 8k 为单位的16倍申请内存。如果没有设置,默认值是申请跟原始数据相同大小的内存空间去存储 gzip 压缩结果

gzip_http_version 1.1:

用于识别 http 协议的版本,早期的浏览器不支持 Gzip 压缩,用户 就会看到乱码,所以为了支持前期版本加上了这个选项,如果你用了 Nginx 的反向代理并 期望也 启用 Gzip 压缩的话,由于末端通信是 http/1.1,故请设置为 1.1

gzip_comp_level 6:

gzip 压缩比,1 压缩比最小处理速度最快,9 压缩比最大但处理速度最 慢(传输快但比较消耗 cpu)

gzip_types:

匹配 mime 类型进行压缩,无论是否指定”text/html”类型总是会被压缩的。 默认值: gzip_types text/html (默认不对 js/css 文件进行压缩)

压缩类型,匹配 MIME 类型进行压缩

不能用通配符 text/*

(无论是否指定)text/html 默认已经压缩 

设置哪压缩种文本文件可参考 conf/mime.types

gzip_proxied any:

Nginx 作为反向代理的时候启用,根据某些请求和应答来决定是否在对 代理请求的应答启用 gzip 压缩,是否压缩取决于请求头中的“Via”字段,指令中可以同时指 定多个不同的参数

意义如下:

off – 关闭所有的代理结果数据的压缩

expired – 启用压缩,如果 header 头中包含 “Expires” 头信息

no-cache – 启用压缩,如果 header 头中包含 “Cache-Control:no-cache” 头信息

no-store – 启用压缩,如果 header 头中包含 “Cache-Control:no-store” 头信息

private – 启用压缩,如果 header 头中包含 “Cache-Control:private” 头信息

no_last_modified – 启用压缩,如果 header 头中不包含 “Last-Modified” 头信息

no_etag – 启用压缩 ,如果 header 头中不包含 “ETag” 头信息

auth – 启用压缩 , 如果 header 头中包含 “Authorization” 头信息

any – 无条件启用压缩

gzip_vary on:

和 http 头有关系,加个 vary 头,给代理服务器用的,有的浏览器支持压缩,

有的不支持,所以避免浪费不支持的也压缩,所以根据客户端的 HTTP 头来判断,是否需要压缩

将httpd服务的网页制造大点,访问测试:
Nginx反向代理缓存服务器构建插图(9)

七、开启br压缩

[root@nginx ~]# tar zxf ngx_brotli.tar.gz -C /usr/src/
[root@nginx ~]# cd /usr/src/nginx-1.14.0/
1、使用nginx -V查看编译时的信息
[root@nginx nginx-1.14.0]# nginx -V
nginx version: nginx/1.14.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC) 
built with OpenSSL 1.0.2k-fips  26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx1.14 --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-proxy-temp-path=/var/tmp/nginx/proxy --http-fastcgi-temp-path=/var/tmp/nginx/fcgi --with-pcre --with-http_flv_module --add-module=/usr/src/nginx-sticky-module --add-module=/usr/src/ngx_cache_purge-2.3
2、进行编译

最后加上--add-module=/usr/src/ngx_brotli即可

[root@nginx nginx-1.14.0]# ./configure --prefix=/usr/local/nginx1.14 --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-proxy-temp-path=/var/tmp/nginx/proxy --http-fastcgi-temp-path=/var/tmp/nginx/fcgi --with-pcre --with-http_flv_module --add-module=/usr/src/nginx-sticky-module --add-module=/usr/src/ngx_cache_purge-2.3 --add-module=/usr/src/ngx_brotli
[root@nginx nginx-1.14.0]# make # 不要make install
3、将新的nginx命令文件替换旧的

替换前先做个备份

[root@nginx nginx-1.14.0]# mv /usr/local/nginx1.14/sbin/nginx /usr/local/nginx1.14/sbin/nginx.bak
[root@nginx nginx-1.14.0]# cp objs/nginx /usr/local/nginx1.14/sbin/
4、重启nginx
[root@nginx nginx-1.14.0]# nginx -s stop
[root@nginx nginx-1.14.0]# nginx
5、添加配置文件内容
[root@nginx ~]# vim /usr/local/nginx1.14/conf/nginx.conf
    #keepalive_timeout 0;
    keepalive_timeout  65;
    brotli on;
    brotli_types text/plain text/css text/xml application/xml application/json ;
    brotli_static off; 
    brotli_comp_level 11;
    brotli_buffers 16 8k;
    brotli_window 512k;
    brotli_min_length 20;
[root@nginx ~]# nginx -s reload

相关参数解释:

brotli_static off;

否允许查找预处理好的、以.br结尾的压缩 件,可inyon off always

brotli_comp_level 11;

压缩级别

brotli_buffers 16 8k;

读取缓冲区数量和大小

brotli_window 512k;

滑动窗口大小

brotli_min_length 20;

指定压缩数据的最小字节

6、访问测试
[root@nginx ~]# curl -I -H "Accept-Encoding: gzip, deflate,br" 127.0.0.1
HTTP/1.1 200 OK
Server: nginx/1.14.0
Date: Thu, 11 Jun 2020 04:01:16 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
Vary: Accept-Encoding
Set-Cookie: route=617ff1b025324ae95a8a4e10c70854c9; Path=/
Last-Modified: Thu, 11 Jun 2020 03:46:40 GMT
ETag: W/"1cb0-5a7c6cef388ea"
Nginx-Cache: MISS
Content-Encoding: br

八、nginx完整配置文件

[root@nginx ~]# cat /usr/local/nginx1.14/conf/nginx.conf

user  nginx nginx;
worker_processes  1;

#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;

#pid logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

upstream backend {
        server 192.168.1.30:80 max_fails=2 fail_timeout=10s;
	server 192.168.1.40:80 max_fails=2 fail_timeout=10s;
        sticky;
}

    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;
    proxy_buffering on;
    proxy_temp_path /usr/local/nginx1.14/proxy_temp;
    proxy_cache_path /usr/local/nginx1.14/proxy_cache levels=1:2 keys_zone=my-cache:100m inactive=600m max_size=2g;



    sendfile        on;
    #tcp_nopush on;

    #keepalive_timeout 0;
    keepalive_timeout  65;
    brotli on;
    brotli_types text/plain text/css text/xml application/xml application/json ;
    brotli_static off; 
    brotli_comp_level 11;
    brotli_buffers 16 8k;
    brotli_window 512k;
    brotli_min_length 20;


    gzip  on;
    gzip_comp_level 6;
    gzip_http_version 1.1;
    gzip_proxied any;
    gzip_min_length 1k;
    gzip_buffers 16 8k;
    gzip_types text/plain text/css text/javascript application/json application/javascript application/x-javascript application/xml;
     gzip_vary on;
     client_max_body_size   10m;
     client_body_buffer_size   128k;
     proxy_connect_timeout   75;
     proxy_send_timeout   75;
     proxy_read_timeout   75;
     proxy_buffer_size   4k;
     proxy_buffers   4 32k;
     proxy_busy_buffers_size   64k;
     proxy_temp_file_write_size  64k;
     #proxy_buffering on;
     #proxy_temp_path /usr/local/nginx1.14/proxy_temp;
     #proxy_cache_path /usr/local/nginx1.14/proxy_cache levels=1:2 keys_zone=my-cache:100m inactive=600m max_size=2g;


    server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;

        #access_log logs/host.access.log main;
	location ~/purge(/.*) {
	    allow 127.0.0.1;
	    allow 192.168.1.0/24;
	    deny all;
	    proxy_cache_purge my-cache $host$1$is_args$args;
	}

        location / {
            root   html;
            index  index.html index.htm;
	    proxy_pass http://backend;
	    proxy_redirect off;
	    proxy_set_header Host $host;
	    proxy_set_header X-Real-IP $remote_addr;
	    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
	    proxy_next_upstream error timeout invalid_header http_500 http_502 http_504;
	    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;
        }

        location /index.html {
            root   html;
            index  index.html index.htm;
        }

        location /auth {
            root   html;
            index  index.html index.htm;
	    auth_basic  "提示语句";
	    auth_basic_user_file  /usr/local/nginx1.14/nginx.passwd;
        }
	

        #error_page 404 /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        # proxy_pass http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ \.php$ {
        # root html;
        # fastcgi_pass 127.0.0.1:9000;
        # fastcgi_index index.php;
        # fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
        # include fastcgi_params;
        #}

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        # deny all;
        #}
    }


    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    # listen 8000;
    # listen somename:8080;
    # server_name somename alias another.alias;

    # location / {
    # root html;
    # index index.html index.htm;
    # }
    #}


    # HTTPS server
    #
    #server {
    # listen 443 ssl;
    # server_name localhost;

    # ssl_certificate cert.pem;
    # ssl_certificate_key cert.key;

    # ssl_session_cache shared:SSL:1m;
    # ssl_session_timeout 5m;

    # ssl_ciphers HIGH:!aNULL:!MD5;
    # ssl_prefer_server_ciphers on;

    # location / {
    # root html;
    # index index.html index.htm;
    # }
    #}

}

九、扩展知识

nginx 修改版本等信息

1、更改ngnix显示版本

编译前编辑

[root@nginx ~]# vim /usr/src/nginx-1.14.0/src/core/nginx.h
#define nginx_version
#define NGINX_VERSION
#define NGINX_VER
#define NGINX_VAR

修改上面的信息,即可更改 nginx 显示版本

2、自定义信息

编译前编辑

[root@nginx ~]# vim /usr/src/nginx-1.14.0/src/http/ngx_http_special_response.c
static u_char ngx_http_error_full_tail[] =
static u_char ngx_http_error_tail[] =
[root@nginx ~]# vim /usr/src/nginx-1.14.0/src/http/ngx_http_header_filter_module.c
static char ngx_http_server_string[]=

修改上面的信息为你自己的

3、修改nginx版本名称

编译完成后修改/usr/local/nginx1.14/conf/目录下面

fastcgi.conffastcgi.conf.defaultfastcgi_paramsfastcgi_params.default这四个文件里面的版本名称

查看 nginx 版本号

[root@nginx ~]# nginx -v
没有账号? 忘记密码?

社交账号快速登录