Nginx正向/反向代理与负载均衡策略

Nginx正向/反向代理与负载均衡策略

1、Nginx

1.1、什么是Nginx

Nginx是一款高性能的http服务器/反向代理服务器及电子邮件(IMAP/POP~3~)代理服务器。官方测试nginx能够支撑5万并发链接,并且cpu、内存等资源消耗却非常低,运行非常稳定。

1.2、Nignx的应用场景

  1. http服务器 。Nginx是一个http服务可以独立提供 http 服务。可以做网页静态服务器
  2. 虚拟主机。可以实现在一台服务器虚拟出多个网站,例如个人网站使用的虚拟主机。
  3. 反向代理,负载均衡。当网站的访问量达到一定程度后,单台服务器不能满足用户的请求时,需要用多台服务器集群可以使用nginx做反向代理。并且多台服务器可以平均分担负载,不会因为某台服务器负载高宕机而某台服务器闲置的情况。

1.3、Nginx安装-Windows

  1. 进入 Nginx 官网: [Nginx 官网](nginx: download)
    • Mainline 是 Nginx 目前主力在做的版本,可以说是开发版
    • Stable version:最新稳定版,生产环境上建议使用的版本
    • Legacy versions:遗留的老版本的稳定版
  1. 等待下载完成后解压,注意解压目录不要有中文,在解压目录处打开 cmd 窗口,启动nginx
  1. 在浏览器输入 :localhost:80 ,看到如下页面即表示启动成功

注意:

  • 如果使用cmd命令窗口启动nginx, 关闭cmd窗口是不能结束nginx进程的。
  • 下述命令请在解压目录路径下进入 cmd 命令行执行
bash 复制代码
nginx -v  # 查看nginx的版本号

nginx -s stop # 快速停止或关闭nginx

nginx -s quit # 正常停止或关闭nginx

nginx -s reload # 配置文件nginx.conf修改重载命令

nginx的配置文件是conf目录下的nginx.conf,默认配置的nginx监听的端口为80,如果80端口被占用可以修改为未被占用的端口即可。

当我们修改了nginx的配置文件nginx.conf 时,不需要关闭nginx后重新启动nginx,只需要执行命令 nginx -s reload 即可让改动生效。

1.4、Nginx安装-Linux

在Linux下安装Nginx,需要先安装4个依赖环境,分别是 gcc、pcre、zlib、openssl

  1. 安装gcc环境
bash 复制代码
yum -y install gcc-c++ 
  1. 安装PCRE(PCRE是一个Perl库,包括perl兼容的正则表达式库。nginx的http模块使用pcre来解析正则表达式,所以需要在linux上安装pcre库)
bash 复制代码
yum install -y pcre pcre-devel
  1. 安装zlib(zlib库提供了很多种压缩和解压缩方式,nginx使用zlib对http包的内容进行gzip,所以需要在Linux上安装zlib库)
bash 复制代码
yum install -y zlib zlib-devel
  1. 安装OpenSSL(OpenSSL 是一个强大的安全套接字层密码库,囊括主要的密码算法、常用的密钥和证书封装管理功能及 SSL 协议,并提供丰富的应用程序供测试或其它目的使用。nginx 不仅支持 http 协议,还支持 https(即在ssl协议上传输http),所以需要在 Centos 安装 OpenSSL 库。)
bash 复制代码
yum install -y openssl openssl-devel
  1. 进入 Nginx 官网: [Nginx 官网](nginx: download),手动下载 .tar.gz安装包
  1. 下载完毕上传到服务器上 /root,解压
bash 复制代码
# 1.解压nginx安装包
tar -zxvf nginx-1.24.0.tar.gz
  1. 配置configure
bash 复制代码
# 2.配置configure
./configure --prefix=/usr/local/nginx  # --prefix=/usr/local/nginx 指安装路径
  1. 执行make
bash 复制代码
# 3.执行make
make 

# 4.执行 make install
make install
  1. 查找安装路径
bash 复制代码
# 5. 找nginx目录
whereis nginx
  1. 进入nginx 目录,启动nginx
bash 复制代码
./nginx # 启动nginx

