Nginx - 反向代理、负载均衡、动静分离(案例实战分析)

目录

[Nginx 开始](#Nginx 开始)

概述

[安装(非 Docker)](#安装(非 Docker))

配置环境变量

常用命令

配置文件概述

[location 路径匹配方式](#location 路径匹配方式)

配置反向代理

实现效果

准备工作

具体配置

效果演示

配置负载均衡

实现效果

准备工作

具体配置

实现效果

其他负载均衡策略

配置动静分离

概念

实现效果

准备工作

[403 错误,怎么办?](#403 错误,怎么办?)

效果演示


Nginx 开始


概述

a)简述

Nginx 是一个高性能的 HTTP 和反向代理服务器,特点是占用内存少,并发能力强(有报告表明支持高达 50 000 个并发连接数).

b)何为正向代理

正向代理:代理客户端(在浏览器中配置代理服务器). 通过代理服务器进行互联网访问.

例如,在中国大陆是不能直接访问到谷歌,因此就需要在浏览器中配置代理服务器,通过代理服务器来访问谷歌.

c)何为反向代理

反向代理:代理服务器. 客户端无需做任何 配置,只需要将请求发送给反向代理服务器,呦反向代理服务器将请求发送给真实服务器(暴露代理服务器地址,隐藏真实服务器 IP 地址).

例如,客户端要给 8080 端口的 tomcat 发送请求,可以不直接访问 tomcat(出于安全考虑),而是通过将请求发送给 9090 的代理服务器,再由 9090 的代理服务器将请求转发给 8080 端口的 tomcat.

d)安装:直接通过 docker 安装(记得挂载配置文件数据卷).

安装(非 Docker)

a)官网下载:nginx: download

b)将下载好的文件上传到终端:

Ps:想了一下,又把文件移到了服务器的 ~/apps 目录下.

c)解压

tar -zxvf nginx-1.26.1.tar.gz

d)下载 nginx 运行环境

依次运行以下命令:

bash 复制代码
yum -y install gcc gcc-c++ autoconf automake make
bash 复制代码
yum -y install openssl openssl-devel

e)进入到刚解压的文件中,进行基本配置(输入如下命令)

bash 复制代码
./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-http_stub_status_module

配置configure

  • --prefix:代表安装的路径
  • --with-http_ssl_module:安装ssl
  • --with-http_stub_status_module:查看nginx的客户端状态

f)在解压文件的目录中可以观察到多出了一个 makefile 文件:

接着输入以下命令:

bash 复制代码
#编译安装nginx
make & make install 

Ps:上一步编译如果出现了错误 "make: *** No rule to make target `build', needed by `default'. Stop".,解决如下:

  1. 安装配置:yum -y install make zlib-devel gcc-c++ libtool openssl openssl-devel
  2. 重新./configure :./configure
  3. 编译:make & make install

f)进入到安装目录(上面 "--prefix=/usr/local/nginx" 配置的就是安装目录)

bash 复制代码
cd /usr/local/nginx/

g)接着进入sbin目录下,执行以下命令启动 nginx

h)最后直接输入服务器的 ip 就可以访问了(只输入服务器 ip,默认走 80 端口)

Ps:如果访问不了,就去关闭一下防火墙吧~

配置环境变量

a)cd /etc 进入到 etc 目录中

b)找到 profile 文件

c)添加如下信息

bash 复制代码
# Nginx 的安装目录
export NGINX_HOME=/usr/local/nginx
# Nginx 环境变量配置
export PATH=${NGINX_HOME}/bin:${NGINX_HOME}/sbin:$PATH

d)刷新环境变量

bash 复制代码
source /etc/profile

e)验证:切换到任意目录下,输入如下命令

常用命令

Note:使用的前提是必须先进入到 /usr/local/nginx/sbin 目录中(配置了环境变量可以忽略,之后都演示配置后的)

a)查看 nginx 版本

bash 复制代码
nginx -v

