Nginx总结

2021/03/14

java架构直通车-第6周 LVS+Nginx实现高可用集群

参考资料

Nginx用途

Nginx是一个静态资源服务器,能够实现动静分离,同时也是能实现反向代理、集群、负载均衡等功能的服务器

一、Linux环境Nginx安装

1.1 离线安装依赖

参考文档:

  • https://www.runoob.com/linux/nginx-install-setup.html
  • https://www.cnblogs.com/taiyonghai/p/6728707.html
  • https://www.cnblogs.com/wcwnina/p/8728430.html

1.下载Nginx及依赖包
模块依赖性Nginx需要依赖下面3个包

2.安装
依赖包安装顺序依次为:openssl、zlib、pcre, 最后安装Nginx包 安装gcc
yum install -y gcc-c++

安装OpenSSL

[root@localhost wcw]# tar -zxvf openssl-fips-2.0.2.tar.gz 
[root@localhost wcw]# cd openssl-fips-2.0.2
[root@localhost openssl-fips-2.0.2]# ./config 
[root@localhost openssl-fips-2.0.2]# make
[root@localhost openssl-fips-2.0.2]# make install 

安装zlib

[root@localhost wcw]# tar -zxvf zlib-1.2.7.tar.gz
[root@localhost wcw]# cd zlib-1.2.7
[root@localhost zlib-1.2.7]# ./configure 
[root@localhost zlib-1.2.7]# make
[root@localhost zlib-1.2.7]# make install 

安装pcre

[root@localhost wcw]# tar -zxvf pcre-8.21.tar.gz
[root@localhost wcw]# cd pcre-8.21
[root@localhost pcre-8.21]# ./configure 
[root@localhost pcre-8.21]# make
[root@localhost pcre-8.21]# make install 

查看pcre版本:pcre-config --version

安装Nginx

#编译之前,先创建临时目录,否则启动报错
mkdir /var/temp/nginx -p

#### 请注意:"--with-xxx="的值是解压目录,而不是安装目录!
[root@localhost wcw]# tar -zxvf nginx-1.12.2.tar.gz 
[root@localhost wcw]# cd nginx-1.12.2
[root@localhost nginx-1.12.2]# ./configure --prefix=/usr/local/nginx --with-pcre=../pcre-8.21 --with-zlib=../zlib-1.2.7 --with-openssl=../openssl-fips-2.0.2
# 或者执行下面的 configure配置,然后继续 make & make install
[root@localhost nginx-1.12.2]# make
[root@localhost nginx-1.12.2]# make install

configure配置

./configure \
--prefix=/usr/local/nginx \
--conf-path=/usr/local/nginx/nginx.conf \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--pid-path=/var/run/nginx.pid \
--lock-path=/var/run/nginx.lock \
--with-http_gzip_static_module \
--http-client-body-temp-path=/var/cache/nginx/client_temp \
--http-proxy-temp-path=/var/cache/nginx/proxy_temp \
--http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp \
--http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp \
--http-scgi-temp-path=/var/cache/nginx/scgi_temp \

命令 解释
–prefix 指定nginx安装目录
–pid-path 指向nginx的pid
–lock-path 锁定安装文件,防止被恶意篡改或误操作
–error-log 错误日志
–http-log-path http日志
–with-http_gzip_static_module 启用gzip模块,在线实时压缩输出数据流
–http-client-body-temp-path 设定客户端请求的临时目录
–http-proxy-temp-path 设定http代理临时目录
–http-fastcgi-temp-path 设定fastcgi临时目录
–http-uwsgi-temp-path 设定uwsgi临时目录
–http-scgi-temp-path 设定scgi临时目录

3.Nginx Linux基本操作指令

检测是否安装成功: 
[root@localhost wcw]# ./nginx -t  或者,在浏览器地址输入"127.0.0.1"回车出现welcome页面

启动服务:./nginx

退出服务:./nginx -s quit

强制关闭服务:./nginx -s stop

重载服务:./nginx -s reload  (重载服务配置文件,类似于重启,但服务不会中止)

验证配置文件:./nginx -t

使用配置文件:./nginx -c "配置文件路径"

使用帮助:./nginx -h

版本查看:./nginx -v

4.问题 & 注意事项
nginx.pid打开失败以及失效的解决方案

1).找不到pid:
查看目录是否存在

2).invalid pid:

./nginx -c /usr/...指定nginx.conf路径
./nginx -s reload