./nginx -s stop # 停止nginx

./nginx -s quit # 安全退出

./nginx -s reload # 重新加载配置文件

ps aux|grep nginx # 查看nginx进程

若 yum 下载太慢,可以尝试换源:https://blog.csdn.net/qq_45773650/article/details/108326429

  • 我这里直接使用宝塔面板进行一键安装,所以不用上述那么多步骤,默认软件安装目录均在:根目录/www/server 里面

查看nginx进程:

bash 复制代码
ps aux|grep nginx

宝塔安装的 nginx 是开机自启的,我们只需要在 www/server/nginx/conf/nginx.conf 里面写入:

nginx 复制代码
server {
    listen 80;
    # 
    server_name 192.168.6.136;
    
    location / {
        root html;
        index index.html index.htm;
       # 万一访问404,则添加下面代码
       # try_files  $uri $uri/ /index.html;
    }
}

更新nginx配置:./nginx -s reload , 之后访问:http://192.168.6.136

如果加了上述代码后仍然访问404,可以去看一下 html/index.html 的代码,不知道为何我的代码就是404代码,所以显示404,搞得我排查了好久,天杀的!

  • 扩展:检查 nginx 的配置文件是否正确 nginx -t

2、Nginx基础使用

2.1、目录结构

进入Nginx的主目录我们可以看到这些文件夹:

bash 复制代码
# 用来存放配置的文件相关
conf 

# 用来存放静态文件的默认目录 html、css等
html

# 日志 
logs 

# nginx 的主程序
sbin 

# 使进程在后台运行,并将日志打到指定的日志文件或者udp服务器
uwsgi_temp

# 以下几个文件夹在刚安装后是没有的,主要用来存放运行过程中的临时文件
client_body_temp 

fastcgi_temp

proxy_temp

scgi_temp
bash 复制代码
[root@localhost ~]# tree /usr/local/nginx
/usr/local/nginx
├── client_body_temp                 # POST 大文件暂存目录
├── conf                             # Nginx所有配置文件的目录
│   ├── fastcgi.conf                 # fastcgi相关参数的配置文件
│   ├── fastcgi.conf.default         # fastcgi.conf的原始备份文件
│   ├── fastcgi_params               # fastcgi的参数文件
│   ├── fastcgi_params.default       
│   ├── koi-utf
│   ├── koi-win
│   ├── mime.types                   # 媒体类型
│   ├── mime.types.default
│   ├── nginx.conf                   #这是Nginx默认的主配置文件,日常使用和修改的文件
│   ├── nginx.conf.default
│   ├── scgi_params                  # scgi相关参数文件
│   ├── scgi_params.default  
│   ├── uwsgi_params                 # uwsgi相关参数文件
│   ├── uwsgi_params.default
│   └── win-utf
├── fastcgi_temp                     # fastcgi临时数据目录
├── html                             # Nginx默认站点目录
│   ├── 50x.html                     # 错误页面优雅替代显示文件,例如出现502错误时会调用此页面
│   └── index.html                   # 默认的首页文件
├── logs                             # Nginx日志目录
│   ├── access.log                   # 访问日志文件
│   ├── error.log                    # 错误日志文件
│   └── nginx.pid                    # pid文件,Nginx进程启动后,会把所有进程的ID号写到此文件
├── proxy_temp                       # 临时目录
├── sbin                             # Nginx 可执行文件目录
│   └── nginx                        # Nginx 二进制可执行程序
├── scgi_temp                        # 临时目录
└── uwsgi_temp                       # 临时目录

2.2、基本运行原理

终端PC机在发起请求http://192.168.44.101/index.html 时,Nginx是怎么处理的呢?

Nginx 首先运行/sbin/nginx 可执行文件,开启 Master 进程进行读取并检验配置文件 /conf/nginx.conf ,如果没有错误则会开启一个子进程Worker进行响应请求。

2.3、Nginx配置文件

  • nginx的配置文件是conf目录下的 nginx.conf,我们可以直接使用Xftp的右键用记事本打开,也可以下载到本地用编辑器打开

配置文件分为三个大模块

  • 全局配置
  • 事件
  • HTTP配置
