跳到主要内容

nginx 配置

1.编译安装

下载地址: https://nginx.org/en/download.html

# 方式一:
# 使用yum直接下载nginx,该种方式能直接以daemon守护进程的方式运行
yum install -y yum-utils

# 修改yum仓库
cat >>/etc/yum.repos.d/nginx.repo<<EOF
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true

[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
EOF

# 安装
yum install nginx -y


# 方式二:
# 下载对应的源码包
curl -O https://nginx.org/download/nginx-1.26.3.tar.gz
wget https://nginx.org/download/nginx-1.26.3.tar.gz

# 解压
tar -zxvf xxx.tar.gz

# 安装编译所需要的库
yum install -y gcc pcre pcre-devel zlib zlib-devel openssl openssl-devel
apt-get install -y gcc pcre pcre-devel zlib zlib-devel openssl openssl-devel

# 编译安装
./configure --prefix=/usr/local/nginx
# 详细
./configure --prefix=/usr/local/nginx \
--sbin-path=/usr/local/nginx/sbin/nginx \
--modules-path=/usr/local/nginx/modules \
--conf-path=/usr/local/nginx/conf/nginx.conf \
--error-log-path=/usr/local/nginx/logs/error.log \
--http-log-path=/usr/local/nginx/logs/access.log \
--pid-path=/usr/local/nginx/logs/nginx.pid \
--lock-path=/usr/local/nginx/logs/nginx.lock
make
make install

# 手动启动nginx
cd /usr/local/nginx/sbin
./nginx # 启动
./nginx -s stop # 快速停止
./nginx -s quit # 优雅关闭,退出前关闭连接
./nginx -s reload # 重新加载配置

# 创建nginx服务脚本
vim /usr/lib/systemd/system/nginx.service

# 内容
[Unit]
Description=nginx - web server
After=network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStartPre=/usr/local/nginx/sbin/nginx -t -c
/usr/local/nginx/conf/nginx.conf
ExecStart=/usr/1ocal/nginx/sbin/nginx -c /usr/1ocal/nginx/conf/nginx.conf
ExecReload=/usr/1ocal/nginx/sbin/nginx -s reload
ExecStop=/usr/local/nginx/sbin/nginx -s stop
ExecQuit=/usr/local/nginx/sbin/nginx -s quit
PrivateTmp=true

[Install]
WantedBy=multi-user.target

# 加载系统服务
systemctl daemon-reload

2.通过信号控制 nginx

# 找到nginx master进程的PID
ps -ef | grep nginx

# 调用的指令为 signal:为信号 PID:master线程ID
kill -signal PID

# TERM/INT 关闭整个服务
# QUIT 优雅的关闭服务
# HUP 重新配置文件并使用服务对新配置生效
# USR1 重新打开日志文件,可以用来进行日志切割
# USR2 平滑升级到最新版的nginx
# WINCH 所有的子进程不在接收处理新请求,相当于给work进程发送QUIT指令

kill -QUIT 15321

3.nginx 核心配置文件

# 常规所在目录
/usr/local/nginx/conf/nginx.conf
/etc/nginx/nginx.conf

# 删除注释行以及空白行
cat nginx.conf | sed -e '/#/d;/^\s*$/d' > simple.conf
  • 删除注释后基本 nginx.conf 文件
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location / {
root /opt/llb-web/dist;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}

1.全局块

# user: 用于配置运行服务器的worker进程的用户和用户组 默认nobody 对于系统权限方位控制更加精细
user www;

# master_process on|off 是否开启工作进程 默认 on
master_process on;

# worker_process num|auto 用于配置nginx生成工作进程的数量,建议该值与cpu内核数量一致 默认 1
worker_process 1;

# deamon on|off nginx服务是否以守护进程来运行 默认 on
daemon on;

# pid file_path 用来配置当前master进程的进程号ID存储的文件 默认 /usr/local/nginx/logs/nginx.pid
pid /usr/local/nginx/logs/nginx.pid

# error_log file_path[日志级别] 用来指定错误日志存放路径以及日志级别 默认值 logs/error.log error
# 日志级别有:debug|info|notice|warn|error|crit|alert|emerg
# 除了全局块,还能在http,server,location中配置
error_log /usr/local/nginx/logs/ error;

# include:用来引入其他配置文件,模块化管理配置 任何块都能使用
include /conf/new.conf

2.events 块

优化 nginx 性能

# accept_mutex on|off 默认on,用来防止一个请求将所有worker进程同时被唤醒,开启后可以逐个唤醒,释放性能
accept_mutex on;

# multi_accept on|off 用来设置是否被允许同时接收多个网络连接 默认为off,即一个工作进程只能同时接受一个新的连接,否则一个进程可以同时接受所有的新连接 默认off
multi_accept on;
# 建议使用 on

# worker_connections num 配置单个worker进程最大的连接数 默认512
worker_connections 512;

# use method 用来设置nginx服务器选用哪种事件驱动来处理消息 method可选值:select/poll/epoll/kqueue等
use epoll;

3.http 块

# nginx通过mime type来区分互联网上不同的资源
include mime.types;

# default_type mime-type 用来指定nginx响应前端请求默认的mime类型 可以在http,server,location中指定
default_type text/plain;

# access_log path[format[buffer=size]] 用来记录用户所有的访问记录 可以在http,server,location中指定
access_log logs/access.log combined;

# log_format 用于指定log日志输出的格式
log_format combined(格式名称,可自定义) "..."

# sendfile on|off 设置nginx服务器是否使用sendfile()传输文件,该属性可以大大提高处理静态资源的性能 默认off
sendfile on;
# 建议打开

# keepalive_timeout time 设置长连接的超时时间,keepalive模式可以在某个客服端发送一个请求后保持连接,但这个客户端再次发送连接时不用重新建立连接,优化性能,但是要设置合理的超时时间才能提高效率,不然将会浪费服务器资源 默认75s
# 可以在http,server,location中指定
keepalive_timeout 75s;

# keepalive_requests num 用来设置一个keep-alive连接的使用的次数,可以在http,server,location中指定
keepalive_requests 100;

4.server 块和 location 块

server 块

# listen address[:port] 指令,用来配置监听端口 写到server块
listen 80;
# listen 127.0.0.1:8000;
# listen 127.0.0.1; 监听指定ip的所有端口
# listen 8000;
# listen *:8000;
# listen [::]:8000;
# listen [::1];
listen 8080 default_server; # default_server属性是标识符号,用来将此虚拟主机设置成默认主机。默认主机指的是如果没有匹配到对应的address:port,就会执行有default_server标记的server,如果没标记,则默认访问第一个server

# server_name name...; 用来设置虚拟主机服务名称,name可以提供多个,中间用空格分隔
server_name ""; # 默认值
# 关于server_name的配置方法有三种:
# 精确匹配1、通配符匹配2、正则匹配3 优先级 1>2>3
server_name abc.good.cn nba.good.cn;
server_name *.good.cn nba.good.*; # 通配符只能在域名的首部及尾部
server_name ~^www\.(\w+)\.com$; # 使用~作为正则表达式字符串的开始标记

常见正则表达式

代码说明
^匹配搜索字符串开始位置
$匹配搜索字符串结束位置
.匹配除换行符\n 之外的任何单个字符
\转义字符,将下一个字符标记为特殊字符
[xyz]字符集,与任意一个指定字符匹配
[a-z]字符范围,匹配指定范围内的任何字符
\w与以下任意字符匹配 A-Z a-z 0-9 和下划线,等效于[A-Za-z0-9_]
\d数字字符匹配,等效于[0-9]
{n}正好匹配 n 次
{n,}至少匹配 n 次
{n,m}匹配至少 n 次至多 m 次
*零次或多次,等效于{0,}
+一次或多次,等效于{1,}
?零次或一次,等效于{0,1}

location 块

# location 用来设置请求的url 可以写到 server,location
# 精确匹配,匹配路径/abc
location =/abc {} # 可以加上符号 location ^~/abc {} 加上^~后就停止往下继续匹配服务了
# 正则匹配,使用~开头
location ~^/abc\w$ {}
location ~*^/abc\w$ {} # 添加*号就不区分大小写

# root path 设置请求的目录 默认值html 可以写在http,server,location
root /usr/www/;
# alias path 用来更改location的url
alias /usr;
# 两者区别
# root的处理结果是:root路径+location路径
# alias的处理结果是:使用alias路径替换location路径

# index file ...; 设置网站的默认首页,可以有多个,直到找到为止,可以写到http,server,location中
index index.html index.htm;

# error_page code url; 设置网站的错误页面,可以写到http,server,location中
server {
# error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location =/50x.html {
root html;
}
}
# 可以选择 =[response] 作用是用来将相应的代码更改为另外一个
server {
error_page 404 =200 /50x.html;
location =/50x.html {
root html;
}
}
# 最终返回状态码200

5.静态资源优化配置语法

# 通过http块的这三个属性
sendfile on;
tcp_nopush on; # 必须打开sendfile才能生效,提高网络包的传输效率
tcp_nodeplay on; # 必须开启keep-alive才能生效,提高网络包的实时性