3).注意事项:

  • 如果在云服务器安装,需要开启默认的nginx端口:80
  • 如果在虚拟机安装,需要关闭防火墙
  • 本地win或mac需要关闭防火墙

1.2 在线安装依赖

1.安装依赖
yum install -y gcc gcc-c++ automake pcre pcre-devel zlib zlib-devel openssl openssl-devel


2.在线下载或者上传nginx-1.16.1.tar.gz 
修改权限:chmod 755 nginx-1.16.1.tar.gz
解压:tar -zxvf nginx-1.16.1.tar.gz

3.编译、安装
cd /data/packages/nginx-1.16.1
./configure  \
--prefix=/data/nginx \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_realip_module \
--with-http_addition_module \
--with-http_sub_module \
--with-http_stub_status_module \
--with-http_gzip_static_module \
--with-http_addition_module \
--with-pcre \
--with-stream \


make && make install

4.创建nginx命令软链接到环境变量
ln -s /data/nginx/sbin/* /usr/local/sbin/

5.验证nginx配置文件是否正确
/data/nginx/sbin/nginx -c /data/nginx/conf/nginx.conf -t

6.启停
/data/nginx/sbin/nginx -c /data/nginx/conf/nginx.conf
./nginx -s reload
./nginx -s stop

二、Nginx核心配置nginx.conf

https://www.cnblogs.com/wcwnina/p/8728430.html
https://www.cnblogs.com/taiyonghai/p/5610112.html

#设置worker进程的用户,指的linux中的用户,会涉及到nginx操作目录或文件的一些权限,默认为 nobody
#user  nobody; 

#worker进程工作数设置,一般来说CPU有几个,就设置几个,或者设置为N-1也行
worker_processes  1;  

#nginx 日志级别 debug | info | notice | warn | error | crit | alert | emerg ,错误级别从左到右越来越大
#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info; 

#设置nginx进程 pid
#pid        logs/nginx.pid;  

#设置工作模式
events {
    #//每个worker允许的连接数
    worker_connections  1024;
}

#http 是指令块,针对http网络传输的一些指令配置
http {
    ## include 引入外部配置,提高可读性,避免单个配置文件过大
    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;

    #使用高效文件传输,提升传输性能。启用后才能使用 tcp_nopush ,是指当数据表累积一定大小后才发送,提高了效率。
    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0; 设置客户端与服务端请求的超时时间,保证客户端多次请求的时候不会重复建立新的连接,节约资源损耗。
    keepalive_timeout  65;
    
    #压缩
    #gzip  on;

    # 服务器主机配置(虚拟主机、反向代理等)
    server {
        listen       80;
        server_name  localhost;
        #charset koi8-r;

        #access_log  logs/host.access.log  main;
        ## 路由配置(虚拟目录等)
        location / {
            root   /home/foodie-shop;
            index  index.html;
        }

        #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快速认知

Nginx主要功能就是通过upstream模块实现 “反向代理 集群、 负载均衡、 路由分发控制”

Nginx进程模型

Nginx进程模型:master进程一个,worker进程可在conf中配置多个

Nginx处理Web请求机制解析

处理web请求机制:异步非阻塞 epoll多路复用

Nginx日志切割

现有的日志都会存在 access.log 文件中,但是随着时间的推移,这个文件的内容会越来越多,体积会越来越大,不便于运维人员查看.
所以我们可以通过把文件切割为多份不同的小文件作为日志,切割规则可以以天为单位
1.Nginx 日志切割-手动方式

具体步骤如下:
1. 创建一个shell可执行文件: cut_my_log.sh ,内容为:
#!/bin/bash 
LOG_PATH="/var/log/nginx/" 
RECORD_TIME=$(date -d "yesterday" +%Y-%m-%d+%H:%M) 
PID=/var/run/nginx/nginx.pid 
mv ${LOG_PATH}/access.log ${LOG_PATH}/access.${RECORD_TIME}.log 
mv ${LOG_PATH}/error.log ${LOG_PATH}/error.${RECORD_TIME}.log 

#向Nginx主进程发送信号,用于重新打开日志文件
kill -USR1 `cat $PID` 

2. 为 cut_my_log.sh 添加可执行的权限:
chmod +x cut_my_log.sh 

3. 测试日志切割后的结果: 
./cut_my_log.sh

2.Nginx 日志切割-定时

1. 安装定时任务:
yum install crontabs插件 

2. crontab -e 编辑并且添加一行新的任务:
*/1 * * * * /usr/local/nginx/sbin/cut_my_log.sh 