nginx 复制代码
# 全局配置

# 设置worker进程的用户,默认为 nobody
user  nobody;

# worker进程工作数设置,一般来说CPU有几个,就设置几个,或者设置为N-1也行,默认为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 {
    # 默认使用epoll
    use epoll;
    # 每个worker允许连接的客户端最大连接数
    worker_connections  1024;
}


# http配置
http {
	# http的全局配置
	# include 引入外部配置,提高可读性,避免单个配置文件过大
    include       mime.types;
    default_type  application/octet-stream;

	# 设定日志格式,main为定义的格式名称,如此 access_log 就可以直接使用这个变量了
	# $remote_addr:客户端ip   $remote_user:远程客户端用户名
	# $time_local:时间和时区  $request:请求的url以及method
    # $status:响应状态码     $body_bytes_sent:响应客户端内容字节数
    # $http_referer:记录用户从哪个链接跳转过来的
    # $http_user_agent:用户所使用的代理,一般来时都是浏览器
    # $http_x_forwarded_for:通过代理服务器来记录客户端的ip
    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;


	# sendfile使用高效文件传输,提升传输性能。
	# 启用后才能使用tcp_nopush,是指当数据表累积一定大小后才发送,提高了效率
    # 对于普通应用,必须设为on.如果用来进行下载等应用磁盘IO重负载应用,可设置为off,以平衡磁盘与网络IO处理速度。 
    sendfile        on;
    tcp_nopush     on;

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

	# gzip启用压缩,html/js/css压缩后传输会更快
    gzip  on;

	# 服务配置
    server {
        # listen 监听端口
        listen       80;
        # 服务器名称,默认为localhost
        server_name  localhost;


	#访问地址 / 表示根目录
        location / {
            # root 表示访问的文件夹,其中默认是html文件夹,可以修改成自己的文件夹
            root   html;
            # index 访问页面,默认访问页面
            index  index.html index.htm;
        }

        
        # 错误页面的配置
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }


}

2.4、服务配置

nginx 复制代码
# 服务配置(虚拟主机配置)
server {
    # listen 监听端口
    listen       80;
    # 服务器名称,默认为localhost
    server_name  localhost;


    #访问地址 / 表示根目录
    location / {
        # root 表示访问的文件夹,其中默认是html文件夹,可以修改成自己的文件夹
        root   html;
        # index 访问页面,默认访问页面
        index  index.html index.htm;
    }


    # 错误页面的配置
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   html;
    }
}
  • 虚拟主机:原本一台服务器只能对应一个站点,通过虚拟主机技术可以虚拟化成多个站点同时对外提供服务

举个例子来说,一台服务器ip地址为192.168.6.136,有两个域名和对应的空间在这台服务器上,使用的都是192.168.6.136的80端口来提供服务。如果只是简单的将两个域名A和B的域名记录解析到这个ip地址,那么web服务器在收到任何请求时反馈的都会是同一个网站的信息,这显然达不到要求。

接下来我们使用主机头绑定域名A和B到他们对应的空间文件夹C和D。当含有域名A的web请求信息到达192.168.6.136时,web服务器将执行它对应的空间C中的首页文件,并返回给客户端,含有域名B的web请求信息同理,web服务器将执行它对应的空间D中的首页文件,并返回给客户端

  • server_name 匹配规则:需要注意的是server_name 匹配分先后顺序,写在前面的匹配上就不会继续往下匹配了。

    • 完整匹配:我们可以在同一servername中匹配多个域名

      nginx 复制代码
      server_name www.qindalin.com nav.qindalin.com;
    • 通配符匹配:精确匹配的优先级大于通配符匹配和正则匹配

      nginx 复制代码
      server_name *.qindalin.com
    • 通配符结束匹配

      nginx 复制代码
      server_name www.qindalin.*
    • 正则匹配

      nginx 复制代码
      server_name ~^[0-9]+\.qindalin\.com$;
  • 正则匹配格式,必须以~开头,比如 server_name ~^www\d+\.example\.net$;
  • 如果开头没有~,则nginx认为是精确匹配

特殊匹配格式:

nginx 复制代码
server_name ""; # 匹配Host请求头不存在的情况。

匹配顺序:

  1. 精确的名字
  2. *号开头的最长通配符名称,例如 *.example.org
  3. *号结尾的最长通配符名称,例如 mail.*
  4. 第一个匹配的正则表达式(在配置文件中出现的顺序)

示例:

  1. nginx.conf加入如下配置
nginx 复制代码
# 虚拟主机的配置
server {
    listen 81;
    server_name kuang.study.cn;
    
    location / {
        root /www/kuang/study81;
        index index.html;
    }
}

server {
    listen 82;
    server_name kuang.study.cn;
    
    location / {
        root /www/kuang/study82;
        index index.html;
    }
}
  1. 开放防火墙81、82端口:
bash 复制代码
firewall-cmd --add-port=81/tcp --permanent

firewall-cmd --add-port=82/tcp --permanent
  1. www/kuang/ 创建 study81、study82 文件夹并分别创建 index.html
html 复制代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Welcome to nginx!</title>
<style>
</style>
</head>
<body>
<h1>这是 Study81 页面!</h1>

</body>
</html>
html 复制代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Welcome to nginx!</title>
<style>
</style>
</head>
<body>
<h1>这是 Study82 页面!</h1>

</body>
</html>
  1. 在XShell中刷新配置:systemctl reload nginx

  2. C:\Windows\System32\drivers\etc 修改 hosts 文件做单机域名

bash 复制代码
# 测试nginx
# kuang.study.cn 域名是不存在的,映射到 192.168.6.136 处
192.168.6.136 kuang.study.cn
  1. 访问:http://kuang.study.cn (相当于访问http://192.168.6.136:80)

接着可继续访问: http://kuang.study.cn:81 、 http://kuang.study.cn:82

2.5、泛域名解析

所谓的泛域名解析是指:利用通配符 * 星号来做次级域名以实现所有的次级域名均指向同一IP地址。

好处:

  • 可以让域名支持无限的子域名(这也是泛域名解析最大的用途)

  • 防止用户错误输入导致的网站不能访问的问题

  • 可以让直接输入网址登陆网站的用户输入简洁的网址即可访问网站

3、代理

  1. 什么是代理?

代理就相当于中间商,本来A和B是可以直接连接的,但是此时添加了一个C在中间,A跟B不直接连接,而是通过C作为中介进行连接。

例子:最常见的例子就是二手房东,其实很多我们租房子时签约的人不是房子的真正房东,而是房东委托的中介,房东不想管事或者房子太多,只靠自己无法进行管理,所以才会通过中介(代理)进行处理

TIps: 一个完整的请求是由: client(客户端) -> proxy(代理) -> server(服务端) 组成。

  1. 什么是正向代理?
  • 正向代理: 顺着请求的方向进行的代理,即代理服务器它是由你配置为你服务,去请求目标服务器地址。

  • 例子:假如我们现在想要访问谷歌,但是由于某些原因,无法直接访问到谷歌,我们可以通过连接一台代理服务器,代理服务将我们的请求提交到谷歌,然后再将谷歌的响应反馈给我们。,对于谷歌而言,它只知道有一个请求过来,但是它并不会知道我们是无法直接访问它的。

  • 作用:

    • 访问原来无法访问的资源,如Google
    • 可以做缓存,加速访问资源
    • 对客户端访问授权,上网进行认证
    • 代理可以记录用户访问记录(上网行为管理),对外隐藏用户信息
  1. 什么是反向代理?
  • 反向代理: 跟正向代理相反,它是为目标服务器进行服务的,但是请求的流程还是 client(客户端) -> proxy(代理) -> server(服务端)
  • 例子: 比如我们访问百度网站,百度的代理服务器对外的域名为 www.baidu.com ,具体内部的服务器节点我们不知道。现实中我们通过访问百度的代理服务器后,代理服务器给我们转发请求到他们N多的服务器节点中的一个给我们进行搜索后将结果返回,此时,代理服务器对我们客户端来说就充当了提供响应的服务器
  • 作用:
    • 保证内网的安全,阻止web攻击,大型网站,通常将反向代理作为公网访问地址。
    • 负载均衡,通过反向代理服务器来优化网站的负载