# 静态资源压缩优化
# gzip on|off ngx_http_gzip_module模块,默认内置,可以写到http,server,location中
gzip on;
# gzip_type mime-type ...; 可以填写多个,该指令可以根据响应页的类型选择性的开启Gzip压缩功能 可以写到http,server,location中
gzip_type text/html application/json;
gzip_type *; # 指定全部
# gzip_comp_level num; 指定压缩程度,可以1-9,1是压缩程度最低,9是压缩程度最高最费时间
gzip_comp_level 6;
# gzip_vary on|off; 压缩是否携带Vary:Accept-Encoding的响应头部数据,用于告诉接受方使用了压缩
gzip_vary on;
# gzip_buffers number size; 设置用于请求压缩缓冲区数量和大小
gzip_buffers 32 4k;
# gzip_disable 正则; 匹配user-agent(区分客户端)的值选择性开启gzip,匹配正则不开启压缩
gzip_disable "asdf.*";
# gzip_http_version 1.1|1.0; 针对不同的http协议版本,选择性开启gzip
gzip_http_version 1.1;
# gzip_min_length length; 该指令针对传输数据的大小,可以选择性地开启Gzip,只有大于最小值的资源才会被压缩
gzip_min_length 1k;
# gzip_proxied off|any|auth|...; 用于反向代理服务器返回结果进行Gzip压缩
gzip_proxied any; # 无限制,所有的都压缩

# gzip和sendfile共存问题
# 通过ngx_http_gzip_static_module模块的gzip_static指令来解决(上述模块需要另外安装)
# gzip_static on|off|always; 检查与访问资源同名的.gz文件时,response中以gzip相关的header返回.gz文件的内容
gzip_static on; # always 将不会判断浏览器版本直接就发送压缩之后的资源给客户端

这些配置在很多地方可能都会用到,所以我们可以将这些内容抽取到一个配置文件中,然后通过 include 指令把配置文件再次加载到 nginx.conf 配置文件中,方法使用。

nginx_gzip.conf

gzip on;
gzip_types *;
gzip_comp_level 6;
gzip_min_length 1024;
gzip_buffers 4 16K;
gzip_http_version 1.1;
gzip_vary on;
gzip_disable "MSIE [1-6]\.";
gzip_proxied off;

nginx.conf

include nginx_gzip.conf

6.浏览器缓存指令

https://www.bilibili.com/video/BV1ov41187bq?spm_id_from=333.788.player.switch&vd_source=e899503d59daaa6b71739ba31fab2d44&p=60

# expires time; 设置缓存的时间,可以写在http,server,location
# time可以是整数,也可以是负数,指定过期时间,如果是负数,Cache-Control则为no-cache(走弱缓存路线),如果为整数或0,则Cache-Control值为max-age=time
location ~ .*\.(png|js|jpg)$ {
expires 1000; # 默认单位为s秒
# expires 10d;
}

什么是缓存

缓存(cache),原始意义是指访问速度比一般随机存取存储器(RAM)快的一种高速存储器,通常它不像系统主存那样使用DRAM技术,而使用昂贵但较快速的SRAM技术。缓存的设置是所有现代计算机系统发挥高性能的重要因素之一。

什么是 web 缓存

Web缓存是指一个Web资源(如html页面,图片,js,数据等)存在于Web服务器和客户端(浏览器)之间的副本。缓存会根据进来的请求保存输出内容的副本;当下一个请求来到的时候,如果是相同的URL,缓存会根据缓存机制决定是直接使用副本响应访问请求,还是向源服务器再次发送请求。比较常见的就是浏览器会缓存访问过网站的网页,当再次访问这个URL地址的时候,如果网页没有更新,就不会再次下载网页,而是直接使用本地缓存的网页。只有当网站明确标识资源已经更新,浏览器才会再次下载网页

web 缓存的种类

客户端缓存
浏览器缓存
服务端缓存
Nginx / Redis / Memcached等

浏览器缓存

是为了节约网络的资源加速浏览,浏览器在用户磁盘上对最近请求过的文档进行存储,当访问者再次请求这个页面时,浏览器就可以从本地磁盘显示文档,这样就可以加速页面的阅览.

为什么要用浏览器缓存

成本最低的一种缓存实现
减少网络带宽消耗
降低服务器压力
减少网络延迟,加快页面打开速度

浏览器缓存的执行流程

HTTP 协议中和页面缓存相关的字段,我们先来认识下:

header说明
Expires缓存过期的日期和时间
Cache-Control设置和缓存相关的配置信息
Last-Modified请求资源最后修改时间
ETag请求变量的实体标签的当前值,比如文件的 MD5 值

image-20250405204934737

(1)用户首次通过浏览器发送请求到服务端获取数据,客户端是没有对应的缓存,所以需要发送 request 请求来获取数据;

(2)服务端接收到请求后,获取服务端的数据及服务端缓存的允许后,返回 200 的成功状态码并且在响应头上附上对应资源以及缓存信息;

(3)当用户再次访问相同资源的时候,客户端会在浏览器的缓存目录中查找是否存在响应的缓存文件

(4)如果没有找到对应的缓存文件,则走(2)步

(5)如果有缓存文件,接下来对缓存文件是否过期进行判断,过期的判断标准是(Expires),

(6)如果没有过期,则直接从本地缓存中返回数据进行展示

(7)如果 Expires 过期,接下来需要判断缓存文件是否发生过变化

(8)判断的标准有两个,一个是 ETag(Entity Tag),一个是 Last-Modified

(9)判断结果是未发生变化,则服务端返回 304,直接从缓存文件中获取数据

(10)如果判断是发生了变化,重新从服务端获取数据,并根据缓存协商(服务端所设置的是否需要进行缓存数据的设置)来进行数据缓存。

浏览器缓存相关指令

Nginx 需要进行缓存相关设置,就需要用到如下的指令

expires 指令

expires:该指令用来控制页面缓存的作用。可以通过该指令控制 HTTP 应答中的"Expires"和"Cache-Control"

语法expires [modified] time
expires epoch|max|off;
默认值expires off;
位置http、server、location

time:可以整数也可以是负数,指定过期时间,如果是负数,Cache-Control 则为 no-cache,如果为整数或 0,则 Cache-Control 的值为 max-age=time;

epoch: 指定 Expires 的值为'1 January,1970,00:00:01 GMT'(1970-01-01 00:00:00),Cache-Control 的值 no-cache

max:指定 Expires 的值为'31 December2037 23:59:59GMT' (2037-12-31 23:59:59) ,Cache-Control 的值为 10 年

off:默认不缓存。

add_header 指令

add_header 指令是用来添加指定的响应头和响应值。

语法add_header name value [always];
默认值
位置http、server、location...

Cache-Control 作为响应头信息,可以设置如下值:

缓存响应指令:

Cache-control: must-revalidate
Cache-control: no-cache
Cache-control: no-store
Cache-control: no-transform
Cache-control: public
Cache-control: private
Cache-control: proxy-revalidate
Cache-Control: max-age=<seconds>
Cache-control: s-maxage=<seconds>
指令说明
must-revalidate可缓存但必须再向源服务器进行确认
no-cache缓存前必须确认其有效性
no-store不缓存请求或响应的任何内容
no-transform代理不可更改媒体类型
public可向任意方提供响应的缓存
private仅向特定用户返回响应
proxy-revalidate要求中间缓存服务器对缓存的响应有效性再进行确认
max-age=<秒>响应最大 Age 值
s-maxage=<秒>公共缓存服务器响应的最大 Age 值

max-age=[秒]:

7.跨域问题解决

# 添加请求头
location / {
# add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Origin http://192.168.123.11,http://192.168.123.88:9000;
add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE;
}

8.防盗链问题

http 请求有一个头信息 referer,当浏览器向 web 服务器发送请求时,一般都会带上 Referer,告诉浏览器该请求是从哪个网页过来的。后台服务器根据这个来判断是否是自己信任的网站,不是就不放行。

# valid_referers none|blocked|server_names|string|...; nginx中有一个变量$invalid_referer,当referer和valid_referer后面内容匹配时,该变量变为0,如果不匹配,变为1,匹配过程不区分大小写。
# node: 如果Header中Referer为空,允许访问
# blocked: 在Header中Referer不为空,但是该值被防火墙或代理进行伪装过,如不带"http://","https://"等协议头的资源允许访问
# server_names: 指定具体域名或IP
# string: 可以支持正则和*的字符串,是正则需要~开头
location ~ .*\.(png|jpg|gir)$ {
valid_referers none blocked code.hzy777.eu.org *.hzy777.eu.org ~\.google\.;
if ($invalid_referer){
return 403;
}
root html/images;
}

# 更加严谨的方法要用到第三方模块ngx_http_accesskey_module

9.rewrite 功能配置(重写)

  • set 指令
# set $variable value; 用来设定一个新的变量名,注意不要与nginx的全局变量重名,可以写在server,location,if中
location / {
set $name nginx;
set $age 18;
default_type text/plain;
return 200 $name=$age;
}
  • Rewrite 常用全局变量