3. 重启定时任务:
service crond restart

附:常用定时任务命令:
service crond start //启动服务 
service crond stop //关闭服务 
service crond restart //重启服务 
service crond reload //重新载入配置 
crontab -e // 编辑任务 
crontab -l // 查看任务列表 

定时任务表达式: Cron表达式是,分为5或6个域,每个域代表一个含义,如下所示:

  星期几 年(可选)
取值范围 0-59 0-23 1-31 1-12 1-7 2019/2020/2021/…

常用表达式:
每分钟执行:
*/1 * * * *
每日凌晨(每天晚上23:59)执行:
59 23 * * *
每日凌晨1点执行:
0 1 * * *

参考文献:
每天定时为数据库备份:https://www.cnblogs.com/leechenxiang/p/7110382.html

虚拟主机-使用Nginx为静态资源提供服务

发布前端工程、或者静态资源通过nginx服务器来提供访问

# 修改nginx.cong服务器主机配置(虚拟主机、反向代理等)
    server {
        listen       80;
        server_name  localhost;

        location / {
            root   /home/foodie-shop;
            index  index.html;
        }
        # 配置静态资源访问:/home/imooc/下存放.jpg .gif .mp3 .mp4
        location /imooc {
            root   /home;  
        }
        # 配置alias别名方式,提供静态资源访问:/home/imooc/下存放.jpg .gif .mp3 .mp4
        location /static {
            alias   /home/imooc;  
        }
    }

使用Gzip压缩提升请求效率

修改nginx.cong

#开启压缩,提高传输效率,节约带宽
gzip  on;
#限制最小压缩,小于1字节不压缩
gzip_min_length 1;
#定义压缩比级别,文件越大压缩越多,但是cpu消耗变多
gzip_comp_level 3;
#压缩文件类型
gzip_types text/css text/xml image/gif image/jpeg image/png application/javascript
image/x-ms-bmp application/pdf text/plain application/json application/xhtml+xml;

location的匹配规则解析

 server {
        listen       80;
        server_name  localhost;
        # = 精确匹配/
        location =/ {
            root   /home/foodie-shop;
            index  index.html;
        }
        # = 精确匹配/home/imooc/img/face.png
        location =/imooc/img/face.png {
            root   /home;  
        }
        # 正则匹配,~*区分大小写,~不区分大小写
        location ~*\.GIF|jpg|jpeg|bmp|png {
            root   /home; 
        }
        # ^~以某个字符开头的请求:/imooc/img下的资源
        location ~^/imooc/img {
            root   /home; 
        }
    }

DNS域名解析


使用SwitchHosts 模拟本地域名解析访问

https://laod.cn/hosts/switchhosts.html
SwitchHosts! 是一款可以方便你管理和一键切换多个 hosts 方案的免费开源工具,跨平台支持 Windows、macOS 和 Linux 系统。
SwitchHosts官网:https://oldj.github.io/SwitchHosts/#cn

配置示例:

221.131.136.154    www.immoc.shop.com

四、Nginx进阶与实战

4-0 在Nginx中解决跨域问题

CORS(cross-origin sharing standard)跨源资源共享

允许跨域的方式 1.Jsonp:使用jsonp,由于jsonp请求是通过script的方式发送的(只有xhr的请求方式才有可能产生跨域问题),所以不会产生跨域问题。
2.springboot Cors
3.Nginx配置

 server {
        listen       80;
        server_name  localhost;

        #允许跨域请求的域,*代表所有 
        add_header 'Access-Control-Allow-Origin' *; 
        #允许带上cookie请求 
        add_header 'Access-Control-Allow-Credentials' 'true'; 
        #允许请求的方法,比如 GET/POST/PUT/DELETE 
        add_header 'Access-Control-Allow-Methods' *; 
        #允许请求的header 
        add_header 'Access-Control-Allow-Headers' *;
 }

4-1 在Nginx中配置静态资源防盗链

 server {
        listen       80;
        server_name  localhost;

        #对源站点验证 
        valid_referers *.imooc.com; 
        #非法引入会进入下方判断 
        if ($invalid_referer) { 
            return 404; 
        }
        #允许跨域请求的域,*代表所有  
 }

4-2 Nginx的模块化设计解析

4-3 Nginx的集群、反向代理、负载均衡解析


Nginx主要功能就是通过upstream模块实现 “反向代理、 集群、 负载均衡、 路由分发控制” 

  • 当upstream只配置一个节点时,就只有反向代理的作用,没有集群就谈不上负载均衡了