用户通过互联网访问 www.baidu.com ,首先进入机房的网关路由上,网关路由会把请求转发到Nginx服务器上,Nginx 服务器再将所有的请求转发到应用服务器,应用服务器应答返回给 Nginx 服务器, Nginx 服务器再将响应返回给用户。 注: 因为网关路由和应用服务器是不通的,所以需要Nginx服务器做代理。

  1. 正向代理和反向代理的区别?
  • 正向代理即是客户端代理, 代理客户端, 服务端不知道实际发起请求的客户端.
  • 反向代理即是服务端代理, 代理服务端, 客户端不知道实际提供服务的服务端.

事实上,正向代理和反向代理的作用都是进行请求和转发,但是为了区别正向代理,所以后出现的就成为反向代理。生活中最常见的例子:

1、正向代理: 卖票的黄牛

2、反向代理: 出租房的二手东

3.1、具体配置

nginx.conf配置文件: 启用proxy_pass,root和index字段就会失效,所以二者不能同时出现

  • proxy_pass http://baidu.com
  • proxy_pass后的地址必须写完整 http://xxx,不支持https
nginx 复制代码
server {
    listen 83;
    server_name localhost;
    
    location / {
        proxy_pass http://baidu.com
        # root /www/kuang/study82;
        #  index index.html;       
    }	
}
  • 开放防火墙83端口
bash 复制代码
firewall-cmd --add-port=83/tcp --permanent
  • 进入http://192.168.6.136:81 ,会跳转至哔哩哔哩

3.2、基于反向代理的负载均衡

  • 使用upstream定义一组地址:访问localhost,访问都会代理到192.168.174.133:80192.168.174.134:80这两个地址之一,每次访问这两个地址轮着切换,因为默认权重相等
nginx 复制代码
http{
	upstream httpds{
            server 192.168.174.133:80; #如果是80端口,可以省略不写
            server 192.168.174.134:80;
	}
	server {
            listen       80;
            server_name  localhost;

            location / { 
                    proxy_pass http://httpds;
            }

            error_page   500 502 503 504  /50x.html;
            location = /50x.html {
                root   html;
            }
	}
}

4、负载均衡策略

先假设一个场景:

  1. 公司项目刚刚上线的时候,并发量小,用户使用的少,所以在低并发的情况下,一个jar包启动应用就够了,然后内部tomcat返回内容给用户
  1. 但是慢慢的,随着平台的用户越来越多了,并发量慢慢增大了,这时候一台服务器满足不了我们的需求了。
  1. 于是我们横向扩展,又增加了服务器。这个时候几个项目启动在不同的服务器上,用户要访问,就需要增加一个代理服务器了,通过代理服务器来帮我们转发和处理请求。

我们希望这个代理服务器可以帮助我们接收用户的请求,然后将用户的请求按照规则帮我们转发到不同的服务器节点之上。这个过程用户是无感知的,用户并不知道是哪个服务器返回的结果,我们还希望他可以按照服务器的性能提供不同的权重选择。保证最佳体验!所以我们使用了Nginx。

引出负载均衡:把请求,按照一定算法规则,分配给多台业务服务器(即使其中一个坏了/维护升级,还有其他服务器可以继续提供服务)

4.1、轮询

默认情况下使用轮询方式,逐一转发,这种方式适用于无状态请求。

  • weight 权重:指定轮询几率,weight 和访问比率成正比,用于后端服务器性能不均的情况。

设置权重:

nginx 复制代码
upstream httpds {
    server 127.0.0.1:8050  weight=10 ;
    # weight 默认为1,weight越大,负载的权重就越大
    server 127.0.0.1:8060  weight=1 ;
}

关闭: down

nginx 复制代码
upstream httpds {
    # down 表示当前的 server 暂时不参与负载
    server 127.0.0.1:8050  weight=10 down;
}

备用机:如果192.168.174.133:80出现故障,无法提供服务,就使用backup的这个机器

nginx 复制代码
upstream httpds{
    server 192.168.174.133:80 weight=10;
    server 192.168.174.134:80 weight=80 backup;
}