变量说明
$args变量中存放了请求 URL 中的请求参数。比如http://192.168.200.133/server?arg1=value1&args2=value2中的"arg1=value1&arg2=value2",功能和$query_string一样
$http_user_agent变量存储的是用户访问服务的代理信息(如果通过浏览器访问,记录的是浏览器的相关版本信息)
$host变量存储的是访问服务器的 server_name 值
$document_uri变量存储的是当前访问地址的 URI。比如http://192.168.200.133/server?id=10&name=zhangsan中的"/server",功能和$uri一样
$document_root变量存储的是当前请求对应 location 的 root 值,如果未设置,默认指向 Nginx 自带 html 目录所在位置
$content_length变量存储的是请求头中的 Content-Length 的值
$content_type变量存储的是请求头中的 Content-Type 的值
$http_cookie变量存储的是客户端的 cookie 信息,可以通过 add_header Set-Cookie 'cookieName=cookieValue'来添加 cookie 数据
$limit_rate变量中存储的是 Nginx 服务器对网络连接速率的限制,也就是 Nginx 配置中对 limit_rate 指令设置的值,默认是 0,不限制。
$remote_addr变量中存储的是客户端的 IP 地址
$remote_port变量中存储了客户端与服务端建立连接的端口号
$remote_user变量中存储了客户端的用户名,需要有认证模块才能获取
$scheme变量中存储了访问协议
$server_addr变量中存储了服务端的地址
$server_name变量中存储了客户端请求到达的服务器的名称
$server_port变量中存储了客户端请求到达服务器的端口号
$server_protocol变量中存储了客户端请求协议的版本,比如"HTTP/1.1"
$request_body_file变量中存储了发给后端服务器的本地文件资源的名称
$request_method变量中存储了客户端的请求方式,比如"GET","POST"等
$request_filename变量中存储了当前请求的资源文件的路径名
$request_uri变量中存储了当前请求的 URI,并且携带请求参数,比如http://192.168.200.133/server?id=10&name=zhangsan中的"/server?id=10&name=zhangsan"

上述参数还可以在日志文件中使用,这个就要用到前面我们介绍的log_format指令

log_format main '$remote_addr - $request - $status-$request_uri $http_user_agent';

access_log logs/access.log main;
  • if 指令

    if ($var){
    ...
    }

    if ($request_method = POST){
    ...
    }

    # 使用正则,表达式之间使用"~","~*","!~","!~*"来连接
    # "~","!~" 代表匹配正则过程区分大小写
    # "~*","!~*" 代表匹配正则过程不区分大小写
    if ($http_user_agent ~ MISE){
    # 是否包含MSIE字符串,包含返回true。
    ...
    }

    # 判断请求的文件是否存在
    # 判断不存在
    if (!-f $request_filename){
    ...
    }

    # 判断请求的目录是否存在 "-d" 和 "!-d"
    # 判断请求的目录或者文件是否存在 "-e" 和 "!-e"
    # 判断请求的文件是否可以执行 "-x" 和 "!-x"
  • break 指令

    该指令用于中断当前作用域中其他 nginx 配置,位于它之后的指令配置失效,并且 break 还可以终止当前的匹配并把当前的 URL 在本 location 进行重定向访问处理。

    location /testbreak{
    default_type text/plain;
    set $username TOM;
    if ($args){
    Set $username JERRY;
    break;
    set $username ROSE;
    }
    add_header username $username;
    return 200 $username;
    }
  • return 指令

    # return code [text];
    # return code URL;
    # return URL;

    code:为返回给客户端的HTTP状态代理。可以返回的状态代码为0~999的任意HTTP状态代理

    text:为返回给客户端的响应体内容,支持变量的使用

    URL:为返回给客户端的URL地址

    code:为返回给客户端的HTTP状态代理。可以返回的状态代码为0~999的任意HTTP状态代理

    text:为返回给客户端的响应体内容,支持变量的使用

    URL:为返回给客户端的URL地址
  • rewrite 指令

    该指令通过正则表达式的使用来改变 URI,可以同时存在一个或者多个指令,按照顺序依次对 URL 进行匹配和处理

    https://www.bilibili.com/video/BV1ov41187bq?spm_id_from=333.788.player.switch&vd_source=e899503d59daaa6b71739ba31fab2d44&p=72

    该指令通过正则表达式的使用来改变 URI。可以同时存在一个或者多个指令,按照顺序依次对 URL 进行匹配和处理。

    语法rewrite regex replacement [flag];
    默认值
    位置server、location、if
    # rewrite regex replacement [flag]; regex 正则,replacement 匹配成功后替换的字符串,如果以"http","https"开头的则不会向下对URI进行其他处理,直接返回重写后的URI给客户端
    location /rewrite {
    rewrite ^/rewrite/url\w*$ https://www.baidu.com;
    rewrite ^/rewrite/(test)\w*$ /$1;
    rewrite ^/rewrite/(demo)\w*$ /$1;
    }

    # rewrite_log on|off; 是否开启URL重写日志的输出功能
    rewrite_log on;
    error_log logs/rewrite_error.log notice;

    flag:用来设置 rewrite 对 URI 的处理行为,可选值有如下:

    • last:终止继续在本 location 块中处理接收到的 URI,并将此处重写的 URI 作为一个新的 URI,使用各 location 块进行处理。该标志将重写后的 URI 重写在 server 块中执行,为重写后的 URI 提供了转入到其他 location 块的机会。
    location rewrite {
    rewrite ^/rewrite/(test)\w*$ /$1 last;
    rewrite ^/rewrite/(demo)\w*$ /$1 last;
    }
    location /test{
    default_type text/plain;
    return 200 test_success;
    }
    location /demo{
    default_type text/plain;
    return 200 demo_success;
    }

    访问 http://192.168.200.133:8081/rewrite/testabc,能正确访问

    • break:将此处重写的 URI 作为一个新的 URI,在本块中继续进行处理。该标志将重写后的地址在当前的 location 块中执行,不会将新的 URI 转向其他的 location 块。
    location rewrite {
    #/test /usr/local/nginx/html/test/index.html
    rewrite ^/rewrite/(test)\w*$ /$1 break;
    rewrite ^/rewrite/(demo)\w*$ /$1 break;
    }
    location /test{
    default_type text/plain;
    return 200 test_success;
    }
    location /demo{
    default_type text/plain;
    return 200 demo_success;
    }

    访问 http://192.168.200.133:8081/rewrite/demoabc,页面报 404 错误

    • redirect:将重写后的 URI 返回给客户端,状态码为 302,指明是临时重定向 URI,主要用在 replacement 变量不是以"http://"或者"https://"开头的情况。
    location rewrite {
    rewrite ^/rewrite/(test)\w*$ /$1 redirect;
    rewrite ^/rewrite/(demo)\w*$ /$1 redirect;
    }
    location /test{
    default_type text/plain;
    return 200 test_success;
    }
    location /demo{
    default_type text/plain;
    return 200 demo_success;
    }

    访问http://192.168.200.133:8081/rewrite/testabc请求会被临时重定向,浏览器地址也会发生改变

    • permanent:将重写后的 URI 返回给客户端,状态码为 301,指明是永久重定向 URI,主要用在 replacement 变量不是以"http://"或者"https://"开头的情况。
    location rewrite {
    rewrite ^/rewrite/(test)\w*$ /$1 permanent;
    rewrite ^/rewrite/(demo)\w*$ /$1 permanent;
    }
    location /test{
    default_type text/plain;
    return 200 test_success;
    }
    location /demo{
    default_type text/plain;
    return 200 demo_success;
    }

    访问http://192.168.200.133:8081/rewrite/testabc请求会被永久重定向,浏览器地址也会发生改变

  • rewrite_log 指令

    该指令配置是否开启 URL 重写日志的输出功能。

    语法rewrite_log on|off;
    默认值rewrite_log off;
    位置http、server、location、if

    开启后,URL 重写的相关日志将以 notice 级别输出到 error_log 指令配置的日志文件汇总。

    rewrite_log on;
    error_log logs/error.log notice;

10.Rewrite 的案例

域名跳转

》问题分析

先来看一个效果,如果我们想访问京东网站,大家都知道我们可以输入www.jd.com,但是同样的我们也可以输入www.360buy.com同样也都能访问到京东网站。这个其实是因为京东刚开始的时候域名就是www.360buy.com,后面由于各种原因把自己的域名换成了www.jd.com, 虽然说域名变量,但是对于以前只记住了www.360buy.com的用户来说,我们如何把这部分用户也迁移到我们新域名的访问上来,针对于这个问题,我们就可以使用Nginx中Rewrite的域名跳转来解决。

》环境准备

  • 准备三个域名:
vim /etc/hosts
127.0.0.1 www.itcast.cn
127.0.0.1 www.itheima.cn
127.0.0.1 www.itheima.com
  • 通过 Nginx 实现访问www.itcast.cn
server {
listen 80;
server_name www.itcast.cn;
location /{
default_type text/html;
return 200 '<h1>welcome to itcast</h1>';
}
}

》通过 Rewrite 完成将www.ithema.com和www.itheima.cn的请求跳转到www.itcast.com

server {
listen 80;
server_name www.itheima.com www.itheima.cn;
rewrite ^/ http://www.itcast.cn;
}

问题描述:如何在域名跳转的过程中携带请求的 URI?

修改配置信息

server {
listen 80;
server_name www.itheima.com www.itheima.cn;
rewrite ^(.*) http://www.itcast.cn$1;
}

域名镜像

镜像网站指定是将一个完全相同的网站分别放置到几台服务器上,并分别使用独立的 URL 进行访问。其中一台服务器上的网站叫主站,其他的为镜像网站。镜像网站和主站没有太大的区别,可以把镜像网站理解为主站的一个备份节点。可以通过镜像网站提供网站在不同地区的响应速度。镜像网站可以平衡网站的流量负载、可以解决网络宽带限制、封锁等。

1589560433192

而我们所说的域名镜像和网站镜像比较类似,上述案例中,将www.itheima.com和 www.itheima.cn都能跳转到www.itcast.cn,那么www.itcast.cn我们就可以把它起名叫主域名,其他两个就是我们所说的镜像域名,当然如果我们不想把整个网站做镜像,只想为其中一个子目录下的资源做镜像,我们可以在location块中配置rewrite功能,比如:

server {
listen 80;
server_name www.itheima.cn www.itheima.com;
location /user {
rewrite ^/user(.*)$ http://www.itcast.cn$1;
}
location /emp{
default_type text/html;
return 200 '<h1>emp_success</h1>';
}
}

独立域名

一个完整的项目包含多个模块,比如购物网站有商品搜索模块、商品详情模块和购物车模块等,那么我们如何为每一个模块设置独立的域名。

需求:

http://search.itcast.com:81 访问商品搜索模块
http://item.itcast.com:82 访问商品详情模块
http://cart.itcast.com:83 访问商品购物车模块
server{
listen 81;
server_name search.itcast.com;
rewrite ^(.*) http://www.itcast.cn/search$1;
}
server{
listen 82;
server_name item.itcast.com;
rewrite ^(.*) http://www.itcast.cn/item$1;
}
server{
listen 83;
server_name cart.itcast.com;
rewrite ^(.*) http://www.itcast.cn/cart$1;
}

目录自动添加"/"

问题描述

通过一个例子来演示下问题:

server {
listen 8082;
server_name localhost;
location /heima {
root html;
index index.html;
}
}

通过http://192.168.200.133:8082/heima和通过http://192.168.200.133:8082/heima/访问的区别?

如果不加斜杠,Nginx 服务器内部会自动做一个 301 的重定向,重定向的地址会有一个指令叫 server_name_in_redirect on|off;来决定重定向的地址:

如果该指令为on
重定向的地址为: http://server_name:8082/目录名/;
http://localhost:8082/heima/
如果该指令为off
重定向的地址为: http://原URL中的域名:8082/目录名/;
http://192.168.200.133:8082/heima/

所以就拿刚才的地址来说,http://192.168.200.133:8082/heima如果不加斜杠,那么按照上述规则,如果指令server_name_in_redirect为on,则301重定向地址变为 http://localhost:8082/heima/,如果为 off,则 301 重定向地址变为http://192.168.200.133:8082/heima/。后面这个是正常的,前面地址就有问题。

注意 server_name_in_redirect 指令在 Nginx 的 0.8.48 版本之前默认都是 on,之后改成了 off,所以现在我们这个版本不需要考虑这个问题,但是如果是 0.8.48 以前的版本并且 server_name_in_redirect 设置为 on,我们如何通过 rewrite 来解决这个问题?

解决方案

我们可以使用 rewrite 功能为末尾没有斜杠的 URL 自动添加一个斜杠

server {
listen 80;
server_name localhost;
server_name_in_redirect on;
location /heima {
if (-d $request_filename){
rewrite ^/(.*)([^/])$ http://$host/$1$2/ permanent;
}
}
}

合并目录

搜索引擎优化(SEO)是一种利用搜索引擎的搜索规则来提高目的网站在有关搜索引擎内排名的方式。我们在创建自己的站点时,可以通过很多中方式来有效的提供搜索引擎优化的程度。其中有一项就包含 URL 的目录层级一般不要超过三层,否则的话不利于搜索引擎的搜索也给客户端的输入带来了负担,但是将所有的文件放在一个目录下又会导致文件资源管理混乱并且访问文件的速度也会随着文件增多而慢下来,这两个问题是相互矛盾的,那么使用 rewrite 如何解决上述问题?

举例,网站中有一个资源文件的访问路径时 /server/11/22/33/44/20.html,也就是说 20.html 存在于第 5 级目录下,如果想要访问该资源文件,客户端的 URL 地址就要写成 http://192.168.200.133/server/11/22/33/44/20.html,

server {
listen 8083;
server_name localhost;
location /server{
root html;
}
}

但是这个是非常不利于 SEO 搜索引擎优化的,同时客户端也不好记.使用 rewrite 我们可以进行如下配置:

server {
listen 8083;
server_name localhost;
location /server{
rewrite ^/server-([0-9]+)-([0-9]+)-([0-9]+)-([0-9]+)\.html$ /server/$1/$2/$3/$4/$5.html last;
}
}

这样的花,客户端只需要输入http://www.web.name/server-11-22-33-44-20.html就可以访问到20.html页面了。这里也充分利用了rewrite指令支持正则表达式的特性。

防盗链

防盗链之前我们已经介绍过了相关的知识,在 rewrite 中的防盗链和之前将的原理其实都是一样的,只不过通过 rewrite 可以将防盗链的功能进行完善下,当出现防盗链的情况,我们可以使用 rewrite 将请求转发到自定义的一张图片和页面,给用户比较好的提示信息。下面我们就通过根据文件类型实现防盗链的一个配置实例:

location /images {
root html;
valid_referers none blocked www.baidu.com;
if ($invalid_referer){
#return 403;
rewrite ^/ /images/forbidden.png break;
}
}

11.Nginx 反向代理

Nginx 反向代理概述

简而言之就是正向代理代理的对象是客户端,反向代理代理的是服务端,这是两者之间最大的区别。

Nginx 即可以实现正向代理,也可以实现反向代理。

我们先来通过一个小案例演示下 Nginx 正向代理的简单应用。

先提需求:

(1)服务端的设置:

http {
log_format main 'client send request=>clientIp=$remote_addr serverIp=>$host';
server{
listen 80;
server_name localhost;
access_log logs/access.log main;
location {
root html;
index index.html index.htm;
}
}
}

(2)使用客户端访问服务端,打开日志查看结果

1589729000713

(3)代理服务器设置:

server {

listen 82;
resolver 8.8.8.8;
location /{
proxy_pass http://$host$request_uri;
}
}

(4)查看代理服务器的 IP(192.168.200.146)和 Nginx 配置监听的端口(82)

(5)在客户端配置代理服务器

(6)设置完成后,再次通过浏览器访问服务端

1589729479920

通过对比,上下两次的日志记录,会发现虽然我们是客户端访问服务端,但是如何使用了代理,那么服务端能看到的只是代理发送过去的请求,这样的化,就使用 Nginx 实现了正向代理的设置。

但是 Nginx 正向代理,在实际的应用中不是特别多,所以我们简单了解下,接下来我们继续学习 Nginx 的反向代理,这是 Nginx 比较重要的一个功能。

Nginx 反向代理的配置语法

Nginx 反向代理模块的指令是由ngx_http_proxy_module模块进行解析,该模块在安装 Nginx 的时候已经自己加装到 Nginx 中了,接下来我们把反向代理中的常用指令一一介绍下:

proxy_pass
proxy_set_header
proxy_redirect

proxy_pass

该指令用来设置被代理服务器地址,可以是主机名称、IP 地址加端口号形式。

语法proxy_pass URL;
默认值
位置location