b)停止 nginx

bash 复制代码
nginx -s stop

c)启动 nginx

bash 复制代码
nginx

d)重新加载 nginx

bash 复制代码
nginx -s reload

将来我们会经常修改 nginx 的配置文件,每次修改后就需要重新加载 ngxin 才能生效.

配置文件概述

a)nginx 配置文件位置

/usr/local/nginx/conf/nginx.conf

b)nginx 默认配置文件内容(去掉注释):

bash 复制代码
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   html;
            index  index.html index.htm;
        }
 
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
 
}

c)nginx 配置文件三部分组成:

1)全局块:从配置文件开始到 events 块之前的内容. 主要用来设置影响 nginx 服务器整体运行的配置指令,例如 "worker_processes 1;" (worker_processes 值越大,可以支持的并发处理量越大). 如下:

bash 复制代码
worker_processes  1;   # 服务器并发处理能力,值越大并发能力越强(受自身配置限制)

2)events 块:主要用来影响 nginx 服务器与用户的网络连接,例如 "worker_connections 1024;" 表示支持的最大连接数. 如下:

bash 复制代码
events {
    worker_connections  1024; #最大连接数1024个,需灵活配置
}

3)http 块:nginx 中配置最频繁的地方,http 块中包括 http 全局块、server 块.

http 全局块如下:

bash 复制代码
http {
    include       mime.types;      # 文件扩展名与文件类型映射表
    default_type  application/octet-stream;  # 访问到未定义的扩展名的时候,就默认为下载该文件
 
    sendfile        on; # 日志自定义
 
    keepalive_timeout  65; # 超时时间

http 块中的 server 块如下:

bash 复制代码
    server {
        listen       80; # 目前监听的端口号
        server_name  localhost; # 主机名称

server 块中又包括 server 全局块 和 location 块.

全局 server 块如下:

bash 复制代码
    server {
        listen       80; # 目前监听的端口号
        server_name  localhost; # 主机名称

location 块如下:

bash 复制代码
   location / {     #表示默认首页
            root   html;
            index  index.html index.htm;

root 指定了服务器的根目录,上述 "root html" 表示 nginx 安装目录的路径下的 html 目录(以 nginx 安装目录为相对路径).

location 路径匹配方式

语法如下:

location { = | ~ | ~* | ^~ } uri {
    # ...
}

a)=:表示不含正则表达式的 uri ,要求请求字符串和 uri 严格匹配,如果匹配成功,就停止继续向后匹配,并立即处理该请求.

例如如下:

location = /exact-match {
    # 配置处理精确匹配的请求
    proxy_pass http://backend_server;
}

只有请求 URI 完全是 /exact-match 时,才会匹配这个 location 块,其他类似的请求(如 /exact-match/ 或 /exact-match123 )不会匹配。

b)~:用于表示 uri 包含正则表达式,并且区分大小写.

例如如下:

location ~ \.php$ {
    # 配置处理所有以 .php 结尾的请求,例如 /index.php 或者 /foo.php
    fastcgi_pass php_backend;
}

c)~*:用于表示 uri 包含正则表达式,并且不区分大小写.

d)^~:不含正则表达式的 uri,要求 Nginx 服务器扎到表示 uri 和请求字符串匹配度最高的 location 后,立即使用 location 处理请求,而不再使用 location 块中的正则 uri 和请求字符串做匹配.

location ^~ /static/ {
    # 配置处理所有以 /static/ 开头的请求
    root /data/static;
}

例如 static/css/styles.css 或者 /static/js/app.js

配置反向代理

实现效果

打开浏览器,在浏览器地址栏中,

输入 env-base:9000/aaa 跳转到 env-base:8080(tomcat8080 的页面)

输入 env-base:9000/bbb 跳转到 env-base:8081(tomcat8081 的页面)

Ps:env-base 为配置 nginx 的服务器 ip

准备工作

a)准备两个 tomcat 服务器,一个 8080,一个 8081