其他负载均衡策略(不常用):

  • ip_hash :根据客户端的 ip 地址转发同一台服务器,可以保持会话

    • 但是很少用这种方式去保持会话,例如我们当前正在使用wifi访问,当切换成手机信号访问时,会话就不保持了。
  • least_conn: 最少连接访问

    • 最少连接访问,优先访问连接最少的那一台服务器,这种方式也很少使用,因为连接少,可能是由于该服务器配置较低,刚开始赋予的权重较低。
  • url_hash :根据用户访问的 url 定向转发请求

    • 需要第三方插件,
  • fair:根据后端服务器响应时间转发请求

    • 需要第三方插件

4.2、动静分离

动静分离:为了提高网站的响应速度,减轻程序服务器Tomcat的负载,对于静态资源,如图片、js、css等文件,可以在反向代理服务器中进行缓存,这样浏览器在请求一个静态资源时,代理服务器就可以直接处理,而不用将请求转发给后端服务器。对于用户请求的动态文件,如servlet、jsp,则转发给Tomcat服务器处理,这就是动静分离。即动态文件与静态文件的分离。

当用户请求时,动态请求分配到Tomcat业务服务器,静态资源请求放在Nginx服务器中

例子:

  • 如果请求的资源地址是location//的优先级比较低,如果下面的location没匹配到,就会走http://xxx这个地址的机器
  • 如果请求的资源地址是location/css/*,就会被匹配到nginx的html目录下的css文件夹中(我们把css静态资源放在这个位置)
nginx 复制代码
server {
        listen       80;
        server_name  localhost;
				
        # /的优先级比较低,如果下面的location没匹配到,就会走http://xxx这个地址的机器
        location / { 
        	proxy_pass http://xxx;
        }
        
        # root指的是html文件夹,location/css指的是root下的css,所以地址就是html/css文件夹
        location /css {  
            root html;		
            index  index.html index.htm;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
}
  • 使用正则
nginx 复制代码
location ~*/(js|css|img){
  root html;
  index  index.html index.htm;
}

location 正则:

  • 精准匹配:location = /{}
  • 一般匹配:location /{}
  • 正则匹配:location ~/{}
nginx 复制代码
#1、 匹配任何以 /images/ 开头的地址,匹配符合以后,停止往下搜索正则,采用这一条
location ^~ /images/ {}

# 2、匹配所有以 gif、jpg或jpeg 结尾的请求
# 然而,所有请求 /images/ 下的图片会被 location ^~ /images/ 处理,因为 ^~ 的优先级更高,所以到达不了这一条正则
location ~* \.(gif|jpg|jpeg)$ {}

# 3、最长字符匹配到 /images/abc,优先级最低,继续往下搜索其它 location,会发现 ^~ 和 ~ 存在
location /images/abc {}

# 4、匹配以/images/abc 开头的,优先级次之,只有去掉 location ^~ /images/ 才会采用这一条
location ~ /images/abc {}

# 5、匹配/images/abc/1.html 文件,如果和正则 ~ /images/abc/1.html 相比,正则优先级更高
location /images/abc/1.html {}

优先级总结:

  • (location =) > (location 完整路径) > (location ^~ 路径) > (location ~,~* 正则顺序) > (location 部分起始路径) > (location /)

实际网站使用中,至少有三个匹配规则定义:

  1. 第一个必选规则:直接匹配网站根,通过域名访问网站首页比较频繁,使用这个会加速处理,比如说官网。这里是直接转发给后端应用服务器了,也可以是一个静态首页
nginx 复制代码
location = / {
    proxy_pass http://127.0.0.1:8080/; 
}
  1. 第二个必选规则:处理静态文件请求,这是nginx作为http服务器的强项,有两种配置模式,目录匹配或后缀匹配,任选其一或搭配使用
nginx 复制代码
location ^~ /static/ {
    root kuang/webroot/static/;
}

location ~* \.(html|gif|jpg|jpeg|png|css|js|ico)$ {
    root kuang/webroot/res/;
}

3.第三个规则:通用规则,用来转发动态请求到后端应用服务器