URL:为要设置的被代理服务器地址,包含传输协议(http,https://)、主机名称或 IP 地址加端口号、URI 等要素。

举例:

proxy_pass http://www.baidu.com;
location /server{}
proxy_pass http://192.168.200.146;
http://192.168.200.146/server/index.html
proxy_pass http://192.168.200.146/;
http://192.168.200.146/index.html

大家在编写 proxy_pass 的时候,后面的值要不要加"/"?

接下来通过例子来说明刚才我们提到的问题:

server {
listen 80;
server_name localhost;
location /{
#proxy_pass http://192.168.200.146;
proxy_pass http://192.168.200.146/;
}
}
当客户端访问 http://localhost/index.html,效果是一样的
server{
listen 80;
server_name localhost;
location /server{
#proxy_pass http://192.168.200.146;
proxy_pass http://192.168.200.146/;
}
}
当客户端访问 http://localhost/server/index.html
这个时候,第一个proxy_pass就变成了http://localhost/server/index.html
第二个proxy_pass就变成了http://localhost/index.html效果就不一样了。

proxy_set_header

该指令可以更改 Nginx 服务器接收到的客户端请求的请求头信息,然后将新的请求头发送给代理的服务器

语法proxy_set_header field value;
默认值proxy_set_header Host $proxy_host;
proxy_set_header Connection close;
位置http、server、location

需要注意的是,如果想要看到结果,必须在被代理的服务器上来获取添加的头信息。

被代理服务器: [192.168.200.146]

server {
listen 8080;
server_name localhost;
default_type text/plain;
return 200 $http_username;
}

代理服务器: [192.168.200.133]

server {
listen 8080;
server_name localhost;
location /server {
proxy_pass http://192.168.200.146:8080/;
proxy_set_header username TOM;
}
}

访问测试

proxy_redirect

该指令是用来重置头信息中的"Location"和"Refresh"的值。

语法proxy_redirect redirect replacement;
proxy_redirect default;
proxy_redirect off;
默认值proxy_redirect default;
位置http、server、location

为什么要用该指令?

服务端[192.168.200.146]

server {
listen 8081;
server_name localhost;
if (!-f $request_filename){
return 302 http://192.168.200.146;
}
}

代理服务端[192.168.200.133]

# 可以将location修改为代理服务器的ip
server {
listen 8081;
server_name localhost;
location / {
proxy_pass http://192.168.200.146:8081/;
proxy_redirect http://192.168.200.146 http://192.168.200.133;
}
}

该指令的几组选项

proxy_redirect redirect replacement;

redirect:目标,Location的值
replacement:要替换的值

proxy_redirect default;

default;
将location块的uri变量作为replacement,
将proxy_pass变量作为redirect进行替换

proxy_redirect off;

关闭proxy_redirect的功能

12.Nginx 反向代理实战

1581883378672

服务器 1,2,3 存在两种情况

第一种情况: 三台服务器的内容不一样。
第二种情况: 三台服务器的内容是一样。
  1. 如果服务器 1、服务器 2 和服务器 3 的内容不一样,那我们可以根据用户请求来分发到不同的服务器。
代理服务器
server {
listen 8082;
server_name localhost;
location /server1 {
proxy_pass http://192.168.200.146:9001/;
}
location /server2 {
proxy_pass http://192.168.200.146:9002/;
}
location /server3 {
proxy_pass http://192.168.200.146:9003/;
}
}

服务端
server1
server {
listen 9001;
server_name localhost;
default_type text/html;
return 200 '<h1>192.168.200.146:9001</h1>'
}
server2
server {
listen 9002;
server_name localhost;
default_type text/html;
return 200 '<h1>192.168.200.146:9002</h1>'
}
server3
server {
listen 9003;
server_name localhost;
default_type text/html;
return 200 '<h1>192.168.200.146:9003</h1>'
}
  1. 如果服务器 1、服务器 2 和服务器 3 的内容是一样的,该如何处理? 负载均衡。

14.Nginx 的安全控制

关于 web 服务器的安全是比较大的一个话题,里面所涉及的内容很多,Nginx 反向代理是如何来提升 web 服务器的安全呢?

安全隔离

什么是安全隔离?

通过代理分开了客户端到应用程序服务器端的连接,实现了安全措施。在反向代理之前设置防火墙,仅留一个入口供代理服务器访问。

1589908851340

如何使用 SSL 对流量进行加密

翻译成大家能熟悉的说法就是将我们常用的 http 请求转变成 https 请求,那么这两个之间的区别简单的来说两个都是 HTTP 协议,只不过 https 是身披 SSL 外壳的 http.

HTTPS 是一种通过计算机网络进行安全通信的传输协议。它经由 HTTP 进行通信,利用 SSL/TLS 建立全通信,加密数据包,确保数据的安全性。

SSL(Secure Sockets Layer)安全套接层

TLS(Transport Layer Security)传输层安全

上述这两个是为网络通信提供安全及数据完整性的一种安全协议,TLS 和 SSL 在传输层和应用层对网络连接进行加密。

总结来说为什么要使用 https:

http协议是明文传输数据,存在安全问题,而https是加密传输,相当于http+ssl,并且可以防止流量劫持。

Nginx 要想使用 SSL,需要满足一个条件即需要添加一个模块--with-http_ssl_module,而该模块在编译的过程中又需要 OpenSSL 的支持,这个我们之前已经准备好了。

nginx 添加 SSL 的支持

(1)完成 --with-http_ssl_module模块的增量添加

》将原有/usr/local/nginx/sbin/nginx进行备份
》拷贝nginx之前的配置信息
》在nginx的安装源码进行配置指定对应模块 ./configure --with-http_ssl_module
》通过make模板进行编译
》将objs下面的nginx移动到/usr/local/nginx/sbin下
》在源码目录下执行 make upgrade进行升级,这个可以实现不停机添加新模块的功能
Nginx 的 SSL 相关指令

因为刚才我们介绍过该模块的指令都是通过 ngx_http_ssl_module 模块来解析的。

ssl:该指令用来在指定的服务器开启 HTTPS,可以使用 listen 443 ssl,后面这种方式更通用些。

语法ssl on | off;
默认值ssl off;
位置http、server
server{
listen 443 ssl;
}

ssl_certificate:为当前这个虚拟主机指定一个带有 PEM 格式证书的证书。

语法ssl_certificate file;
默认值
位置http、server

ssl_certificate_key:该指令用来指定 PEM secret key 文件的路径

语法ssl_ceritificate_key file;
默认值
位置http、server

ssl_session_cache:该指令用来配置用于 SSL 会话的缓存

语法ssl_sesion_cache off|none|[builtin[:size]] [shared:name:size]
默认值ssl_session_cache none;
位置http、server

off:禁用会话缓存,客户端不得重复使用会话

none:禁止使用会话缓存,客户端可以重复使用,但是并没有在缓存中存储会话参数

builtin:内置 OpenSSL 缓存,仅在一个工作进程中使用。

shared:所有工作进程之间共享缓存,缓存的相关信息用 name 和 size 来指定

ssl_session_timeout:开启 SSL 会话功能后,设置客户端能够反复使用储存在缓存中的会话参数时间。

语法ssl_session_timeout time;
默认值ssl_session_timeout 5m;
位置http、server

ssl_ciphers:指出允许的密码,密码指定为 OpenSSL 支持的格式

语法ssl_ciphers ciphers;
默认值ssl_ciphers HIGH:!aNULL:!MD5;
位置http、server

可以使用openssl ciphers查看 openssl 支持的格式。

ssl_prefer_server_ciphers:该指令指定是否服务器密码优先客户端密码

语法ssl_perfer_server_ciphers on|off;
默认值ssl_perfer_server_ciphers off;
位置http、server
生成证书

方式一: 使用阿里云/腾讯云等第三方服务进行购买。

方式二: 使用 openssl 生成证书

先要确认当前系统是否有安装 openssl

openssl version

安装下面的命令进行生成

mkdir /root/cert
cd /root/cert
openssl genrsa -des3 -out server.key 1024
openssl req -new -key server.key -out server.csr
cp server.key server.key.org
openssl rsa -in server.key.org -out server.key
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
开启 SSL 实例
server {
listen 443 ssl;
server_name localhost;

ssl_certificate server.cert;
ssl_certificate_key server.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;
}
}

(4)验证

15.反向代理系统调优

反向代理值 Buffer 和 Cache

Buffer 翻译过来是"缓冲",Cache 翻译过来是"缓存"。

1581879638569

总结下:

相同点:
两种方式都是用来提供IO吞吐效率,都是用来提升Nginx代理的性能。
不同点:
缓冲主要用来解决不同设备之间数据传递速度不一致导致的性能低的问题,缓冲中的数据一旦此次操作完成后,就可以删除。
缓存主要是备份,将被代理服务器的数据缓存一份到代理服务器,这样的话,客户端再次获取相同数据的时候,就只需要从代理服务器上获取,效率较高,缓存中的数据可以重复使用,只有满足特定条件才会删除.

(1)Proxy Buffer 相关指令

proxy_buffering :该指令用来开启或者关闭代理服务器的缓冲区;

语法proxy_buffering on|off;
默认值proxy_buffering on;
位置http、server、location

proxy_buffers:该指令用来指定单个连接从代理服务器读取响应的缓存区的个数和大小。

语法proxy_buffers number size;
默认值proxy_buffers 8 4k | 8K;(与系统平台有关)
位置http、server、location

number:缓冲区的个数

size:每个缓冲区的大小,缓冲区的总大小就是 number*size

proxy_buffer_size:该指令用来设置从被代理服务器获取的第一部分响应数据的大小。保持与 proxy_buffers 中的 size 一致即可,当然也可以更小。

语法proxy_buffer_size size;
默认值proxy_buffer_size 4k | 8k;(与系统平台有关)
位置http、server、location

proxy_busy_buffers_size:该指令用来限制同时处于 BUSY 状态的缓冲总大小。

语法proxy_busy_buffers_size size;
默认值proxy_busy_buffers_size 8k|16K;
位置http、server、location

proxy_temp_path:当缓冲区存满后,仍未被 Nginx 服务器完全接受,响应数据就会被临时存放在磁盘文件上,该指令设置文件路径

语法proxy_temp_path path;
默认值proxy_temp_path proxy_temp;
位置http、server、location

注意 path 最多设置三层。

proxy_temp_file_write_size:该指令用来设置磁盘上缓冲文件的大小。

语法proxy_temp_file_write_size size;
默认值proxy_temp_file_write_size 8K|16K;
位置http、server、location

通用网站的配置

proxy_buffering on;
proxy_buffer_size 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;

根据项目的具体内容进行相应的调节。

16.Nginx 负载均衡

负载均衡概述

早期的网站流量和业务功能都比较简单,单台服务器足以满足基本的需求,但是随着互联网的发展,业务流量越来越大并且业务逻辑也跟着越来越复杂,单台服务器的性能及单点故障问题就凸显出来了,因此需要多台服务器进行性能的水平扩展及避免单点故障出现。那么如何将不同用户的请求流量分发到不同的服务器上呢?

1591631182469

负载均衡的原理及处理流程

系统的扩展可以分为纵向扩展和横向扩展。

纵向扩展是从单机的角度出发,通过增加系统的硬件处理能力来提升服务器的处理能力

横向扩展是通过添加机器来满足大型网站服务的处理能力。

1584602513812

这里面涉及到两个重要的角色分别是"应用集群"和"负载均衡器"。

应用集群:将同一应用部署到多台机器上,组成处理集群,接收负载均衡设备分发的请求,进行处理并返回响应的数据。

负载均衡器:将用户访问的请求根据对应的负载均衡算法,分发到集群中的一台服务器进行处理。

负载均衡的作用

1、解决服务器的高并发压力,提高应用程序的处理性能。

2、提供故障转移,实现高可用。

3、通过添加或减少服务器数量,增强网站的可扩展性。

4、在负载均衡器上进行过滤,可以提高系统的安全性。

17.负载均衡常用的处理方式

方式一:用户手动选择