4-6 四层、七层与DNS负载均衡 

4-7 OSI 网络模型

在讲到Nginx负载均衡的时候,
其实Nginx是七层负载均衡,
后续我们还会涉及到LVS,是四层负载均衡,
七层和四层是什么概念呢?这就必须提到网络模型

层级 名称 说明
第七层 应用层 与用户行为交互
第六层 表示层 定义数据格式以及数据加密
第五层 会话层 创建、管理以及销毁会话
第四层 传输层 创建、管理请求端到响应端(端到端)的连接
第三层 网络层 请求端的IP地址
第二层 数据链路层 提供介质访问与链路管理
第一层 物理层 传输介质,物理媒介

4-8 使用Nginx搭建3台Tomcat集群

    #配置上游服务器集群, nginx默认是轮训
    upstream tomcats{
        server 192.168.1.173:8080;
        server 192.168.1.174:8080;
        server 192.168.1.175:8080; 
    }
    server {
        listen       80;
        server_name  www.tomcats.com;
        location /{
            proxy_pass http://tomcats; // 反向代理
        } 
    }
参数 含义 说明
max_conns 允许最大连接数  
slow_start 当节点恢复,不立即加入 商用版本参数
max_fails 失败多少次 认为主机已挂掉则,踢出 默认值1
fail_timeout 踢出后重新探测时间 默认值10s
backup 备用服务,其他服务器节点挂调才会使用  
/down 不可用,节点下线  
weight 权重  

4-9 使用JMeter测试单节点与集群的并发异常率 

并发请求数高的时候(jemeter测试:200个线程,每个请求100次),多节点集群的故障率(请求失败数)远远小于单节点;
并发性能提高效果显著;

步骤:

1.新建测试计划
2.测试计划添加线程组: 设置线程数,循环次数
3.线程组添加取样器: 填写http请求信息(协议、域名或者ip、port、请求方法、路径)
4.测试计划添加监听器:聚合报告
5.测试计划添加监听器:查看结果树
6.测试计划添加监听器:用表格查看结果

4-10 负载均衡原理 - 轮训(默认) 

参见:4-8 使用Nginx搭建3台Tomcat集群

4-11 负载均衡原理 - 权重(weight) 

    #配置上游服务器集群, nginx默认是轮训
    upstream tomcats{
        #配置权重
        server 192.168.1.173:8080 weigth=1;
        server 192.168.1.174:8080 weigth=2; 
        server 192.168.1.175:8080 weigth=3;
    }
    server {
        listen       80;
        server_name  www.tomcats.com;
        location /{
            proxy_pass http://tomcats(和upstream名保持一致); // 配置反向代理
        } 
    }

4-12-13 upstream的指令参数之max_conns(允许最大连接数) 

限制每台server的连接数,用于保护避免过载,可起到限流作用。

测试参考配置如下:
# worker进程设置1个,便于测试观察成功的连接数 
worker_processes 1; 
upstream tomcats { 
    server 192.168.1.173:8080 max_conns=2; 
    server 192.168.1.174:8080 max_conns=2; 
    server 192.168.1.175:8080 max_conns=2; 
}

4-14-15 upstream的指令参数之slow_start(当节点恢复,不立即加入) 

商业版,需要付费 配置参考如下:
upstream tomcats { 
    server 192.168.1.173:8080 weight=6 slow_start=60s; 
    server 192.168.1.174:8080 weight=2; 
    server 192.168.1.175:8080 weight=2; 
} 

注意

  • 该参数不能使用在 hash 和 random load balancing 中。
  • 如果在 upstream 中只有一台 server,则该参数失效。
  • 必须使用在集群中

4-16-17 upstream的指令参数之down(节点下线不可用)与backup(备用节点,其他服务器节点挂调才会起用) 

#down 用于标记服务节点不可用:
upstream tomcats { 
    server 192.168.1.173:8080 down; 
    server 192.168.1.174:8080 weight=1; 
    server 192.168.1.175:8080 weight=1; 
}
#backup 表示当前服务器节点是备用机,只有在其他的服务器都宕机以后,自己才会加入到集群中,被用户访问到:
upstream tomcats { 
    server 192.168.1.173:8080 backup; 
    server 192.168.1.174:8080 weight=1; 
    server 192.168.1.175:8080 weight=1; 
}

注意

  • backup 参数不能使用在 hash 和 random load balancing 中。