nginx 复制代码
location /api/ {
    proxy_pass http://127.0.0.1:3000/api/
}

4.3、URLRewrite

rewrite是实现URL重写的关键指令,根据正则表达式部分内容,重定向到repacement,结尾是flag标记。

格式:

nginx 复制代码
#关键字     正则          替代内容        flag标记
  rewrite <regex> <replacement> [flag];
  • 替代内容: 将正则匹配的内容替换成 replacement
  • flag 标记: rewrite 支持的 flag 标记
    • last : 本条规则匹配完成后,继续向下匹配新的 location uri 规则
    • break: 本条规则匹配完成即终止,不再匹配后面的任何规则
    • redirect : 返回302临时重定向,浏览器地址会显示跳转后的url地址
    • permanent: 返回301永久重定向,浏览器地址会显示跳转后的url地址

rewrite 参数的标签段位置: server、location、if

URLRewrite的优缺点:

  • 优点:掩藏真实的url以及url中可能暴露的参数,以及隐藏web使用的编程语言,提高安全性便于搜索引擎收录
  • 缺点:降低效率,影响性能。如果项目是内网使用,比如公司内部软件,则没有必要配置。

示例:

nginx 复制代码
server {
        listen       80;
        server_name  localhost;
				
        location / { 
            rewrite ^/([0-9]+).html$ /index.jsp?pageNum=$1  break;
            proxy_pass http://xxx;
        }
      

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
}

浏览器地址栏访问 xxx/123.html实际上是访问xxx/index.jsp?pageNum=123

5、防盗链

当我们请求到一个页面后,这个页面一般会再去请求其中的静态资源,这时候请求头中,会有一个refer字段,表示当前这个请求的来源,我们可以限制指定来源的请求才返回,否则就不返回,这样可以防止别人利用我们的资源。

配置格式:

nginx 复制代码
valid_referers  none|server_name