这种方式比较原始,只要实现的方式就是在网站主页上面提供不同线路、不同服务器链接方式,让用户来选择自己访问的具体服务器,来实现负载均衡。

1584602887881

方式二:DNS 轮询方式

DNS

域名系统(服务)协议(DNS)是一种分布式网络目录服务,主要用于域名与 IP 地址的相互转换。

大多域名注册商都支持对同一个主机名添加多条 A 记录,这就是 DNS 轮询,DNS 服务器将解析请求按照 A 记录的顺序,随机分配到不同的 IP 上,这样就能完成简单的负载均衡。DNS 轮询的成本非常低,在一些不重要的服务器,被经常使用。

1591010973996

如下是我们为某一个域名添加的 IP 地址,用 2 台服务器来做负载均衡。

1590064506355

验证:

ping www.nginx521.cn

清空本地的 dns 缓存

ipconfig/flushdns

我们发现使用 DNS 来实现轮询,不需要投入过多的成本,虽然 DNS 轮询成本低廉,但是 DNS 负载均衡存在明显的缺点。

1.可靠性低

假设一个域名 DNS 轮询多台服务器,如果其中的一台服务器发生故障,那么所有的访问该服务器的请求将不会有所回应,即使你将该服务器的 IP 从 DNS 中去掉,但是由于各大宽带接入商将众多的 DNS 存放在缓存中,以节省访问时间,导致 DNS 不会实时更新。所以 DNS 轮流上一定程度上解决了负载均衡问题,但是却存在可靠性不高的缺点。

2.负载均衡不均衡

DNS 负载均衡采用的是简单的轮询负载算法,不能区分服务器的差异,不能反映服务器的当前运行状态,不能做到为性能好的服务器多分配请求,另外本地计算机也会缓存已经解析的域名到 IP 地址的映射,这也会导致使用该 DNS 服务器的用户在一定时间内访问的是同一台 Web 服务器,从而引发 Web 服务器减的负载不均衡。

负载不均衡则会导致某几台服务器负荷很低,而另外几台服务器负荷确很高,处理请求的速度慢,配置高的服务器分配到的请求少,而配置低的服务器分配到的请求多。

方式三:四/七层负载均衡

介绍四/七层负载均衡之前,我们先了解一个概念,OSI(open system interconnection),叫开放式系统互联模型,这个是由国际标准化组织 ISO 指定的一个不基于具体机型、操作系统或公司的网络体系结构。该模型将网络通信的工作分为七层。

1584693830966

应用层:为应用程序提供网络服务。

表示层:对数据进行格式化、编码、加密、压缩等操作。

会话层:建立、维护、管理会话连接。

传输层:建立、维护、管理端到端的连接,常见的有 TCP/UDP。

网络层:IP 寻址和路由选择

数据链路层:控制网络层与物理层之间的通信。

物理层:比特流传输。

所谓四层负载均衡指的是 OSI 七层模型中的传输层,主要是基于 IP+PORT 的负载均衡

实现四层负载均衡的方式:
硬件:F5 BIG-IP、Radware等
软件:LVS、Nginx、Hayproxy等

所谓的七层负载均衡指的是在应用层,主要是基于虚拟的 URL 或主机 IP 的负载均衡

实现七层负载均衡的方式:
软件:Nginx、Hayproxy等

四层和七层负载均衡的区别

四层负载均衡数据包是在底层就进行了分发,而七层负载均衡数据包则在最顶端进行分发,所以四层负载均衡的效率比七层负载均衡的要高。
四层负载均衡不识别域名,而七层负载均衡识别域名。

处理四层和七层负载以为其实还有二层、三层负载均衡,二层是在数据链路层基于 mac 地址来实现负载均衡,三层是在网络层一般采用虚拟 IP 地址的方式实现负载均衡。

实际环境采用的模式

四层负载(LVS)+七层负载(Nginx)

18.Nginx 七层负载均衡

Nginx 要实现七层负载均衡需要用到 proxy_pass 代理模块配置。Nginx 默认安装支持这个模块,我们不需要再做任何处理。Nginx 的负载均衡是在 Nginx 的反向代理基础上把用户的请求根据指定的算法分发到一组【upstream 虚拟服务池】。

Nginx 七层负载均衡的指令

upstream 指令

该指令是用来定义一组服务器,它们可以是监听不同端口的服务器,并且也可以是同时监听 TCP 和 Unix socket 的服务器。服务器可以指定不同的权重,默认为 1。

语法upstream name {...}
默认值
位置http
server 指令

该指令用来指定后端服务器的名称和一些参数,可以使用域名、IP、端口或者 unix socket

语法server name [paramerters]
默认值
位置upstream

Nginx 七层负载均衡的实现流程

1590248160635

服务端设置

server {
listen 9001;
server_name localhost;
default_type text/html;
location /{
return 200 '<h1>192.168.200.146:9001</h1>';
}
}
server {
listen 9002;
server_name localhost;
default_type text/html;
location /{
return 200 '<h1>192.168.200.146:9002</h1>';
}
}
server {
listen 9003;
server_name localhost;
default_type text/html;
location /{
return 200 '<h1>192.168.200.146:9003</h1>';
}
}

负载均衡器设置

upstream backend{
server 192.168.200.146:9091;
server 192.168.200.146:9092;
server 192.168.200.146:9093;
}
server {
listen 8083;
server_name localhost;
location /{
proxy_pass http://backend;
}
}

负载均衡状态

代理服务器在负责均衡调度中的状态有以下几个:

状态概述
down当前的 server 暂时不参与负载均衡
backup预留的备份服务器
max_fails允许请求失败的次数
fail_timeout经过 max_fails 失败后, 服务暂停时间
max_conns限制最大的接收连接数
down

down:将该服务器标记为永久不可用,那么该代理服务器将不参与负载均衡。

upstream backend{
server 192.168.200.146:9001 down;
server 192.168.200.146:9002
server 192.168.200.146:9003;
}
server {
listen 8083;
server_name localhost;
location /{
proxy_pass http://backend;
}
}

该状态一般会对需要停机维护的服务器进行设置。

backup

backup:将该服务器标记为备份服务器,当主服务器不可用时,将用来传递请求。

upstream backend{
server 192.168.200.146:9001 down;
server 192.168.200.146:9002 backup;
server 192.168.200.146:9003;
}
server {
listen 8083;
server_name localhost;
location /{
proxy_pass http://backend;
}
}

此时需要将 9094 端口的访问禁止掉来模拟下唯一能对外提供访问的服务宕机以后,backup 的备份服务器就要开始对外提供服务,此时为了测试验证,我们需要使用防火墙来进行拦截。

介绍一个工具firewall-cmd,该工具是 Linux 提供的专门用来操作 firewall 的。

查询防火墙中指定的端口是否开放

firewall-cmd --query-port=9001/tcp

如何开放一个指定的端口

firewall-cmd --permanent --add-port=9002/tcp

批量添加开发端口

firewall-cmd --permanent --add-port=9001-9003/tcp

如何移除一个指定的端口

firewall-cmd --permanent --remove-port=9003/tcp

重新加载

firewall-cmd --reload

其中

​ --permanent 表示设置为持久

​ --add-port 表示添加指定端口

​ --remove-port 表示移除指定端口

max_conns

max_conns=number:用来设置代理服务器同时活动链接的最大数量,默认为 0,表示不限制,使用该配置可以根据后端服务器处理请求的并发量来进行设置,防止后端服务器被压垮。

max_fails 和 fail_timeout

max_fails=number:设置允许请求代理服务器失败的次数,默认为 1。

fail_timeout=time:设置经过 max_fails 失败后,服务暂停的时间,默认是 10 秒。

upstream backend{
server 192.168.200.133:9001 down;
server 192.168.200.133:9002 backup;
server 192.168.200.133:9003 max_fails=3 fail_timeout=15;
}
server {
listen 8083;
server_name localhost;
location /{
proxy_pass http://backend;
}
}

负载均衡策略

介绍完 Nginx 负载均衡的相关指令后,我们已经能实现将用户的请求分发到不同的服务器上,那么除了采用默认的分配方式以外,我们还能采用什么样的负载算法?

Nginx 的 upstream 支持如下六种方式的分配算法,分别是:

算法名称说明
轮询默认方式
weight权重方式
ip_hash依据 ip 分配方式
least_conn依据最少连接方式
url_hash依据 URL 分配方式
fair依据响应时间方式
轮询

是 upstream 模块负载均衡默认的策略。每个请求会按时间顺序逐个分配到不同的后端服务器。轮询不需要额外的配置。

upstream backend{
server 192.168.200.146:9001 weight=1;
server 192.168.200.146:9002;
server 192.168.200.146:9003;
}
server {
listen 8083;
server_name localhost;
location /{
proxy_pass http://backend;
}
}
weight 加权[加权轮询]

weight=number:用来设置服务器的权重,默认为 1,权重数据越大,被分配到请求的几率越大;该权重值,主要是针对实际工作环境中不同的后端服务器硬件配置进行调整的,所有此策略比较适合服务器的硬件配置差别比较大的情况。

upstream backend{
server 192.168.200.146:9001 weight=10;
server 192.168.200.146:9002 weight=5;
server 192.168.200.146:9003 weight=3;
}
server {
listen 8083;
server_name localhost;
location /{
proxy_pass http://backend;
}
}
ip_hash