这里使用 docker,直接运行以下命令

bash 复制代码
# 1.先简单启动
docker run --name tomcat -p 8080:8080 -d tomcat:8.0

# 2.在宿主机中创建将来容器的映射文件
mkdir -p ~/test/tomcat8080
mkdir -p ~/test/tomcat8081

# 3.将容器中的文件拷贝到宿主机
docker cp tomcat:/usr/local/tomcat/webapps/ ~/test/tomcat8080
docker cp tomcat:/usr/local/tomcat/webapps/ ~/test/tomcat8081

# 4.删除旧的容器
docker rm -f tomcat

# 5.启动新容器
docker run --name tomcat8080 -p 8080:8080  \
-v ~/test/tomcat8080/webapps:/usr/local/tomcat/webapps \
-e TZ=Asia/Shanghai \
-d tomcat:8.0

docker run --name tomcat8081 -p 8081:8080  \
-v ~/test/tomcat8081/webapps:/usr/local/tomcat/webapps \
-e TZ=Asia/Shanghai \
-d tomcat:8.0

正常访问:

b)由于将来访问 env-base:8080 或者 env-base:8081 实际上都是访问 webapps 下的目录,因此为了演示不同效果,就在前面创建的 tomcat8080 和 tomcat8081 的 webapps 目录下创建两个不同的文件(aaa、bbb)和两个不同的 HTML(a.html 和 b.html):

  • ~/test/tomcat8080/webapps/aaa/a.html
  • ~/test/tomcat8081/webapps/bbb/b.html

效果如下:

具体配置

编辑 nginx 配置文件,进行反向代理配置

bash 复制代码
    server {
        listen       9000;
        server_name  env-base;

        location ~ /aaa/ {
            proxy_pass http://127.0.0.1:8080;
        }

        location ~ /bbb/ {
            proxy_pass http://127.0.0.1:8081;
        }
    }

使用 nginx -s reload 命令重新加载 nginx

效果演示

e)上述原理

location ~ /aaa/ {

proxy_pass http://127.0.0.1:8080;

}

由于 ~ /aaa/ 是正则表达式,表示只要路径中含有 /aaa/ 就会被代理

  • 例如输入 env-base:9000/aaa/a.html 就会被代理成 127.0.0.1:8080/aaa/a.html(可以正常访问)
  • 例如输入 env-base:9000/abc/aaa/a.html 就会被代理成 http://127.0.0.1:8080/abc/aaa/a.html(404 错误)

配置负载均衡

实现效果

浏览器地址栏输入地址 http://env-base:9000/ccc/c.html 实现负载均衡效果,平均分配到 8080 和 8081 端口中.

准备工作

  1. 准备两个 tomcat 服务器,一台 8080,一台 8081.(在上一章配置反向代理,我们已经准备好了两个 tomcat 容器,路径分别为 "~/test/tomcat8080"、"~/test/tomcat8081")
  2. 在两个 tomcat 中 webapps 目录中,创建名称是 ccc 文件夹,在 ccc 文件夹中创建 c.html ,用于测试.

tomcat8080 访问如下:

tomcat8081 访问如下:

具体配置

实现效果

默认按照轮询的策略分配

第一次:

第二次:

其他负载均衡策略

默认负载均衡的策略是轮询,除此之外,还有其他策略,如下:

a)weight 权重

另外可以通过 weight 来控制需要负载均衡的权重. 权重越大,访问到的概率越大.

比如将权重都配置为 1,表示两者访问到的概率相同.

    upstream group1 {
        server 192.168.0.12:80 weight=1;
        server 192.168.0.12:81 weight=1;
    }
    server {
        listen       80;
        server_name  localhost;

        default_type  text/html;
        location /a {
            proxy_pass "https://group1";
        }
    }