参数值,设置有效的refer值:可以同时携带多个参数,表示多个 referer 头部都生效

  • none: 允许没有 referer 信息的请求访问,即直接通过url访问。
  • blocked:通俗点说就是允许http://https://以外的请求
  • server_name:检测主机地址,refer显示是从这个地址来的,则有效(server_name必须是完整的http://xxxx
  • 其他字符串类型:检测referer与字符串是否匹配,如果匹配则允许访问,可以采用通配符*
  • 正则表达式:若 referer 的值匹配上了正则,就允许访问

invalid_referer 变量:

  • 允许访问时变量值为空
  • 不允许访问时变量值为1

示例:这里设置nginx服务器中的img目录下的图片必须refer为http:192.168.174/133才能访问

nginx 复制代码
server {
        listen       80;
        server_name  localhost;
				
        location / { 
        	proxy_pass http://xxx;
        }
      
        location /img{
        	#如果引用这张图片的页面且refer并没有被设置,图片就无法加载出来。
            valid_referers http:192.168.174/133;
            #if 后面有个空格,不写就会报错 
            if ($invalid_referer){#无效的
                    return 403;#返回状态码403
            }
            root html;
            index  index.html index.htm;
        }
        
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
}

示例:

nginx 复制代码
# none:表示没有 referer 的可以访问
# server_names:表示本机 server_name 也就是 referer.test.com 可以访问
# *.test.com:匹配上了正则的可以访问
# www.test.org.cn/nginx/:该页面发起的请求可以访问

server {
    server_name referer.test.com;
    listen 80;

    error_log logs/myerror.log debug;
    root html;
    location / {
        valid_referers none server_names
                       *.test.com www.test.org.cn/nginx/;
        if ($invalid_referer) {
                return 403; # 返回错误码
        }
        return 200 'valid\n';
    }
}

5.1、防盗链照片

将提示图片放在html/img/x.png,访问设置防盗链图片时,就返回这x.png张图

nginx 复制代码
location /img{
        valid_referers http:192.168.174/133;
        if ($invalid_referer){#无效的
             rewrite ^/  /img/x.png break;
        }
        root html;
        index  index.html index.htm;
}

5.2、使用curl测试

我们使用浏览器进行访问测试,浏览器会有缓存,导致测试不准,可以借助 curl 工具

  1. 安装curl
bash 复制代码
yum install -y curl
  1. 测试示例

    bash 复制代码
    curl -I http://192.168.44.101/img/logo.png

    带引用测试

    bash 复制代码
    curl -e "http://baidu.com" -I http://192.168.44.101/img/logo.png

    带引用测试需要我们在 valid_referers中添加 baidu.com

    nginx 复制代码
    location /img{
            valid_referers http://192.168.44.101 baidu.com;
            if ($invalid_referer){#无效的
                 rewrite ^/  /img/x.png break;
            }
            root html;
            index  index.html index.htm;
    }

6、高可用

  • 用户访问时,访问的是一个虚拟IP,keepalived会选定一个主服务器使用这个虚拟IP

  • 每台机器上的keepalived会相互通信,根据其他机器上的keepalived进程是否存在,判断服务器状态,如果默认的Master停止了,就会在剩下的Backup机器中,竞选出一台Nginx服务器作为Master

开始使用:

  1. 安装 keepalived
bash 复制代码
 yum install -y keepalived
  1. 修改 keepalived 配置
    • 配置文件在/etc/keepalived/keepalived.conf
    • vrrp_instanceauthenticationvirtual_router_idvirtual_ipaddress这几个一样的机器,才算是同一个组里。这个组才会选出一个作为Master机器
    • 下载好的 conf 文件东西很多,我们只需保留下面这些即可

第一台机器配置:

bash 复制代码
! Configuration File for keepalived

global_defs {
   router_id lb1 # 名字与其他配置了keepalive的机器不重复就行
}

vrrp_instance Augenestern {#vrrp实例名可以随意取
    state MASTER #只能有一个默认的Master,其他写BACKUP
    interface ens33 # ip addr查看下网卡名,默认是ens33
    virtual_router_id 51
    priority 100 # 竞争的优先级
    advert_int 1 #通信时间
    authentication {#分组
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.200.16 #虚拟的IP
    }
}

第二台机器配置:

bash 复制代码
! Configuration File for keepalived

global_defs {
   router_id lb2 # 名字与其他配置了keepalive的机器不重复就行
}

vrrp_instance Augenestern {#vrrp实例名可以随意取
    state BACKUP #只能有一个默认的Master,其他写BACKUP
    interface ens33 # ip addr查看下网卡名,默认是ens33
    virtual_router_id 51
    priority 50 # 竞争的优先级
    advert_int 1  #通信时间
    authentication {#分组
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.200.16 #虚拟IP
    }
}
  1. 启动
bash 复制代码
systemctl start keepalived
  1. 第一台查看ip
bash 复制代码
ip addr

这样当第一台机器宕机之后,第二台机器会继续接收虚拟此ip地址,从而继续对外提供服务。

相关推荐
墨鸦_Cormorant9 小时前
使用docker快速部署Nginx、Redis、MySQL、Tomcat以及制作镜像
redis·nginx·docker
一只爱撸猫的程序猿9 小时前
一个简单的Linux 服务器性能优化案例
linux·mysql·nginx
DC_BLOG13 小时前
Linux-Nginx虚拟主机
linux·运维·nginx
Stara051113 小时前
Git推送+拉去+uwsgi+Nginx服务器部署项目
git·python·mysql·nginx·gitee·github·uwsgi
oushaojun217 小时前
ubuntu中使用ffmpeg和nginx推流rtmp视频
nginx·ubuntu·ffmpeg·rtmp
不能只会打代码17 小时前
大学课程项目中的记忆深刻 Bug —— 一次意外的数组越界
java·github·intellij-idea·话题博客
ladymorgana18 小时前
【Nginx从入门到精通】05-安装部署-虚拟机不能上网简单排错
网络·nginx·智能路由器
linweidong1 天前
MariaDB面试题及参考答案
linux·运维·数据库·负载均衡·dba·mariadb·后端面试
Web极客码1 天前
如何修复WordPress卡在维护模式
服务器·网络·github
苹果醋31 天前
Redis | 第3章 对象《Redis设计与实现》
java·运维·spring boot·mysql·nginx