4-18-19 upstream的指令参数之max_fails(失败多少次 认为主机已挂掉则,踢出)与fail_timeout(踢出后重新探测时间) 

  • max_fails :表示失败几次,则标记server已宕机,剔出上游服务。
  • fail_timeout :表示失败的重试时间。

假设目前设置如下: max_fails=2 fail_timeout=15s

则代表在15秒内请求某一server失败达到2次后,则认为该server已经挂了或者宕机了,
随后再过15秒,这15秒内不会有新的请求到达刚刚挂掉的节点上,而是会到达运作的server,
15秒后会再有新请求尝试连接挂掉的server,如果还是失败,重复上一过程,直到恢复。

4-20-21 使用Keepalived提高吞吐量 

Keepalive 配置http长连接数量,减少频繁创建关闭连接的消耗

upstream tomcats { 
    server 192.168.1.190:8080; 
    keepalive 32; #设置长连接处理的数量
}
server {
    listen 80; 
    server_name www.tomcats.com; 
    
    location / { 
        proxy_pass http://tomcats; 
        proxy_http_version 1.1; #设置长连接http版本为1.1
        proxy_set_header Connection ""; #清除connection header 信息
    } 
}

4-22-23 负载均衡原理 - ip_hash 

使用

upstream tomcats { 
    ip_hash;
    
    server 192.168.1.173:8080; 
    server 192.168.1.174:8080; 
    server 192.168.1.175:8080;
}
server {
    listen 80; 
    server_name www.tomcats.com; 
    
    location / { 
        proxy_pass http://tomcats; 
    } 
}

注意

  • 同一局域网(192.168.1.*)下的ip会hash到同一个值

服务节点增减带来的问题

  • 如果节点数量变化,所有请求需要重新hash,原来的用户会话和缓存都会丢失

4-24 一致性hash算法 

只有增减节点影响到服务节点环形的就近节点,用户会话和缓存会发生变化,其他大部分节点用户不会变化

4-25-26 负载均衡原理 - url hash 与 least_conn 

#根据每次请求的url地址,hash后访问到固定的服务器节点。
upstream tomcats { 
    # url hash 
    hash $request_uri; 
    # 最少连接数 
    # least_conn; 
    server 192.168.1.173:8080; 
    server 192.168.1.174:8080; 
    server 192.168.1.175:8080; 
}
server { 
    listen 80; 
    server_name www.tomcats.com; 
    location / { 
        proxy_pass http://tomcats; 
    } 
}

4-27-28-29 Nginx控制浏览器缓存


1.浏览器缓存:

  • 加速用户访问,提升单个用户(浏览器访问者)体验,缓存在本地

2.Nginx缓存

  • 缓存在nginx端,提升所有访问到nginx这一端的用户
  • 提升访问上游(upstream)服务器的速度
  • 用户访问仍然会产生请求流量

3.控制浏览器缓存:

location /files { 
    alias /home/imooc; 
    # expires 10s; //10秒 后过期
    # expires @22h30m; //指定晚上10:30过期
    # expires -1h; // 提前1小时过期 ~= no cache
    # expires epoch; // 1970年过期 ~= no cache
    # expires off; //关闭nginx缓存,使用浏览器默认缓存机制
    expires max; //大概18年后过期
}

4-30-31 Nginx的反向代理缓存

# proxy_cache_path 设置缓存目录 
# keys_zone 设置共享内存以及占用空间大小 
# max_size 设置缓存大小 
# inactive 超过此时间则被清理 
# use_temp_path 临时目录,使用后会影响nginx性能,off关闭 
proxy_cache_path /usr/local/nginx/upstream_cache keys_zone=mycache:5m max_size=1g inactive=1m use_temp_path=off
location / { 
    proxy_pass http://tomcats; 
    
    # 启用缓存,和keys_zone一致 
    proxy_cache mycache; 
    # 针对200和304状态码缓存时间为8小时 
    proxy_cache_valid 200 304 8h; 
}

4-32 使用Nginx配置SSL证书提供HTTPS访问 

要在nginx中配置https,就必须安装ssl模块,也就是: http_ssl_module 。

安装ssl模块 1.进入到nginx的解压目录: /home/software/nginx-1.16.1
2.新增ssl模块(原来的那些模块需要保留)