当对后端的多台动态应用服务器做负载均衡时,ip_hash 指令能够将某个客户端 IP 的请求通过哈希算法定位到同一台后端服务器上。这样,当来自某一个 IP 的用户在后端 Web 服务器 A 上登录后,在访问该站点的其他 URL,能保证其访问的还是后端 web 服务器 A。

语法ip_hash;
默认值
位置upstream
upstream backend{
ip_hash;
server 192.168.200.146:9001;
server 192.168.200.146:9002;
server 192.168.200.146:9003;
}
server {
listen 8083;
server_name localhost;
location /{
proxy_pass http://backend;
}
}

需要额外多说一点的是使用 ip_hash 指令无法保证后端服务器的负载均衡,可能导致有些后端服务器接收到的请求多,有些后端服务器接收的请求少,而且设置后端服务器权重等方法将不起作用。

1591706748677

least_conn

最少连接,把请求转发给连接数较少的后端服务器。轮询算法是把请求平均的转发给各个后端,使它们的负载大致相同;但是,有些请求占用的时间很长,会导致其所在的后端负载较高。这种情况下,least_conn 这种方式就可以达到更好的负载均衡效果。

upstream backend{
least_conn;
server 192.168.200.146:9001;
server 192.168.200.146:9002;
server 192.168.200.146:9003;
}
server {
listen 8083;
server_name localhost;
location /{
proxy_pass http://backend;
}
}

此负载均衡策略适合请求处理时间长短不一造成服务器过载的情况。

1591809623736

url_hash

按访问 url 的 hash 结果来分配请求,使每个 url 定向到同一个后端服务器,要配合缓存命中来使用。同一个资源多次请求,可能会到达不同的服务器上,导致不必要的多次下载,缓存命中率不高,以及一些资源时间的浪费。而使用 url_hash,可以使得同一个 url(也就是同一个资源请求)会到达同一台服务器,一旦缓存住了资源,再此收到请求,就可以从缓存中读取。

upstream backend{
hash &request_uri;
server 192.168.200.146:9001;
server 192.168.200.146:9002;
server 192.168.200.146:9003;
}
server {
listen 8083;
server_name localhost;
location /{
proxy_pass http://backend;
}
}

访问如下地址:

http://192.168.200.133:8083/a
http://192.168.200.133:8083/b
http://192.168.200.133:8083/c

1591812222306

fair

fair 采用的不是内建负载均衡使用的轮换的均衡算法,而是可以根据页面大小、加载时间长短智能的进行负载均衡。那么如何使用第三方模块的 fair 负载均衡策略。

upstream backend{
fair;
server 192.168.200.146:9001;
server 192.168.200.146:9002;
server 192.168.200.146:9003;
}
server {
listen 8083;
server_name localhost;
location /{
proxy_pass http://backend;
}
}

但是如何直接使用会报错,因为 fair 属于第三方模块实现的负载均衡。需要添加nginx-upstream-fair,如何添加对应的模块:

  1. 下载 nginx-upstream-fair 模块
下载地址为:
https://github.com/gnosek/nginx-upstream-fair
  1. 将下载的文件上传到服务器并进行解压缩
unzip nginx-upstream-fair-master.zip
  1. 重命名资源
mv nginx-upstream-fair-master fair
  1. 使用./configure 命令将资源添加到 Nginx 模块中
./configure --add-module=/root/fair
  1. 编译
make

编译可能会出现如下错误,ngx_http_upstream_srv_conf_t 结构中缺少 default_port

1584941470457

解决方案:

在 Nginx 的源码中 src/http/ngx_http_upstream.h,找到ngx_http_upstream_srv_conf_s,在模块中添加添加 default_port 属性

in_port_t default_port

1584943399597

然后再进行 make.

  1. 更新 Nginx

​ 6.1 将 sbin 目录下的 nginx 进行备份

mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginxold

​ 6.2 将安装目录下的 objs 中的 nginx 拷贝到 sbin 目录

cd objs
cp nginx /usr/local/nginx/sbin

​ 6.3 更新 Nginx

cd ../
make upgrade
  1. 编译测试使用 Nginx

上面介绍了 Nginx 常用的负载均衡的策略,有人说是 5 种,是把轮询和加权轮询归为一种,也有人说是 6 种。那么在咱们以后的开发中到底使用哪种,这个需要根据实际项目的应用场景来决定的。

负载均衡案例

案例一:对所有请求实现一般轮询规则的负载均衡
upstream backend{
server 192.168.200.146:9001;
server 192.168.200.146:9002;
server 192.168.200.146:9003;
}
server {
listen 8083;
server_name localhost;
location /{
proxy_pass http://backend;
}
}
案例二:对所有请求实现加权轮询规则的负载均衡
upstream backend{
server 192.168.200.146:9001 weight=7;
server 192.168.200.146:9002 weight=5;
server 192.168.200.146:9003 weight=3;
}
server {
listen 8083;
server_name localhost;
location /{
proxy_pass http://backend;
}
}
案例三:对特定资源实现负载均衡
upstream videobackend{
server 192.168.200.146:9001;
server 192.168.200.146:9002;
}
upstream filebackend{
server 192.168.200.146:9003;
server 192.168.200.146:9004;
}
server {
listen 8084;
server_name localhost;
location /video/ {
proxy_pass http://videobackend;
}
location /file/ {
proxy_pass http://filebackend;
}
}
案例四:对不同域名实现负载均衡
upstream itcastbackend{
server 192.168.200.146:9001;
server 192.168.200.146:9002;
}
upstream itheimabackend{
server 192.168.200.146:9003;
server 192.168.200.146:9004;
}
server {
listen 8085;
server_name www.itcast.cn;
location / {
proxy_pass http://itcastbackend;
}
}
server {
listen 8086;
server_name www.itheima.cn;
location / {
proxy_pass http://itheimabackend;
}
}
案例五:实现带有 URL 重写的负载均衡
upstream backend{
server 192.168.200.146:9001;
server 192.168.200.146:9002;
server 192.168.200.146:9003;
}
server {
listen 80;
server_name localhost;
location /file/ {
rewrite ^(/file/.*) /server/$1 last;
}
location / {
proxy_pass http://backend;
}
}

19.Nginx 四层负载均衡

Nginx 在 1.9 之后,增加了一个 stream 模块,用来实现四层协议的转发、代理、负载均衡等。stream 模块的用法跟 http 的用法类似,允许我们配置一组 TCP 或者 UDP 等协议的监听,然后通过 proxy_pass 来转发我们的请求,通过 upstream 添加多个后端服务,实现负载均衡。

四层协议负载均衡的实现,一般都会用到 LVS、HAProxy、F5 等,要么很贵要么配置很麻烦,而 Nginx 的配置相对来说更简单,更能快速完成工作。

添加 stream 模块的支持

Nginx 默认是没有编译这个模块的,需要使用到 stream 模块,那么需要在编译的时候加上--with-stream

完成添加--with-stream的实现步骤:

》将原有/usr/local/nginx/sbin/nginx进行备份
》拷贝nginx之前的配置信息
》在nginx的安装源码进行配置指定对应模块 ./configure --with-stream
》通过make模板进行编译
》将objs下面的nginx移动到/usr/local/nginx/sbin下
》在源码目录下执行 make upgrade进行升级,这个可以实现不停机添加新模块的功能

Nginx 四层负载均衡的指令

stream 指令

该指令提供在其中指定流服务器指令的配置文件上下文。和 http 指令同级。

语法stream { ... }
默认值
位置main
upstream 指令

该指令和 http 的 upstream 指令是类似的。

四层负载均衡的案例

需求分析

1591897178807

实现步骤

(1)准备 Redis 服务器,在一条服务器上准备三个 Redis,端口分别是 6379,6378

1.上传 redis 的安装包,redis-4.0.14.tar.gz

2.将安装包进行解压缩

tar -zxf redis-4.0.14.tar.gz

3.进入 redis 的安装包

cd redis-4.0.14

4.使用 make 和 install 进行编译和安装

make PREFIX=/usr/local/redis/redis01 install

5.拷贝 redis 配置文件redis.conf到/usr/local/redis/redis01/bin 目录中

cp redis.conf /usr/local/redis/redis01/bin

6.修改 redis.conf 配置文件

port 6379 #redis的端口
daemonize yes #后台启动redis

7.将 redis01 复制一份为 redis02

cd /usr/local/redis
cp -r redis01 redis02

8.将 redis02 文件文件夹中的 redis.conf 进行修改

port 6378 #redis的端口
daemonize yes #后台启动redis

9.分别启动,即可获取两个 Redis.并查看

ps -ef | grep redis

使用 Nginx 将请求分发到不同的 Redis 服务器上。

(2)准备 Tomcat 服务器.

1.上传 tomcat 的安装包,apache-tomcat-8.5.56.tar.gz

2.将安装包进行解压缩

tar -zxf apache-tomcat-8.5.56.tar.gz

3.进入 tomcat 的 bin 目录

cd apache-tomcat-8.5.56/bin
./startup

nginx.conf 配置

stream {
upstream redisbackend {
server 192.168.200.146:6379;
server 192.168.200.146:6378;
}
upstream tomcatbackend {
server 192.168.200.146:8080;
}
server {
listen 81;
proxy_pass redisbackend;
}
server {
listen 82;
proxy_pass tomcatbackend;
}
}

访问测试。

20.Nginx 缓存集成

缓存的概念

缓存就是数据交换的缓冲区(称作:Cache),当用户要获取数据的时候,会先从缓存中去查询获取数据,如果缓存中有就会直接返回给用户,如果缓存中没有,则会发请求从服务器重新查询数据,将数据返回给用户的同时将数据放入缓存,下次用户就会直接从缓存中获取数据。