或者将 80 端口的权重改为 10,让其访问到的概率大一些.

    upstream group1 {
        server 192.168.0.12:80 weight=10;
        server 192.168.0.12:81 weight=1;
    }
    server {
        listen       80;
        server_name  localhost;

        default_type  text/html;
        location /a {
            proxy_pass "https://group1";
        }
    }

b)ip_hash

每个请求按访问 ip 的hash 结果分配,这样子访客固定访问一个后端服务器,可以解决session问题

举个例子:

A用户固定ip,第一次访问到8080 tomcat,那么后面就都是访问到这台机器.

upstream myserver {
    ip_hash;
    server 127.0.0.1:8080;
	server 127.0.0.1:8081;
}

c)fair

根据后端响应时间来分配请求,处理时间短的优先分配.

upstream myserver {
    server 127.0.0.1:8080;
	server 127.0.0.1:8081;
	fair;
}

配置动静分离

概念

为了加快网站的解析速度,可以把动态页面和静态页面由不同的服务器来解析,加快解析速度.

实际上就是将来客户端会先访问 nginx,如果要访问的是静态资源,就会代理到对应放静态资源的 服务器(如 html、css、js); 如果是动态资源,就会代理到对应放动态资源的服务器(如 jsp、sevlet)

另外,这也是一种可以直接通过 url 访问服务器上对应的静态资源的方法(如 图片、html、css).

实现效果

在浏览器中输入地址 http://env-base/image/1.png 访问到服务器上 ~/data/image/1.png 图片

在浏览器中输入地址 http://env-base/www/index.html 访问到服务器上 ~/data/www/index.html 页面.

准备工作

在服务器上的 ~/data/image/ 目录下,准备一个 1.png 图片.

在服务器上的 ~/data/www/ 目录下,准备一个 index.html 页面.

d)具体配置

重启 nginx.

1)

location /www/ {

root /root/data/;

}

表示如果将来浏览器中输入的 uri 是 /www/ ,则匹配服务器上 /root/data 目录下的 /www/ 目录中.

  1. autoindex on; 表示开启自动显示索引.

403 错误,怎么办?

a)先提一嘴,如果出现了 403 错误,是因为 静态资源不可以访问在某个家目录下,如 /root 也就是 ~/ 目录下.

可以在 nginx.conf 文件中指定用户

user nobody

修改为

user root; # 设置为 root 用户

b)也有可能是权限不足,通过 chmod 755 -R 所在文件夹 即可提升权限,解决问题.

c)如果还是不行,可能是操作系统设定 SELinux,这是 Linux 系统的选项,为了保护服务求防止文件被随意获取的机制.

通过 getenforce 就可以查看到默认是开启的(Enforcing),需要改成 disabled 状态

要想要永久关闭,就需要进入配置文件 /etc/sysconfig/selinux 将 SELINUX=enforcing 改为SELINUX=disabled

如下:

重启机器,这时候因该就没问题了.

效果演示

autoindex on 的效果如下:

访问到具体图片:

以及 html

相关推荐
Tiffany_Ho2 分钟前
【TypeScript】知识点梳理(三)
前端·typescript
安冬的码畜日常1 小时前
【D3.js in Action 3 精译_029】3.5 给 D3 条形图加注图表标签(上)
开发语言·前端·javascript·信息可视化·数据可视化·d3.js
苹果醋32 小时前
快速玩转 Mixtral 8x7B MOE大模型!阿里云机器学习 PAI 推出最佳实践
spring boot·nginx·毕业设计·layui·课程设计
小白学习日记2 小时前
【复习】HTML常用标签<table>
前端·html
丁总学Java2 小时前
微信小程序-npm支持-如何使用npm包
前端·微信小程序·npm·node.js
yanlele2 小时前
前瞻 - 盘点 ES2025 已经定稿的语法规范
前端·javascript·代码规范
懒羊羊大王呀3 小时前
CSS——属性值计算
前端·css
DOKE3 小时前
VSCode终端:提升命令行使用体验
前端
xgq3 小时前
使用File System Access API 直接读写本地文件
前端·javascript·面试