./configure \ 
--prefix=/usr/local/nginx \ 
--pid-path=/var/run/nginx/nginx.pid \ 
--lock-path=/var/lock/nginx.lock \ 
--error-log-path=/var/log/nginx/error.log \ 
--http-log-path=/var/log/nginx/access.log \ 
--with-http_gzip_static_module \ 
--http-client-body-temp-path=/var/temp/nginx/client \ 
--http-proxy-temp-path=/var/temp/nginx/proxy \ 
--http-fastcgi-temp-path=/var/temp/nginx/fastcgi \ 
--http-uwsgi-temp-path=/var/temp/nginx/uwsgi \ 
--http-scgi-temp-path=/var/temp/nginx/scgi \ 
--with-http_ssl_module

3.编译和安装

make
make install

配置https
1.把ssl证书 *.crt 和 私钥 *.key 拷贝到 /usr/local/nginx/conf 目录中。 (使用云服务的话,可以再阿里云或者腾讯云上申请)
2.新增 server 监听 443 端口:

server { 
	listen 443;
	server_name www.imoocdsp.com;
	# 开启ssl ssl on;
	# 配置ssl证书 
	ssl_certificate 1_www.imoocdsp.com_bundle.crt;
	# 配置证书秘钥 
	ssl_certificate_key 2_www.imoocdsp.com.key;
	# ssl会话cache 
	ssl_session_cache shared:SSL:1m;
	# ssl会话超时时间 
	ssl_session_timeout 5m;
	# 配置加密套件,写法遵循 openssl 标准 
	ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
	ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
	ssl_prefer_server_ciphers on;
	location / { 
		proxy_pass http://tomcats/;
    }
}

4-33 动静分离的那些事儿 

  • 1.前端静态资源和后端api接口分开部署,减少后端api服务的请求压力;
  • 2.前端静态资源由nginx提供访问,并且可以缓存,提高响应速度;
  • 3.动态资源由接口请求后台api服务tomcat,统一封装接口,对外(web、移动端、小程序)提供服务;
  • 4.前后端解耦,并行开发;

动静分离的方式

4-34 部署Nginx到云端 - 安装Nginx(同虚拟机安装) 

前后端可以用同一个nginx代理,

  • 配置一个server代理前端项目静态资源
  • 配置另一个server反向代理后端api集群节点

便于维护,可以配置两个api.conf web.conf文件,然后在nginx.conf中引入

include api.conf;
include web.conf;

4-35 部署Nginx1到云端 - 配置反向代理(同4-11)

1.upstream中配置后端api服务节点集群
2.server中配置反向代理api Server
3.验证:访问nginx地址,能求请求到后端节点接口数据

upstream api.shop.mooc.com{
    server 192.168.41.6:8088; //实际后端api服务集群节点1
    server 192.168.41.7:8088; //实际后端api服务集群节点2
}

server{
    listen 80; //同一个nginx,虽然多个server都是80端口,但是server_name不同,所以不会冲突
    server_name api.shop.mooc.com  //前端代码请求的api地址,nginx代理服务器
    location ~{
        proxy_pass http://api.shop.mooc.com;
    }
}

4-36 部署Nginx2到云端 - 实现动静分离与虚拟主机