1591944051969

缓存其实在很多场景中都有用到,比如:

场景作用
操作系统磁盘缓存减少磁盘机械操作
数据库缓存减少文件系统的 IO 操作
应用程序缓存减少对数据库的查询
Web 服务器缓存减少对应用服务器请求次数
浏览器缓存减少与后台的交互次数

缓存的优点

​ 1.减少数据传输,节省网络流量,加快响应速度,提升用户体验;

​ 2.减轻服务器压力;

​ 3.提供服务端的高可用性;

缓存的缺点

​ 1.数据的不一致

​ 2.增加成本

1582295367198

本次课程注解讲解的是 Nginx,Nginx 作为 web 服务器,Nginx 作为 Web 缓存服务器,它介于客户端和应用服务器之间,当用户通过浏览器访问一个 URL 时,web 缓存服务器会去应用服务器获取要展示给用户的内容,将内容缓存到自己的服务器上,当下一次请求到来时,如果访问的是同一个 URL,web 缓存服务器就会直接将之前缓存的内容返回给客户端,而不是向应用服务器再次发送请求。web 缓存降低了应用服务器、数据库的负载,减少了网络延迟,提高了用户访问的响应速度,增强了用户的体验。

Nginx 的 web 缓存服务

Nginx 是从 0.7.48 版开始提供缓存功能。Nginx 是基于 Proxy Store 来实现的,其原理是把 URL 及相关组合当做 Key,在使用 MD5 算法对 Key 进行哈希,得到硬盘上对应的哈希目录路径,从而将缓存内容保存在该目录中。它可以支持任意 URL 连接,同时也支持 404/301/302 这样的非 200 状态码。Nginx 即可以支持对指定 URL 或者状态码设置过期时间,也可以使用 purge 命令来手动清除指定 URL 的缓存。

1591947990200

Nginx 缓存设置的相关指令

Nginx 的 web 缓存服务主要是使用ngx_http_proxy_module模块相关指令集来完成,接下来我们把常用的指令来进行介绍下。

proxy_cache_path

该指定用于设置缓存文件的存放路径

语法proxy_cache_path path [levels=number]
keys_zone=zone_name:zone_size [inactive=time][max_size=size];
默认值
位置http

path:缓存路径地址,如:

/usr/local/proxy_cache

levels: 指定该缓存空间对应的目录,最多可以设置 3 层,每层取值为 1|2 如 :

levels=1:2 缓存空间有两层目录,第一次是1个字母,第二次是2个字母
举例说明:
itheima[key]通过MD5加密以后的值为 43c8233266edce38c2c9af0694e2107d
levels=1:2 最终的存储路径为/usr/local/proxy_cache/d/07
levels=2:1:2 最终的存储路径为/usr/local/proxy_cache/7d/0/21
levels=2:2:2 最终的存储路径为??/usr/local/proxy_cache/7d/10/e2

keys_zone:用来为这个缓存区设置名称和指定大小,如:

keys_zone=itcast:200m 缓存区的名称是itcast,大小为200M,1M大概能存储8000个keys

inactive:指定缓存的数据多次时间未被访问就将被删除,如:

inactive=1d 缓存数据在1天内没有被访问就会被删除

max_size:设置最大缓存空间,如果缓存空间存满,默认会覆盖缓存时间最长的资源,如:

max_size=20g

配置实例:

http{
proxy_cache_path /usr/local/proxy_cache keys_zone=itcast:200m levels=1:2:1 inactive=1d max_size=20g;
}

proxy_cache

该指令用来开启或关闭代理缓存,如果是开启则自定使用哪个缓存区来进行缓存。

语法proxy_cache zone_name|off;
默认值proxy_cache off;
位置http、server、location

zone_name:指定使用缓存区的名称

proxy_cache_key

该指令用来设置 web 缓存的 key 值,Nginx 会根据 key 值 MD5 哈希存缓存。

语法proxy_cache_key key;
默认值proxy_cache_key $scheme$proxy_host$request_uri;
位置http、server、location

proxy_cache_valid

该指令用来对不同返回状态码的 URL 设置不同的缓存时间

语法proxy_cache_valid [code ...] time;
默认值
位置http、server、location

如:

proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
为200和302的响应URL设置10分钟缓存,为404的响应URL设置1分钟缓存
proxy_cache_valid any 1m;
对所有响应状态码的URL都设置1分钟缓存

proxy_cache_min_uses

该指令用来设置资源被访问多少次后被缓存

语法proxy_cache_min_uses number;
默认值proxy_cache_min_uses 1;
位置http、server、location

proxy_cache_methods

该指令用户设置缓存哪些 HTTP 方法

语法proxy_cache_methods GET|HEAD|POST;
默认值proxy_cache_methods GET HEAD;
位置http、server、location

默认缓存 HTTP 的 GET 和 HEAD 方法,不缓存 POST 方法。

21.Nginx 缓存设置案例

需求分析

1591959569463

步骤实现

1.环境准备

应用服务器的环境准备

(1)在 192.168.200.146 服务器上的 tomcat 的 webapps 下面添加一个 js 目录,并在 js 目录中添加一个 jquery.js 文件

(2)启动 tomcat

(3)访问测试

http://192.168.200.146:8080/js/jquery.js

Nginx 的环境准备

(1)完成 Nginx 反向代理配置

http{
upstream backend{
server 192.168.200.146:8080;
}
server {
listen 8080;
server_name localhost;
location / {
proxy_pass http://backend/js/;
}
}
}

(2)完成 Nginx 缓存配置

4.添加缓存配置

http{
proxy_cache_path /usr/local/proxy_cache levels=2:1 keys_zone=itcast:200m inactive=1d max_size=20g;
upstream backend{
server 192.168.200.146:8080;
}
server {
listen 8080;
server_name localhost;
location / {
proxy_cache itcast;
proxy_cache_key itheima;
proxy_cache_min_uses 5;
proxy_cache_valid 200 5d;
proxy_cache_valid 404 30s;
proxy_cache_valid any 1m;
add_header nginx-cache "$upstream_cache_status";
proxy_pass http://backend/js/;
}
}
}

22.Nginx 缓存的清除

方式一:删除对应的缓存目录

rm -rf /usr/local/proxy_cache/......

方式二:使用第三方扩展模块

ngx_cache_purge

(1)下载 ngx_cache_purge 模块对应的资源包,并上传到服务器上。

ngx_cache_purge-2.3.tar.gz

(2)对资源文件进行解压缩

tar -zxf ngx_cache_purge-2.3.tar.gz

(3)修改文件夹名称,方便后期配置

mv ngx_cache_purge-2.3 purge

(4)查询 Nginx 的配置参数

nginx -V

(5)进入 Nginx 的安装目录,使用./configure 进行参数配置

./configure --add-module=/root/nginx/module/purge

(6)使用 make 进行编译

make

(7)将 nginx 安装目录的 nginx 二级制可执行文件备份

mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginxold

(8)将编译后的 objs 中的 nginx 拷贝到 nginx 的 sbin 目录下

cp objs/nginx /usr/local/nginx/sbin

(9)使用 make 进行升级

make upgrade

(10)在 nginx 配置文件中进行如下配置

server{
location ~/purge(/.*) {
proxy_cache_purge itcast itheima;
}
}

Nginx 设置资源不缓存

前面咱们已经完成了 Nginx 作为 web 缓存服务器的使用。但是我们得思考一个问题就是不是所有的数据都适合进行缓存。比如说对于一些经常发生变化的数据。如果进行缓存的话,就很容易出现用户访问到的数据不是服务器真实的数据。所以对于这些资源我们在缓存的过程中就需要进行过滤,不进行缓存。

Nginx 也提供了这块的功能设置,需要使用到如下两个指令

proxy_no_cache

该指令是用来定义不将数据进行缓存的条件。

语法proxy_no_cache string ...;
默认值
位置http、server、location

配置实例

proxy_no_cache $cookie_nocache $arg_nocache $arg_comment;

proxy_cache_bypass

该指令是用来设置不从缓存中获取数据的条件。

语法proxy_cache_bypass string ...;
默认值
位置http、server、location

配置实例

proxy_cache_bypass $cookie_nocache $arg_nocache $arg_comment;

上述两个指令都有一个指定的条件,这个条件可以是多个,并且多个条件中至少有一个不为空且不等于"0",则条件满足成立。上面给的配置实例是从官方网站获取的,里面使用到了三个变量,分别是$cookie_nocache、$arg_nocache、$arg_comment

这三个参数分别代表的含义是:

$cookie_nocache
指的是当前请求的cookie中键的名称为nocache对应的值
$arg_nocache$arg_comment
指的是当前请求的参数中属性名为nocache和comment对应的属性值

案例演示下:

log_format params $cookie_nocache | $arg_nocache | $arg_comment
server{
listen 8081;
server_name localhost;
location /{
access_log logs/access_params.log params;
add_header Set-Cookie 'nocache=999';
root html;
index index.html;
}
}

案例实现

设置不缓存资源的配置方案

server{
listen 8080;
server_name localhost;
location / {
if ($request_uri ~ /.*\.js$){
set $nocache 1;
}
proxy_no_cache $nocache $cookie_nocache $arg_nocache $arg_comment;
proxy_cache_bypass $nocache $cookie_nocache $arg_nocache $arg_comment;
}
}