1.服务器上创建前端静态资源项目目录:/home/website
2.上传前端项目到website下
3.修改前端js中api接口地址:修改为```api.shop.mooc.com:80; //80端口默认可以去掉``
4.配置nginx代理静态资源

# 修改nginx.cong服务器主机配置(虚拟主机、反向代理等)
    server {
        listen       80; //同一个nginx,虽然多个server都是80端口,但是server_name不同,所以不会冲突
        server_name  web.shop.mooc.com;

        location / {
            root   /home/website/foodie-shop;
            index  index.html;
        } 
    }

4-37 实际项目配置记录

示例1

 		upstream demoApp.api{
 			server 192.168.0.1:8084;
 			server 192.168.0.2:8084;
 		}
 	    server {
 	        listen       80;
 	        server_name  192.168.0.1;
 			#配置跨域
 	        add_header 'Access-Control-Allow-Origin' *; 
 	        add_header 'Access-Control-Allow-Credentials' 'true'; 
 	        add_header 'Access-Control-Allow-Methods' *; 
 	        add_header 'Access-Control-Allow-Headers' *;
 			#系统首页
 	        location / {
 	            root   /home/dist;
 	            index  index.html;
 	        }
 			#静态资源, index.html在static下,能够匹配到
 			location ^~/static/ {
 	            root   /home/dist/;
 	        }  
 			#其他请求,反向代理至后端api,可配置多节点负载均衡
 			location ~/ { 
 				proxy_pass http://demoApp.api;
 				proxy_http_version 1.1;
 				proxy_set_header Upgrade $http_upgrade;
 				proxy_set_header Connection ‘upgrade’;
 				proxy_set_header Host $host;
 				proxy_cache_bypass $http_upgrade;
 			}
 	    }

示例2

 		upstream demoApp.api{
 			server 192.168.0.1:8084;
 		}
 	    server {
 	        listen       80;
 	        server_name  192.168.0.1;
 			#配置跨域
 	        add_header 'Access-Control-Allow-Origin' *; 
 	        add_header 'Access-Control-Allow-Credentials' 'true'; 
 	        add_header 'Access-Control-Allow-Methods' *; 
 	        add_header 'Access-Control-Allow-Headers' *;
 			#系统首页
 	        location / {
 	            root   /home/dist;
 	            index  index.html;
 	        }  
 			#index.html不在static下,单独匹配,严格、模糊匹配二选一即可
 			location =/index.html {
 	            root   /home/dist;
 	        }
 			#index.html不在static下,单独匹配,严格、模糊匹配二选一即可
 			location ^~/index.html {
 	            root   /home/dist;
 	        } 
 			#静态资源
 			location ^~/static/ {
 	            root   /home/dist;
 	        } 
 			#其他请求,反向代理至后端api,可配置多节点负载均衡
 			location ~/ { 
 				proxy_pass http://demoApp.api;
 				proxy_http_version 1.1;
 				proxy_set_header Upgrade $http_upgrade;
 				proxy_set_header Connection ‘upgrade’;
 				proxy_set_header Host $host;
 				proxy_cache_bypass $http_upgrade;
 			}
 	    }

nginx代理Websocket

https://www.jiyik.com/tm/xwzj/network_954.html
https://developer.aliyun.com/article/873518?spm=a2c6h.12873639.article-detail.33.2bd24525wxJnEm

websocket配置

#升级http请求为websocket长连接
location /ws  {
         proxy_pass  http://ip:port/;# 后端服务地址
         proxy_http_version 1.1; 
         proxy_set_header Upgrade $http_upgrade;
         proxy_set_header Connection  "Upgrade";
         proxy_read_timeout 6000s;
     }

隐藏Server版本号

 http {
         server_tokens off;
    }

黑白名单配置allow、deny

某些场景下,需要将一些IP或网段列入白名单,仅允许特定的人员访问,本文以Nginx为例配置IP白名单访问。
Nginx白名单使用allow和deny来控制,该配置可以添加在http段,也可以server、location中。

1).对整个Nginx下所有网站设置IP访问白名单,可以配置在http段中,如:仅允许10.10.10.10的访问,其他所有IP均不能访问。
http {
    ......
    allow 10.10.10.10;  #单个ip允许
    deny all;
    ......
}

2).允许10.10.10.11和10.10.10.55访问blog.whsir.com域名,可直接在对应域名的server字段中配置
server {
    ......
    server_name blog.whsir.com;
    allow 10.10.10.11; #单个ip允许
    allow 10.10.11.0/24;  #允许网段内ip
    deny all;

}

3).仅允许10.10.10.0~10.10.10.255对某个URI地址进行访问
location /text/login {
    ......
    allow 10.10.10.11; #单个ip允许
    allow 10.10.11.0/24;  #允许网段内ip
    deny all;
}

4).为了方便管理ip,设置了一个ip_white.conf文件, include引入到nginx.conf 
# vi ip_white.conf
allow 10.10.10.11; #单个ip允许
allow 10.10.11.0/24;  #允许网段内ip

# vi nginx.conf 
location /text/login {
    ......
    include /opt/nginx/conf/ip_white.conf; #引入ip_white列表
    deny all;
}

修改配置文件后,需nginx -s reload

nginx限流的几种方式

1. 控制速率

正常限流,ngx_http_limit_req_module 模块提供限制请求处理速率能力,使用了漏桶算法(leaky bucket)。下面例子使用 nginx limit_req_zone 和 limit_req 两个指令,限制单个IP的请求处理速率。
在 nginx.conf http 中添加限流配置:
格式:limit_req_zone key zone rate

http {
limit_req_zone $binary_remote_addr zone=myRateLimit:10m rate=10r/s;
}
配置 server,使用 limit_req 指令应用限流。

server {
location / {
limit_req zone=myRateLimit;
proxy_pass http://my_upstream;
}
}
key :定义限流对象,binary_remote_addr 是一种key,表示基于 remote_addr(客户端IP) 来做限流,binary_ 的目的是压缩内存占用量。
zone:定义共享内存区来存储访问信息, myRateLimit:10m 表示一个大小为10M,名字为myRateLimit的内存区域。1M能存储16000 IP地址的访问信息,10M可以存储16W IP地址访问信息。
rate 用于设置最大访问速率,rate=10r/s 表示每秒最多处理10个请求。Nginx 实际上以毫秒为粒度来跟踪请求信息,因此 10r/s 实际上是限制:每100毫秒处理一个请求。这意味着,自上一个请求处理完后,若后续100毫秒内又有请求到达,将拒绝处理该请求。

2. 处理突发流量

上面例子限制 10r/s,如果有时正常流量突然增大,超出的请求将被拒绝,无法处理突发流量,可以结合 burst 参数使用来解决该问题。

server {
location / {
limit_req zone=myRateLimit burst=20;
proxy_pass http://my_upstream;
}
}
burst 译为突发、爆发,表示在超过设定的处理速率后能额外处理的请求数。当 rate=10r/s 时,将1s拆成10份,即每100ms可处理1个请求。
此处,burst=20,若同时有21个请求到达,Nginx 会处理第一个请求,剩余20个请求将放入队列,然后每隔100ms从队列中获取一个请求进行处理。若请求数大于21,将拒绝处理多余的请求,直接返回503.
不过,单独使用 burst 参数并不实用。假设 burst=50 ,rate依然为10r/s,排队中的50个请求虽然每100ms会处理一个,但第50个请求却需要等待 50 * 100ms即 5s,这么长的处理时间自然难以接受。
因此,burst 往往结合 nodelay 一起使用。

server {
location / {
limit_req zone=myRateLimit burst=20 nodelay;
proxy_pass http://my_upstream;
}
}
nodelay 针对的是 burst 参数,burst=20 nodelay 表示这20个请求立马处理,不能延迟,相当于特事特办。不过,即使这20个突发请求立马处理结束,后续来了请求也不会立马处理。burst=20 相当于缓存队列中占了20个坑,即使请求被处理了,这20个位置这只能按 100ms一个来释放。

3. 限制连接数

ngx_http_limit_conn_module 提供了限制连接数的能力,利用 limit_conn_zone 和 limit_conn 两个指令即可。下面是 Nginx 官方例子:

limit_conn_zone $binary_remote_addr zone=perip:10m;
limit_conn_zone $server_name zone=perserver:10m;
server {
...
limit_conn perip 10;
limit_conn perserver 100;
}
limit_conn perip 10 作用的key 是 $binary_remote_addr,表示限制单个IP同时最多能持有10个连接。
limit_conn perserver 100 作用的key是 $server_name,表示虚拟主机(server) 同时能处理并发连接的总数。
需要注意的是:只有当 request header 被后端server处理后,这个连接才进行计数。

4. 设置白名单

限流主要针对外部访问,内网访问相对安全,可以不做限流,通过设置白名单即可。利用 Nginx ngx_http_geo_module 和 ngx_http_map_module 两个工具模块即可搞定。
在 nginx.conf 的 http 部分中配置白名单:

geo $limit {
default 1;
10.0.0.0/8 0;
192.168.0.0/24 0;
172.0.0.1 0;
}

map $limit $limit_key {
0 "";
1 $binary_remote_addr;
}
limit_req_zone $limit_key zone=myRateLimit:10m rate=10r/s;

geo 对于白名单(子网或IP都可以) 将返回0,其他IP将返回1。
map 将 limit∗∗转换为∗∗ limit** 转换为 **limit∗∗转换为∗∗limit_key,如果是 $limit 是0(白名单),则返回空字符串;如果是1,则返回客户端实际IP。
limit_req_zone 限流的key不再使用 binaryremoteaddr∗∗,而是∗∗limit_key 来动态获取值。如果是白名单,limit_req_zone 的限流key则为空字符串,将不会限流;若不是白名单,将会对客户端真实IP进行限流。

5. 拓展阅读

除限流外,ngx_http_core_module 还提供了限制数据传输速度的能力(即常说的下载速度)。
例如:

location /flv/ {
flv;
limit_rate_after 20m;
limit_rate 100k;
}

这个限制是针对每个请求的,表示客户端下载前20M时不限速,后续限制100kb/s。

问题记录

Post Directory

扫码关注公众号:暂无公众号
发送 290992
即可立即永久解锁本站全部文章