sf-utils2 sf-utils2
版本v3.3.3-beta1
首页
  • 01.快速开始 🔥
  • 02.基础-Base
  • 03.对象-Object
  • 04.数组-Array
  • 05.方法-Function
  • 06.字符串-String
  • 07.数学-Math
  • 08.dom
  • 09.拓展
  • webpack5.x教程学习 (opens new window)
  • 例子
  • 教程 🔥
  • 例子配置
企业级后台模版 (opens new window)
版本v3.3.3-beta1
首页
  • 01.快速开始 🔥
  • 02.基础-Base
  • 03.对象-Object
  • 04.数组-Array
  • 05.方法-Function
  • 06.字符串-String
  • 07.数学-Math
  • 08.dom
  • 09.拓展
  • webpack5.x教程学习 (opens new window)
  • 例子
  • 教程 🔥
  • 例子配置
企业级后台模版 (opens new window)
  • Nginx配置

    • 教程🔥
      • 1.介绍
      • 2.概念
        • 2.1 跨域
        • 2.2 正向代理和反向代理 🔥
        • 2.3 负载均衡 🔥
        • 2.4 动静分离
      • 3.nginx 开始
        • 3.1 安装
        • 3.2 查找 nginx 配置文件路径
        • 3.3 查看 nginx 监听的端口
        • 方式一
        • 方式二
        • 3.4 nginx 基本命令
        • 3.5 Nginx.conf 文件配置简要说明
      • 4.Nginx 配置语法
        • 4.1 经典配置
      • 5 Nginx 实战
        • 5.1 前端 vue 传统的 spa 项目打包
        • 5.1 location 匹配流程
        • 5.2 root 和 alias
        • 5.2 try_files
        • 5.3 index
        • 5.4 proxy_pass
        • 5.5 rewrite
        • 5.5 upstream
      • 6.结合院内实际业务中使用 🔥
        • 6.1 背景
        • 6.1 例子一 广东等级评审
        • Q1: 如果我前端是hash模式路由,该怎么配置?
        • Q2: 我想继续采用history模式,我配置不想在locaton中使用用root,我想改用alias比较直观?
        • 6.2 例子二 危重、广东、重庆四个项目放在一个项目下
      • 7.单个部署
        • 7.1 部署要求
        • 7.2 前端准备
        • 7.3 测试人员准备
      • 8.多个项目部署
        • 8.1 部署要求
        • 8.2 前端准备
        • 8.3 测试准备
    • 指南者留学nginx配置
    • 溧阳口腔nginx配置
    • 本地mac nginx配置
    • 阿里云服务器nginx配置
    • 匿名sit配置
    • 匿名uat配置
目录

教程🔥

# 1.介绍

是一款是由俄罗斯的程序设计师 Igor Sysoev 所开发高性能的 Web 和 反向代理 服务器,也是一个 IMAP/POP3/SMTP 代理服务器。 在高连接并发的情况下,Nginx 是 Apache 服务器不错的替代品。
Nginx 的最重要的几个使用场景: 静态资源服务,通过本地文件系统提供服务; 反向代理服务,延伸出包括缓存、负载均衡等; API 服务,OpenResty ;
个人觉得 作为一名前端还是有必要去了解和使用 nginx。Nginx 官方文档 (opens new window)

以下例子运行环境 nginx:1.8.0 centos: 7.8

[root@iZuf6eednvvtf310byi0kaZ ~]# nginx -v
nginx version: nginx/1.8.0
[root@iZuf6eednvvtf310byi0kaZ ~]# lsb_release -a
LSB Version:    :core-4.1-amd64:core-4.1-noarch
Distributor ID: CentOS
Description:    CentOS Linux release 7.8.2003 (Core)
Release:        7.8.2003
Codename:       Core
1
2
3
4
5
6
7
8

# 2.概念

# 2.1 跨域

在浏览器上当前访问的网站向另一个网站发送请求获取数据的过程就是跨域请求。 跨域是浏览器的同源策略决定的,是一个重要的浏览器安全策略,用于限制一个 origin 的文档或者它加载的脚本与另一个源的资源进行交互,它能够帮助阻隔恶意文档,减少可能被攻击的媒介,可以使用 CORS 配置解除这个限制。 关于跨域网上已经有很多解释,这里就不啰嗦,也可以直接看 MDN 的 <浏览器的同源策略> 文档进一步了解,这里就列举几个同源和不同元的例子,相信程序员都能看得懂。

# 同源的例子
http://example.com/app1/index.html  # 只是路径不同
http://example.com/app2/index.html

http://Example.com:80  # 只是大小写差异
http://example.com

# 不同源的例子
http://example.com/app1   # 协议不同
https://example.com/app2

http://example.com        # host 不同
http://www.example.com
http://myapp.example.com

http://example.com        # 端口不同
http://example.com:8080
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 2.2 正向代理和反向代理 🔥

# 2.3 负载均衡 🔥

# 2.4 动静分离

为了加快网站的解析速度,可以把动态页面和静态页面由不同的服务器来解析,加快解析速度,降低原来单个服务器的压力。 一般来说,都需要将动态资源和静态资源分开,由于 Nginx 的高并发和静态资源缓存等特性,经常将静态资源部署在 Nginx 上。如果请求的是静态资源,直接到静态资源目录获取资源,如果是动态资源的请求,则利用反向代理的原理,把请求转发给对应后台应用去处理,从而实现动静分离。

使用前后端分离后,可以很大程度提升静态资源的访问速度,即使动态服务不可用,静态资源的访问也不会受到影响。

# 3.nginx 开始

# 3.1 安装

安装教程不做过多介绍,安装请参考下面

centos 安装 Nginx (opens new window)

window 安装 Nginx (opens new window)

# 3.2 查找 nginx 配置文件路径

若不知道 nginx 的安装目录和配置文件路径,则可以通过以下方式查找。

[root@iZuf6eednvvtf310byi0kaZ ~]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@iZuf6eednvvtf310byi0kaZ ~]#
1
2
3
4

从日志就可以看到 nginx 配置文件在 /usr/local/nginx/conf/nginx.conf

# 3.3 查看 nginx 监听的端口

# 方式一

先获取到 nginx 服务的PID,然后调用netstat -anp | grep [PID],查看 nginx 监听的端口。

[root@iZuf6eednvvtf310byi0kaZ ~]# ps -ef | grep nginx
nobody     712 15672  0 13:22 ?        00:00:00 nginx: worker process
root       843   591  0 13:51 pts/0    00:00:00 grep --color=auto nginx
root     15672     1  0 Mar18 ?        00:00:00 nginx: master process nginx
[root@iZuf6eednvvtf310byi0kaZ ~]# netstat -anp | grep 712
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      712/nginx: worker p
tcp        0      0 0.0.0.0:8081            0.0.0.0:*               LISTEN      712/nginx: worker p
tcp        0      0 0.0.0.0:8082            0.0.0.0:*               LISTEN      712/nginx: worker p
tcp        0      0 0.0.0.0:8083            0.0.0.0:*               LISTEN      712/nginx: worker p
tcp        0      0 0.0.0.0:8089            0.0.0.0:*               LISTEN      712/nginx: worker p
unix  3      [ ]         STREAM     CONNECTED     5926516  712/nginx: worker p
[root@iZuf6eednvvtf310byi0kaZ ~]#
1
2
3
4
5
6
7
8
9
10
11
12

从日志可以看到 nginx 启动的服务占用的端口号有:80、8081、8082、8083、8089

# 方式二

直接调用netstat -anp | grep nginx,查看 nginx 监听的端口。

[root@iZuf6eednvvtf310byi0kaZ ~]# netstat -anp | grep nginx
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      712/nginx: worker p
tcp        0      0 0.0.0.0:8081            0.0.0.0:*               LISTEN      712/nginx: worker p
tcp        0      0 0.0.0.0:8082            0.0.0.0:*               LISTEN      712/nginx: worker p
tcp        0      0 0.0.0.0:8083            0.0.0.0:*               LISTEN      712/nginx: worker p
tcp        0      0 0.0.0.0:8089            0.0.0.0:*               LISTEN      712/nginx: worker p
unix  3      [ ]         STREAM     CONNECTED     5926515  15672/nginx: master
unix  3      [ ]         STREAM     CONNECTED     5926516  712/nginx: worker p
[root@iZuf6eednvvtf310byi0kaZ ~]#
1
2
3
4
5
6
7
8
9

# 3.4 nginx 基本命令

[root@iZuf6eednvvtf310byi0kaZ ~]# nginx -h
nginx version: nginx/1.8.0
Usage: nginx [-?hvVtq] [-s signal] [-c filename] [-p prefix] [-g directives]

Options:
  -?,-h         : this help
  -v            : show version and exit
  -V            : show version and configure options then exit
  -t            : test configuration and exit
  -q            : suppress non-error messages during configuration testing
  -s signal     : send signal to a master process: stop, quit, reopen, reload
  -p prefix     : set prefix path (default: /usr/local/nginx/)
  -c filename   : set configuration file (default: conf/nginx.conf)
  -g directives : set global directives out of configuration file

[root@iZuf6eednvvtf310byi0kaZ ~]#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

常用的命令有:

# 启动 nginx
nginx

# 停止 nginx
nginx -s stop

# 检查 NGINX 配置是否正确
nginx -t

# 重启 nginx,常用
nginx -s reload

# 重新打开 nginx
nginx -s reopen

# 设置配置文件,默认为 /usr/local/etc/nginx/nginx.conf
nginx -c filename
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 3.5 Nginx.conf 文件配置简要说明

配置,点击查看
#定义 nginx 运行的用户和用户组
user www www;

#nginx 进程数,建议设置为等于 CPU 总核心数。
worker_processes 8;

#nginx 默认没有开启利用多核 CPU, 通过增加 worker_cpu_affinity 配置参数来充分利用多核 CPU 以下是 8 核的配置参数
worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;

#全局错误日志定义类型,[ debug | info | notice | warn | error | crit ]
error_log /var/log/nginx/error.log info;

#进程文件
pid /var/run/nginx.pid;

#一个 nginx 进程打开的最多文件描述符数目,理论值应该是最多打开文件数(系统的值 ulimit -n)与 nginx 进程数相除,但是 nginx 分配请求并不均匀,所以建议与 ulimit -n 的值保持一致。
worker_rlimit_nofile 65535;

#工作模式与连接数上限
events
{
    #参考事件模型,use [ kqueue | rtsig | epoll | /dev/poll | select | poll ]; epoll 模型是 Linux 2.6 以上版本内核中的高性能网络 I/O 模型,如果跑在 FreeBSD 上面,就用 kqueue 模型。
    #epoll 是多路复用 IO(I/O Multiplexing) 中的一种方式,但是仅用于 linux2.6 以上内核,可以大大提高 nginx 的性能
    use epoll;

    ############################################################################
    #单个后台 worker process 进程的最大并发链接数
    #事件模块指令,定义 nginx 每个进程最大连接数,默认 1024。最大客户连接数由 worker_processes 和 worker_connections 决定
    #即 max_client=worker_processes*worker_connections, 在作为反向代理时:max_client=worker_processes*worker_connections / 4
    worker_connections 65535;
    ############################################################################
}

#设定 http 服务器
http {
    include mime.types; #文件扩展名与文件类型映射表
    default_type application/octet-stream; #默认文件类型
    #charset utf-8; #默认编码

    server_names_hash_bucket_size 128; #服务器名字的 hash 表大小
    client_header_buffer_size 32k; #上传文件大小限制
    large_client_header_buffers 4 64k; #设定请求缓
    client_max_body_size 8m; #设定请求缓
    sendfile on; #开启高效文件传输模式,sendfile 指令指定 nginx 是否调用 sendfile 函数来输出文件,对于普通应用设为 on,如果用来进行下载等应用磁盘 IO 重负载应用,可设置为 off,以平衡磁盘与网络 I/O 处理速度,降低系统的负载。注意:如果图片显示不正常把这个改成 off。
    autoindex on; #开启目录列表访问,合适下载服务器,默认关闭。
    tcp_nopush on; #防止网络阻塞
    tcp_nodelay on; #防止网络阻塞

    ##连接客户端超时时间各种参数设置##
    keepalive_timeout  120;          #单位是秒,客户端连接时时间,超时之后服务器端自动关闭该连接 如果 nginx 守护进程在这个等待的时间里,一直没有收到浏览发过来 http 请求,则关闭这个 http 连接
    client_header_timeout 10;        #客户端请求头的超时时间
    client_body_timeout 10;          #客户端请求主体超时时间
    reset_timedout_connection on;    #告诉 nginx 关闭不响应的客户端连接。这将会释放那个客户端所占有的内存空间
    send_timeout 10;                 #客户端响应超时时间,在两次客户端读取操作之间。如果在这段时间内,客户端没有读取任何数据,nginx 就会关闭连接
    ################################

    #FastCGI 相关参数是为了改善网站的性能:减少资源占用,提高访问速度。下面参数看字面意思都能理解。
    fastcgi_connect_timeout 300;
    fastcgi_send_timeout 300;
    fastcgi_read_timeout 300;
    fastcgi_buffer_size 64k;
    fastcgi_buffers 4 64k;
    fastcgi_busy_buffers_size 128k;
    fastcgi_temp_file_write_size 128k;

    ###作为代理缓存服务器设置#######
    ###先写到 temp 再移动到 cache
    #proxy_cache_path /var/tmp/nginx/proxy_cache levels=1:2 keys_zone=cache_one:512m inactive=10m max_size=64m;
    ###以上 proxy_temp 和 proxy_cache 需要在同一个分区中
    ###levels=1:2 表示缓存级别,表示缓存目录的第一级目录是 1 个字符,第二级目录是 2 个字符 keys_zone=cache_one:128m 缓存空间起名为 cache_one 大小为 512m
    ###max_size=64m 表示单个文件超过 128m 就不缓存了  inactive=10m 表示缓存的数据,10 分钟内没有被访问过就删除
    #########end####################

    #####对传输文件压缩###########
    #gzip 模块设置
    gzip on; #开启 gzip 压缩输出
    gzip_min_length 1k; #最小压缩文件大小
    gzip_buffers 4 16k; #压缩缓冲区
    gzip_http_version 1.0; #压缩版本(默认 1.1,前端如果是 squid2.5 请使用 1.0)
    gzip_comp_level 2; #压缩等级,gzip 压缩比,1 为最小,处理最快;9 为压缩比最大,处理最慢,传输速度最快,也最消耗 CPU;
    gzip_types text/plain application/x-javascript text/css application/xml;
    #压缩类型,默认就已经包含 text/html,所以下面就不用再写了,写上去也不会有问题,但是会有一个 warn。
    gzip_vary on;
    ##############################

    #limit_zone crawler $binary_remote_addr 10m; #开启限制 IP 连接数的时候需要使用

    upstream blog.ha97.com {
        #upstream 的负载均衡,weight 是权重,可以根据机器配置定义权重。weigth 参数表示权值,权值越高被分配到的几率越大。
        server 192.168.80.121:80 weight=3;
        server 192.168.80.122:80 weight=2;
        server 192.168.80.123:80 weight=3;
    }

    #虚拟主机的配置
    server {
        #监听端口
        listen 80;

        #############https##################
        #listen 443 ssl;
        #ssl_certificate /opt/https/xxxxxx.crt;
        #ssl_certificate_key /opt/https/xxxxxx.key;
        #ssl_protocols SSLv3 TLSv1;
        #ssl_ciphers HIGH:!ADH:!EXPORT57:RC4+RSA:+MEDIUM;
        #ssl_prefer_server_ciphers on;
        #ssl_session_cache shared:SSL:2m;
        #ssl_session_timeout 5m;
        ####################################end

        #域名可以有多个,用空格隔开
        server_name www.ha97.com ha97.com;
        index index.html index.htm index.php;
        root /data/www/ha97;
        location ~ .*.(php|php5)?$ {
            fastcgi_pass 127.0.0.1:9000;
            fastcgi_index index.php;
            include fastcgi.conf;
        }

        #图片缓存时间设置
        location ~ .*.(gif|jpg|jpeg|png|bmp|swf)$ {
            expires 10d;
        }

        #JS 和 CSS 缓存时间设置
        location ~ .*.(js|css)?$ {
            expires 1h;
        }

        #日志格式设定
        log_format access '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" $http_x_forwarded_for';

        #定义本虚拟主机的访问日志
        access_log /var/log/nginx/ha97access.log access;

        #对 "/" 启用反向代理
        location / {
            proxy_pass http://127.0.0.1:88;
            proxy_redirect off;
            proxy_set_header X-Real-IP $remote_addr;
            #后端的 Web 服务器可以通过 X-Forwarded-For 获取用户真实 IP
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            #以下是一些反向代理的配置,可选。
            proxy_set_header Host $host;
            client_max_body_size 10m; #允许客户端请求的最大单文件字节数
            client_body_buffer_size 128k; #缓冲区代理缓冲用户端请求的最大字节数,

            ##代理设置 以下设置是 nginx 和后端服务器之间通讯的设置##
            proxy_connect_timeout 90; #nginx 跟后端服务器连接超时时间(代理连接超时)
            proxy_send_timeout 90; #后端服务器数据回传时间(代理发送超时)
            proxy_read_timeout 90; #连接成功后,后端服务器响应时间(代理接收超时)
            proxy_buffering on;    #该指令开启从后端被代理服务器的响应内容缓冲 此参数开启后 proxy_buffers 和 proxy_busy_buffers_size 参数才会起作用
            proxy_buffer_size 4k;  #设置代理服务器(nginx)保存用户头信息的缓冲区大小
            proxy_buffers 4 32k;   #proxy_buffers 缓冲区,网页平均在 32k 以下的设置
            proxy_busy_buffers_size 64k; #高负荷下缓冲大小(proxy_buffers*2)
            proxy_max_temp_file_size 2048m; #默认 1024m, 该指令用于设置当网页内容大于 proxy_buffers 时,临时文件大小的最大值。如果文件大于这个值,它将从 upstream 服务器同步地传递请求,而不是缓冲到磁盘
            proxy_temp_file_write_size 512k; 这是当被代理服务器的响应过大时 nginx 一次性写入临时文件的数据量。
            proxy_temp_path  /var/tmp/nginx/proxy_temp;    ##定义缓冲存储目录,之前必须要先手动创建此目录
            proxy_headers_hash_max_size 51200;
            proxy_headers_hash_bucket_size 6400;
            #######################################################
        }

        #设定查看 nginx 状态的地址
        location /nginxStatus {
            stub_status on;
            access_log on;
            auth_basic "nginxStatus";
            auth_basic_user_file conf/htpasswd;
            #htpasswd 文件的内容可以用 apache 提供的 htpasswd 工具来产生。
        }

        #本地动静分离反向代理配置
        #所有 jsp 的页面均交由 tomcat 或 resin 处理
        location ~ .(jsp|jspx|do)?$ {
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_pass http://127.0.0.1:8080;
        }

        #所有静态文件由 nginx 直接读取不经过 tomcat 或 resin
        location ~ .*.(htm|html|gif|jpg|jpeg|png|bmp|swf|ioc|rar|zip|txt|flv|mid|doc|ppt|pdf|xls|mp3|wma)$
        { expires 15d; }

        location ~ .*.(js|css)?$
        { expires 1h; }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190

# 4.Nginx 配置语法

比如说我们的 nginx 配置文件在 /usr/local/nginx/conf/nginx.conf中,你以进行 cat /usr/local/nginx/conf/nginx.conf 查看 nginx 配置

main        # 全局配置,对全局生效
├── events  # 配置影响 Nginx 服务器或与用户的网络连接
├── http    # 配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置
│   ├── upstream # 配置后端服务器具体地址,负载均衡配置不可或缺的部分
│   ├── server   # 配置虚拟主机的相关参数,一个 http 块中可以有多个 server 块
│   ├── server
│   │   ├── location  # server 块可以包含多个 location 块,location 指令用于匹配 uri
│   │   ├── location
│   │   └── ...
│   └── ...
└── ...
1
2
3
4
5
6
7
8
9
10
11

一个 Nginx 配置文件的结构就像 nginx.conf 显示的那样,配置文件的语法规则:

  1. 配置文件由指令与指令块构成;
  2. 每条指令以 ; 分号结尾,指令与参数间以空格符号分隔;
  3. 指令块以 {} 大括号将多条指令组织在一起;
  4. include 语句允许组合多个配置文件以提升可维护性;
  5. 使用 # 符号添加注释,提高可读性;
  6. 使用 $符号使用变量;
    部分指令的参数支持正则表达式;

# 4.1 经典配置

user  nginx;                        # 运行用户,默认即是nginx,可以不进行设置
worker_processes  1;                # Nginx 进程数,一般设置为和 CPU 核数一样
error_log  /var/log/nginx/error.log warn;   # Nginx 的错误日志存放目录
pid        /var/run/nginx.pid;      # Nginx 服务启动时的 pid 存放位置

events {
    use epoll;     # 使用epoll的I/O模型(如果你不知道Nginx该使用哪种轮询方法,会自动选择一个最适合你操作系统的)
    worker_connections 1024;   # 每个进程允许最大并发数
}

http {   # 配置使用最频繁的部分,代理、缓存、日志定义等绝大多数功能和第三方模块的配置都在这里设置
    # 设置日志模式
    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  /var/log/nginx/access.log  main;   # Nginx访问日志存放位置

    sendfile            on;   # 开启高效传输模式
    tcp_nopush          on;   # 减少网络报文段的数量
    tcp_nodelay         on;
    keepalive_timeout   65;   # 保持连接的时间,也叫超时时间,单位秒
    types_hash_max_size 2048;

    include             /etc/nginx/mime.types;      # 文件扩展名与类型映射表
    default_type        application/octet-stream;   # 默认文件类型

    include /etc/nginx/conf.d/*.conf;   # 加载子配置项

    server {
    	listen       80;       # 配置监听的端口
    	server_name  localhost;    # 配置的域名

    	location / {
    		root   /usr/share/nginx/html;  # 网站根目录
    		index  index.html index.htm;   # 默认首页文件
    		deny 172.168.22.11;   # 禁止访问的ip地址,可以为all
    		allow 172.168.33.44; # 允许访问的ip地址,可以为all
    	}

    	error_page 500 502 503 504 /50x.html;  # 默认50x对应的访问页面
    	error_page 400 404 error.html;   # 同上
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

# 5 Nginx 实战

# 5.1 前端 vue 传统的 spa 项目打包

针对于 Vue MPA 工程,工程里会存在多个业务,每个业务都是一个 SPA。假设上线后, 前端模板代码都位于 /data/mandalat-web/ 目录下,该目录结构如下:

├── front-end
|   └── index.html
├── back-end
|   ├── index.html
|   └── main.html
├── es6
|   └── index.html
├── vue
|   └── index.html
├── test
|   └── index-test.html
1
2
3
4
5
6
7
8
9
10
11

其中,front-end、back-end、es6、vue分别代表不同的业务,每个业务都是 SPA。
这时候我想访问 分别访问 front-end、back-end、es6、vue

Nginx 的 nginx.conf 配置文件如下:

server {
    listen      8080;

    # 访问日志
    access_log  /data/logs/nginx/access.log  main;
    error_log  /data/logs/nginx/error.log;

    keepalive_requests 30;

    # 根目录,在如下描述中用 $root 占位
    root /data/mandalat-web/;

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

    error_page   403  /403.html;
    location = /403.html {
        root   html;
    }

    error_page  404  /404.html;
    location = /404.html {
        root   html;
    }

    location /front-end/ {
        try_files $uri $uri/ /front-end/index.html;
        index index.html;
    }

    location /back-end/ {
        try_files $uri $uri/ /back-end/index.html;
        index index.html;
    }

    location /es6/ {
        try_files $uri $uri/ /es6/index.html;
        index index.html;
    }

    location /test/hello {
        try_files $uri $uri/ /es6/index.html;
        index world.html;
    }
    # ...
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

# 5.1 location 匹配流程

location = / {
    # 完全匹配  =
    # 大小写敏感 ~
    # 忽略大小写 ~*
}
location ^~ /images/ {
    # 前半部分匹配 ^~
    # 可以使用正则,如:
    # location ~* \.(gif|jpg|png)$ { }
}
location / {
    # 如果以上都未匹配,会进入这里
}
1
2
3
4
5
6
7
8
9
10
11
12
13

server 块可以包含多个 location 块,location 指令用于匹配 uri,语法:

location [ = | ~ | ~* | ^~] uri {
	...
}
1
2
3

指令后面:

  1. = 精确匹配路径,用于不含正则表达式的 uri 前,如果匹配成功,不再进行后续的查找;
  2. ^~ 用于不含正则表达式的 uri; 前,表示如果该符号后面的字符是最佳匹配,采用该规则,不再进行后续的查找;
  3. ~ 表示用该符号后面的正则去匹配路径,区分大小写;
  4. ~* 表示用该符号后面的正则去匹配路径,不区分大小写。跟 ~ 优先级都比较低,如有多个 location 的正则能匹配的话,则使用正则表达式最长的那个;

匹配流程:

# 5.2 root 和 alias

假设访问 es6 语法 root与alias的区别主要在于 Nginx 如何解释location后面的路径的 URI,这会使两者分别以不同的方式将请求映射到服务器文件上。具体来看:

root 的处理结果是:root路径+location路径 alias 的处理结果是:使用alias路径替换location路径

例如,如下的 Nginx 配置:

server {
    listen              9001;
    server_name         localhost;
    location /hello {
        root            /usr/local/var/www/;
    }
}
1
2
3
4
5
6
7

在请求http://localhost:9001/hello/时,真实服务器返回的路径地址应该是/usr/local/var/www/hello/index.html

当使用 alias 时:

server {
    listen              9001;
    server_name         localhost;
    location /hello {
        alias           /usr/local/var/www/;
    }
}
1
2
3
4
5
6
7

在请求 http://localhost:9001/hello/ 时,服务器返回的路径地址应该是 /usr/local/var/www/index.html(用 alias 后面的路径将请求的 location 的地址 hello 替换掉)

另外,要注意的是,alias 路径后面必须使用/结束,否则无法匹配正确的路径,而 root 后则可有可无。所以建议都加上/,反之出错

提示

alias 大多数是处理 文件静态资源的。

# 5.2 try_files

当访问 http://192.168.8.55/es6/array 时,会经过 Nginx 的如下规则处理。

  location /es6/ {
        try_files $uri $uri/ /es6/index.html;
        index index.html;
  }
1
2
3
4

根据try_files的写法,

  1. 首先,查找$uri即/es6/array,也就是$root/es6文件夹下的 array 文件,找到则返回文件,否则进入下一步;
  2. 其次,查找$uri/即/es6/array/,也就是$root/es6/array文件夹,查看该文件夹下是否有index.html文件,有则返回文件,否则进入下一步;
  3. 最后,查找/es6/index.html,即$root/es6/index.html文件,有则返回。

⚠️ 注意

  1. 当 location 中有设置 root 时,try_files 路径是开始是从 root 目录下开始的,假如配置这样
    location /test/hello {
        root /data/front;
        try_files $uri $uri/ /es6/index.html;
        index world.html;
    }
1
2
3
4
5

当访问 http://192.168.8.55/test/hello/1.wps 时,真实访问地址是 http://192.168.8.55/data/front/test/hello/1.wps,会经过 Nginx 的如下规则处理。它会访问 本台服务器 /data/front/test/hello/1.wps,假设找不到,这时候会默认返回一个默认的 /data/front/es6/index.html

  1. 当 location 中有设置 alias 时,try_files 路径是开始是从 最近的 root 目录下开始的,如果上级没有设置 root,那么会从 nginx 的安装默认位置中html 算起,
    location /test/hello {
        alias /data/front;
        try_files $uri $uri/ /es6/index.html;
        index world.html;
    }
1
2
3
4
5

比如我们设定 nginx 中 html 目录地址是 /usr/local/nginx/html 当访问 http://192.168.8.55/test/hello/1.wps 时,真实访问地址是 http://192.168.8.55/data/front/1.wps,会经过 Nginx 的如下规则处理。 它会访问 本台服务器 /data/front/1.wps,假设找不到,这时候会默认返回一个默认的 /usr/local/nginx/html/es6/index.html

# 5.3 index

当访问 http://192.168.8.55/es6/array 时,会经过 Nginx 的如下规则处理。

    location /test/hello {
        try_files $uri $uri/ /es6/index.html;
        index world.html;
    }
1
2
3
4

先按照 try_files 进行处理,当处理第二步的$uri/时,会结合index world.html,此时会查找/test/hello/world.html是否存在,不存在则进入下一步。

因此 location 里的 index 的作用时,在查找文件夹时,指定该文件夹下默认匹配的文件。因此当访问 http://localhost:9527/test/hello 时,会返回``

# 5.4 proxy_pass

实际使用中,可以将请求转发到本机另一个服务器上,也可以根据访问的路径跳转到不同端口的服务中。 比如我们监听 9001 端口,然后把访问不同路径的请求进行反向代理:

  1. 把访问 http://127.0.0.1:9001/edu 的请求转发到 http://127.0.0.1:8080
  2. 把访问 http://127.0.0.1:9001/vod 的请求转发到 http://127.0.0.1:8081

这种要怎么配置呢,首先同样打开主配置文件,然后在 http 模块下增加一个 server 块:

server {
  listen 9001;

  location ~ /edu/ {
    proxy_pass http://127.0.0.1:8080;
    rewrite ^/edu/(.*)$ /$1 break;
  }

  location ~ /vod/ {
    proxy_pass http://127.0.0.1:8081;
  }
}
1
2
3
4
5
6
7
8
9
10
11
12

反向代理还有一些其他的指令,可以了解一下:

  1. proxy_set_header:在将客户端请求发送给后端服务器之前,更改来自客户端的请求头信息。
  2. proxy_connect_timeout:配置 Nginx 与后端代理服务器尝试建立连接的超时时间。
  3. proxy_read_timeout:配置 Nginx 向后端服务器组发出 read 请求后,等待相应的超时时间。
  4. proxy_send_timeout:配置 Nginx 向后端服务器组发出 write 请求后,等待相应的超时时间。
  5. proxy_redirect:用于修改后端服务器返回的响应头中的 Location 和 Refresh。

# 5.5 rewrite

rewrite模块即ngx_http_rewrite_module模块,主要功能是改写请求 URI,是Nginx默认安装的模块。rewrite模块会根据 PCRE 正则匹配重写URI,然后发起内部跳转再匹配location,或者直接做 30x 重定向返回客户端。

场景:假设后端 api 服务器地址是 192.168.8.55:3280,前端在业务项目中用特定标识前缀开头,比如用 /grade,我们可以在server下,我们前端打包部署在8081端口号上

server {
  listen 8081;

  location / {
      root /data/grade-ui;
      index index.html index.htm;
      try_files $uri $uri/ index.html;
  }

  location ^~ /grade/ {
    proxy_pass 192.168.8.55:3280;
    rewrite ^/grade/(.*)$ /$1 break;
  }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

其中的 $1 指的是 (.*),由配置我们可以知道,nginx 判断请求路径 开头是否是/grade,如果是 将/grade开头去除,保留后面url,然后代理到192.168.8.55:3280 上

rewrite 参考文档 (opens new window)

break 和 last 区别、permanent 和 redirect 区别 (opens new window)

# 5.5 upstream

主要思想就是把负载均匀合理地分发到多个服务器上,实现压力分流的目的。

主要配置如下:

http {
  upstream myserver {
  	# ip_hash;  # ip_hash 方式
    # fair;   # fair 方式
    server 127.0.0.1:8081;  # 负载均衡目的服务地址
    server 127.0.0.1:8080;
    server 127.0.0.1:8082 weight=10;  # weight 方式,不写默认为 1
  }

  server {
    location / {
      proxy_pass http://myserver;
      proxy_connect_timeout 10;
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

Nginx 提供了好几种分配方式,默认为轮询,就是轮流来。有以下几种分配方式:

  1. 轮询,默认方式,每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务挂了,能自动剔除;
  2. weight,权重分配,指定轮询几率,权重越高,在被访问的概率越大,用于后端服务器性能不均的情况;
  3. ip_hash,每个请求按访问 IP 的 hash 结果分配,这样每个访客固定访问一个后端服务器,可以解决动态网页 session 共享问题。负载均衡每次请求都会重新定位到服务器集群中的某一个,那么已经登录某一个服务器的用户再重新定位到另一个服务器,其登录信息将会丢失,这样显然是不妥的;
  4. fair(第三方),按后端服务器的响应时间分配,响应时间短的优先分配,依赖第三方插件 nginx-upstream-fair,需要先安装;

# 6.结合院内实际业务中使用 🔥

# 6.1 背景

前后端分离虽然是 ajax 的功劳,但是真根本性的问题是路由跳转到底是谁来控制,谁来进行跳转。前端分离后,前端路由跳转是交由前端来把控。
前端路由模式常用的分为两种:

  1. hash 模式,利用浏览器原生的提供的抛锚事件 window.addEventListener('hashchange', e => {})。监听到变化根据#后面的链接地址,去注册路由 path 中正则匹配,匹配到的将对应的路由组件(component)渲染出来。
  2. history 模式, 利用浏览器原生的提供的抛锚事件 window.addEventListener('popstate', e => {}).监听到变化根据#后面的链接地址,去注册路由 path 中正则匹配,匹配到的将对应的路由组件(component)渲染出来。

前端项目又分为mpa项目和spa项目。我们公司大多数产品都是spa项目。

前端请求接口会产生跨域(同源策略),发布到生产线上,可能也要调其他非本后端的接口。

# 6.1 例子一 广东等级评审

假设我们以 广东等级评审 为例子。我的需求是这样的。

  • 将前端部署在 192.168.8.55 服务器中文件夹 /data/grade-ui 下,
  • 代理接口到后端服务器地址 192.168.8.55:3280,
  • 不要挂载到端口根路径下,能够允许多个项目部署在同一个端口8081上访问。
  • 要求浏览器访问广东等级评审项目,地址是这样的 http://192.168.8.55:8081/review-gd/xxxx访问
  1. 前端采用路由 history 模式。
const router = new VueRouter({
    mode: 'history',
    base: import.meta.env.BASE_URL + '/front',
    routes: ....
})
1
2
3
4
5
  1. 前端打包目录:
dist
├── assets
│  ├── -anesthesia-legacy.898d93ea.js
│  ├── -anesthesia-legacy.898d93ea.js.gz
│  ├── vendor.60602741.js
│  └── vendor.60602741.js.gz
|       ....
├── favicon.ico
├── front
│  ├── index.html
│  └── index.html.gz
1
2
3
4
5
6
7
8
9
10
11

前端需要做法

  1. 需要在 vite 打包中配置 base,找到项目根路径下 vite.config.js文,如果是以webpack为为基础的,比如 vue-cli,找到根路径下 vue.config.js,设置publicPath。
export default defineConfig(({ mode }) => {
  const IS_PRO = mode === 'production'
  const publicPath = IS_PRO ? '/review-gd/' : '' // 指定打包前缀,设置打包 打包静态资源文件前缀

  return {
    base: publicPath,
    ...
  })

1
2
3
4
5
6
7
8
9
  1. 在192.168.8.55服务器中/data/grade-ui,新建review-gd 文件夹, 注意一定要 新建文件夹名字和请求前缀名一致
├── data
│   └── grade-ui
│       └── review-gd
│           └── ...
|   ...
1
2
3
4
5
  1. 配置 nginx.conf文件,找到 nginx.conf 文件里面 include /usr/local/nginx/conf.d/*.conf。 进入 /usr/local/nginx/conf.d 目录中。 新建一个 文件以 .conf为结尾的配置文件,这里我起了grade-ui.conf。

server {
    listen                    8080;
    server_name               localhost;

    root                      /data/grade-ui;  # 顶级设置了root

    # 代理接口
    location /grade {
        proxy_pass            http://localhost:3280; #代理的地址
        rewrite               ^/grade/(.*)$ /grade/$1 break;  # 重写路径
    }

    # 假如前端需要访问其他接口地址,前端在代码中给出特定标识开头,比如 /grade-gd
    location /grade-gd {
        proxy_pass            http://localhost:3281; #代理的地址
        rewrite               ^//grade-gd/(.*)$ /grade/$1 break;  # 重写路径
    }

    location ^~ /review-gd {
        root                  /data/grade-ui;
        try_files             $uri $uri/ /review-gd/front/index.html;  # 表示找不到资源,始终返回 /data/grade-ui/review-gd/front/index.html资源文件
        index                 index.html index.htm;
        #设置某个文件不缓存读取本地,永远走200,拿到最新的
        if ($request_filename ~* .*\.(?:htm|html)$) {
            add_header        Cache-Control "private, no-store, no-cache, must-revalidate, proxy-revalidate";
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

# Q1: 如果我前端是hash模式路由,该怎么配置?

  1. 需要在 vite 打包中配置 base,找到项目根路径下 vite.config.js文,如果是以webpack为为基础的,比如 vue-cli,找到根路径下 vue.config.js,设置publicPath。
export default defineConfig(({ mode }) => {
  const IS_PRO = mode === 'production'
  const publicPath = IS_PRO ? './' : '' // 设置相对路径,设置打包 打包静态资源文件前缀

  return {
    base: publicPath,
    ...
  })
1
2
3
4
5
6
7
8
  1. nginx 配置和上面一样。

# Q2: 我想继续采用history模式,我配置不想在locaton中使用用root,我想改用alias比较直观?

nginx 配置如下

server {
    listen                    8080;
    server_name               localhost;

    root                      /data/grade-ui; # 顶级设置根路径

    # 代理接口
    location /grade {
        proxy_pass            http://localhost:3280; #代理的地址
        rewrite               ^/grade/(.*)$ /grade/$1 break;  # 重写路径
    }

    # 假如前端需要访问其他接口地址,前端在代码中给出特定标识开头,比如 /grade-gd
    location /grade-gd {
        proxy_pass            http://localhost:3281; #代理的地址
        rewrite               ^/grade-gd/(.*)$ /grade/$1 break;  # 重写路径
    }

    location ^~ /review-gd {
        alias                  /data/grade-ui/review-gd/;  # 用alias必须要/为结尾
        try_files             $uri $uri/ /review-gd/front/index.html;
        index                 index.html index.htm;
        #设置某个文件不缓存读取本地,永远走200,拿到最新的
        if ($request_filename ~* .*\.(?:htm|html)$) {
            add_header        Cache-Control "private, no-store, no-cache, must-revalidate, proxy-revalidate";
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

# 6.2 例子二 危重、广东、重庆四个项目放在一个项目下

要求

  • 危重、广东、重庆四个项目放在一个项目下,都是通过同一个端口号8088访问
  • 将前端部署在 192.168.8.55 服务器中文件夹 /data/grade-ui 下,
  • 项目case、critical、examine、subject、target项目接口代理192.168.8.55:3280,review-gd项目接口代理到192.168.8.55:3281,
  • 要求浏览器访问case项目,地址 http://192.168.8.55:8088/case/index.html/#/xxxx访问
  • 要求浏览器访问critical项目,地址 http://192.168.8.55:8088/critical/index.html/#/xxxx访问
  • 要求浏览器访问examine项目,地址 http://192.168.8.55:8088/examine/index.html/#/xxxx访问
  • 要求浏览器访问subject项目,地址 http://192.168.8.55:8088/subject/index.html/#/xxxx访问
  • 要求浏览器访问target项目,地址 http://192.168.8.55:8088/target/index.html/#/xxxx访问
  • 要求浏览器访问review-gd项目,地址 http://192.168.8.55:8088/review-gd/xxxx访问
  1. 前端打包后的合并的文件目录如下
├── assets
│  ├── windi.c6df3ebe.js
│  └── windi.c6df3ebe.js.gz
├── case  # 危重项目 hash模式,路径设置为./
│  ├── index.html
│  └── index.html.gz
├── critical
│  ├── index.html
│  └── index.html.gz
├── examine # examine项目 hash模式,路径设置为./
│  ├── index.html
│  └── index.html.gz
├── favicon.ico
├── review-gd # 广东绩效 history模式,路径设置为/review-gd
│  ├── assets
│  │  ├── vendor.60602741.js
│  │  └── vendor.60602741.js.gz
│  ├── favicon.ico
│  ├── front
│  │  ├── index.html
│  │  └── index.html.gz
├── subject # subject项目 hash模式,路径设置为./
│  ├── index.html
│  └── index.html.gz
└── target # examine项目 hash模式,路径设置为./
    ├── index.html
    └── index.html.gz
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

因为 case、critical、examine、subject、target都是 hash 路由模式,而广东绩效项目review-gd是 history 模式。

配置如下:

server {
    listen                    8088;  #设定端口号
    server_name               localhost;

    root                      /data/grade-ui;  #部署地址,文件存放的地址

    location /grade {
        proxy_pass            http://localhost:3280;  # `case`、`critical`、`examine`、`subject`、`target` 项目后端接口地址
        rewrite               ^/grade/(.*)$ /grade/$1 break;
    }

    location /grade-gd {
        proxy_pass            http://localhost:3281; # `review-gd` 后端接口地址
        rewrite               ^/grade-gd/(.*)$ /grade/$1 break;
    }

    location ^~ /review-gd {
        try_files             $uri $uri/ /review-gd/front/index.html;
        index                 index.html index.htm;
        #设置某个文件不缓存读取本地,永远走200,拿到最新的
        if ($request_filename ~* .*\.(?:htm|html)$) {
            add_header        Cache-Control "private, no-store, no-cache, must-revalidate, proxy-revalidate";
        }
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

# 7.单个部署

总的来说 前端 pc 项目要推荐采用 hash 模式,配置 理由如下:

  1. 兼容性强
  2. nginx 配置简单、方便【主要原因】
  3. 因为是 pc 场景,基本不会出现和第三方对接,比如微信,因为从微信有些地方中转过来,链接中携带#会被微信拦截掉。

前端一般 spa 打包出的项目结构如下:

├── config.js
├── css
│  ├── app.54cd93ee.css
│  ├── chunk-1b329e6a.2953a92f.css
│  ├── chunk-2394cd92.ae6b30f4.css
│  ├── xxxx
├── favicon.ico
├── fonts
│  ├── element-icons.535877f5.woff
│  └── element-icons.732389de.ttf
├── img
│  ├── bpf-error-404.b0e61908.jpg
│  └── logo-white.68740006.png
├── inject
│  ├── css
│  │  └── loading.css
│  └── js
│      ├── jsplumb.js
│      ├── jsplumb.min.js
│      └── preload.js
├── js
│  ├── app.ba205fb1.js
│  ├── chunk-1b329e6a.7eae04ce.js
│  ├── chunk-2394cd92.7eb8acd8.js
│  ├── chunk-2d0baac6.47f8b7fa.js
│  └── chunk-vendors.e6fdc261.js
├── index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

# 7.1 部署要求

  1. 服务器地址 192.168.5.88,前端部署端口号 10001,存放在 /data/front/project 目录下
  2. 后端接口部署的地址:192.168.5.88,端口号 10002
  3. 前端使用调用接口前缀:back-api

# 7.2 前端准备

  1. 如果项目基于vue-cli的,vue-cli中的设置 vue.config.js,本质上是进行 webpack 操作
const IS_PRO = process.env.NODE_ENV === 'production'  // 是否是生产环境打包
module.exports = {
  publicPath: IS_PRO ? './' : '/', // 打包静态资源文件前缀
  ...
}
1
2
3
4
5

如果项目是基于 vite 的,需要在 vite 打包中配置 base,找到项目根路径下 vite.config.js文,修改如下

export default defineConfig(({ mode }) => {
  const IS_PRO = mode === 'production'
  const publicPath = IS_PRO ? '/review-gd/' : '' // 指定打包前缀,设置打包 打包静态资源文件前缀
  return {
    base: publicPath,
    ...
  })
1
2
3
4
5
6
7
  1. vue-router 配置
const router = new Router({
  mode: 'hash',
//   base: process.env.BASE_URL,  base只有是history路由匹配
  routes,
  ...
})
1
2
3
4
5
6
  1. 在 public 目录下新建 nginx.conf,

要告知测试前端有哪些接口是要代理的。

server {
    listen                    xxx;  #设定端口号,【可修改】
    server_name               localhost; #设置当前服务名

    # root                      /data/grade-ui;  #部署地址,前端存放的地址,这里选择不甜

    # 前端项目匹配规则
    location / {
        root                    xxx; # 前端文件存放的地址【可修改】
        try_files               $uri $uri/ /index.html; # 这里要保证前端打包出来的index.html是在 root 根路径下,根据实际情况。
        index                   index.html;
         #设置某个文件不缓存读取本地,永远走200,拿到最新的,防止缓存情况
        if ($request_filename ~* .*\.(?:htm|html)$) {
            add_header        Cache-Control "private, no-store, no-cache, must-revalidate, proxy-revalidate";
        }
    }

    # 前端请求后端接口前缀 back-api,走代理
    location ^~ /back-api {
        proxy_pass            xxx; # 代理后端接口地址,如果前、后端部署在同一台服务器上,这里可以写localhost 【可修改】
        rewrite               ^/back-api/(.*)$ /$1 break; # 这里的 $1 等于 (.*) 里的内容,break这里表示不需要在交给nginx进行location再次匹配了。【可修改】
    }

    # 注:如果前端要调用多个后端地址,写成和上面的类似,一些参数自行调整

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

# 7.3 测试人员准备

  1. 找到 nginx 所在的位置
[root@iZuf6eednvvtf310byi0kaZ ~]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@iZuf6eednvvtf310byi0kaZ ~]#
1
2
3
4
  1. 查看的 /usr/local/nginx/conf/nginx.conf,配置文件内容,找到include xxx/nginx.d/*.conf;,这样类似的位置,比如我从服务器中找的一张截图。
# 进入 /etc/nginx/nginx.d/ 下
[root@iZuf6eednvvtf310byi0kaZ nginx.d]# cd /etc/nginx/nginx.d/

# 在其目录下新建demo.10001.conf,新建文件名根据实际情况 按照这样的格式 [项目名].[端口号].conf
[root@iZuf6eednvvtf310byi0kaZ nginx.d]# touch demo.10001.conf

# 编辑内容
[root@iZuf6eednvvtf310byi0kaZ nginx.d]# vim demo.10001.conf

# 拿到前端部署根路径下的 nginx.conf 配置文件,根据实际情况替换xxx。

server {
    listen                    10001;  #设定端口号,【可修改】
    server_name               localhost; #设置当前服务名

    # root                      /data/grade-ui;  #部署地址,前端存放的地址,这里选择不甜

    # 前端项目匹配规则
    location / {
        root                    /data/front/project; # 前端文件存放的地址【可修改】
        try_files               $uri $uri/ /index.html; # 这里要保证前端打包出来的index.html是在 root 根路径下,根据实际情况。
        index                   index.html;
         #设置某个文件不缓存读取本地,永远走200,拿到最新的,防止缓存情况
        if ($request_filename ~* .*\.(?:htm|html)$) {
            add_header        Cache-Control "private, no-store, no-cache, must-revalidate, proxy-revalidate";
        }
    }

    # 前端请求后端接口前缀 back-api,走代理
    location ^~ /back-api {
        proxy_pass            http://192.168.5.88:10002; # 代理后端接口地址,如果前、后端部署在同一台服务器上,这里可以写localhost 【可修改】
        rewrite               ^/back-api/(.*)$ /$1 break; # 这里的 $1 等于 (.*) 里的内容,break这里表示不需要在交给nginx进行location再次匹配了。【可修改】
    }
}

# wq保存


# 重新启动nginx,让nginx重新读取配置
[root@iZuf6eednvvtf310byi0kaZ nginx.d]# nginx -s reload
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

# 8.多个项目部署

总的来说 前端 pc 项目要推荐采用 hash 模式,配置 理由如下:

  1. 兼容性强
  2. nginx 配置简单、方便【主要原因】
  3. 因为是 pc 场景,基本不会出现和第三方对接,比如微信,因为从微信有些地方中转过来,链接中携带#会被微信拦截掉。

前端一般 spa 打包出的项目结构如下:

# 8.1 部署要求

  1. 服务器地址 192.168.5.88,前端部署端口号 10001,存放在 /data/front/project 目录下
  2. 后端接口部署的地址:192.168.5.88,端口号 10002
  3. 在一个项目下5个项目部署在同一个端口上,根据不同的接口前缀代理不同的地址。
  4. A项目,访问地址 http://192.168.5.88:10001/A/#/xxxx
  5. B项目,访问地址 http://192.168.5.88:10001/B/#/xxxx
  6. C项目,访问地址 http://192.168.5.88:10001/C/#/xxxx
  7. D项目,访问地址 http://192.168.5.88:10001/D/#/xxxx
  8. E项目,访问地址 http://192.168.5.88:10001/E/#/xxxx
├── A  # A hash模式,路径设置为./ 接口前缀 A-api,代理地址是 192.168.5.88:8001
│  ├── static
│  ├── ...
│  ├── nginx.conf
│  └── index.html
├── B  # B hash模式,路径设置为./ 接口前缀 B-api,代理地址是 192.168.5.88:8002
│  ├── static
│  ├── ...
│  ├── nginx.conf
│  └── index.html
├── C  # C hash模式,路径设置为./ 接口前缀 C-api,代理地址是 192.168.5.88:8003
│  ├── static
│  ├── ...
│  ├── nginx.conf
│  └── index.html
├── D  # D hash模式,路径设置为./ 接口前缀 D-api,代理地址是 192.168.5.88:8004
│  ├── static
│  ├── ...
│  ├── nginx.conf
│  └── index.html
├── E  # E hash模式,路径设置为./ 接口前缀 E-api,代理地址是 192.168.5.88:8005
│  ├── static
│  ├── ...
│  ├── nginx.conf
│  └── index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

# 8.2 前端准备

⚠️ 下面相当于每个项目基本是这样打包配置流程,以A项目为例子

  1. 如果项目基于vue-cli的,vue-cli中的设置 vue.config.js,本质上是进行 webpack 操作
const IS_PRO = process.env.NODE_ENV === 'production'  // 是否是生产环境打包
module.exports = {
  publicPath: IS_PRO ? './' : '/', // 打包静态资源文件前缀
  ...
}
1
2
3
4
5

如果项目是基于 vite 的,需要在 vite 打包中配置 base,找到项目根路径下 vite.config.js文,修改如下

export default defineConfig(({ mode }) => {
  const IS_PRO = mode === 'production'
  const publicPath = IS_PRO ? '/review-gd/' : '' // 指定打包前缀,设置打包 打包静态资源文件前缀
  return {
    base: publicPath,
    ...
  })
1
2
3
4
5
6
7
  1. vue-router 配置
const router = new Router({
  mode: 'hash',
//   base: process.env.BASE_URL,  base只有是history路由匹配
  routes,
  ...
})
1
2
3
4
5
6
  1. 在 public 目录下新建 nginx.conf,

要告知测试前端有哪些接口是要代理的。

server {
    listen                    xxx;  #设定端口号,【可修改】
    server_name               localhost; #设置当前服务名

    # root                      /data/grade-ui;  #部署地址,前端存放的地址,这里选择不甜

    # 前端项目匹配规则
    location / {
        root                    xxx; # 前端文件存放的地址【可修改】
        try_files               $uri $uri/ /index.html; # 这里要保证前端打包出来的index.html是在 root 根路径下,根据实际情况。
        index                   index.html;
         #设置某个文件不缓存读取本地,永远走200,拿到最新的,防止缓存情况
        if ($request_filename ~* .*\.(?:htm|html)$) {
            add_header        Cache-Control "private, no-store, no-cache, must-revalidate, proxy-revalidate";
        }
    }

    # 前端请求后端接口前缀 A-api,走代理
    location ^~ /A-api {
        proxy_pass            xxx; # 代理后端接口地址,如果前、后端部署在同一台服务器上,这里可以写localhost 【可修改】
        rewrite               ^/A-api/(.*)$ /$1 break; # 这里的 $1 等于 (.*) 里的内容,break这里表示不需要在交给nginx进行location再次匹配了。【可修改】
    }

    # 注:如果前端要调用多个后端地址,写成和上面的类似,一些参数自行调整

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

# 8.3 测试准备

[root@iZuf6eednvvtf310byi0kaZ ~]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@iZuf6eednvvtf310byi0kaZ ~]#
1
2
3
4
  1. 查看的 /usr/local/nginx/conf/nginx.conf,配置文件内容,找到include xxx/nginx.d/*.conf;,这样类似的位置,比如我从服务器中找的一张截图。
# 进入 /etc/nginx/nginx.d/ 下
[root@iZuf6eednvvtf310byi0kaZ nginx.d]# cd /etc/nginx/nginx.d/

# 在其目录下新建demo.10001.conf,新建文件名根据实际情况 按照这样的格式 [项目名].[端口号].conf
[root@iZuf6eednvvtf310byi0kaZ nginx.d]# touch demo.10001.conf

# 编辑内容
[root@iZuf6eednvvtf310byi0kaZ nginx.d]# vim demo.10001.conf

# 拿到前端部署根路径下的 nginx.conf 配置文件,根据实际情况替换xxx。

server {
    listen                    10001;  #设定端口号,【可修改】
    server_name               localhost; #设置当前服务名

    # root                      /data/grade-ui;  #部署地址,前端存放的地址,这里选择不甜

    # 项目A 前端项目匹配规则
    location /A {
        root                    /data/front/project; # 前端文件存放的地址【可修改】
        try_files               $uri $uri/ /index.html; # 这里要保证前端打包出来的index.html是在 root 根路径下,根据实际情况。
        index                   index.html;
         #设置某个文件不缓存读取本地,永远走200,拿到最新的,防止缓存情况
        if ($request_filename ~* .*\.(?:htm|html)$) {
            add_header        Cache-Control "private, no-store, no-cache, must-revalidate, proxy-revalidate";
        }
    }
     # 项目A 前端请求后端接口前缀 A-api,走代理
    location ^~ /A-api {
        proxy_pass            http://192.168.5.88:10002; # 代理后端接口地址,如果前、后端部署在同一台服务器上,这里可以写localhost 【可修改】
        rewrite               ^/A-api/(.*)$ /$1 break; # 这里的 $1 等于 (.*) 里的内容,break这里表示不需要在交给nginx进行location再次匹配了。【可修改】
    }


    # 项目B 前端项目匹配规则
    location /B {
        root                    /data/front/project; # 前端文件存放的地址【可修改】
        try_files               $uri $uri/ /index.html; # 这里要保证前端打包出来的index.html是在 root 根路径下,根据实际情况。
        index                   index.html;
         #设置某个文件不缓存读取本地,永远走200,拿到最新的,防止缓存情况
        if ($request_filename ~* .*\.(?:htm|html)$) {
            add_header        Cache-Control "private, no-store, no-cache, must-revalidate, proxy-revalidate";
        }
    }
    # 项目B 前端请求后端接口前缀 B-api,走代理
    location ^~ /B-api {
        proxy_pass            http://192.168.5.88:10002; # 代理后端接口地址,如果前、后端部署在同一台服务器上,这里可以写localhost 【可修改】
        rewrite               ^/B-api/(.*)$ /$1 break; # 这里的 $1 等于 (.*) 里的内容,break这里表示不需要在交给nginx进行location再次匹配了。【可修改】
    }


    # 项目C 前端项目匹配规则
    location /C {
        root                    /data/front/project; # 前端文件存放的地址【可修改】
        try_files               $uri $uri/ /index.html; # 这里要保证前端打包出来的index.html是在 root 根路径下,根据实际情况。
        index                   index.html;
         #设置某个文件不缓存读取本地,永远走200,拿到最新的,防止缓存情况
        if ($request_filename ~* .*\.(?:htm|html)$) {
            add_header        Cache-Control "private, no-store, no-cache, must-revalidate, proxy-revalidate";
        }
    }
    # 项目C 前端请求后端接口前缀 C-api,走代理
    location ^~ /C-api {
        proxy_pass            http://192.168.5.88:10002; # 代理后端接口地址,如果前、后端部署在同一台服务器上,这里可以写localhost 【可修改】
        rewrite               ^/C-api/(.*)$ /$1 break; # 这里的 $1 等于 (.*) 里的内容,break这里表示不需要在交给nginx进行location再次匹配了。【可修改】
    }

    # 项目D 前端项目匹配规则
    location /D {
        root                    /data/front/project; # 前端文件存放的地址【可修改】
        try_files               $uri $uri/ /index.html; # 这里要保证前端打包出来的index.html是在 root 根路径下,根据实际情况。
        index                   index.html;
         #设置某个文件不缓存读取本地,永远走200,拿到最新的,防止缓存情况
        if ($request_filename ~* .*\.(?:htm|html)$) {
            add_header        Cache-Control "private, no-store, no-cache, must-revalidate, proxy-revalidate";
        }
    }
    # 项目D 前端请求后端接口前缀 D-api,走代理
    location ^~ /D-api {
        proxy_pass            http://192.168.5.88:10002; # 代理后端接口地址,如果前、后端部署在同一台服务器上,这里可以写localhost 【可修改】
        rewrite               ^/D-api/(.*)$ /$1 break; # 这里的 $1 等于 (.*) 里的内容,break这里表示不需要在交给nginx进行location再次匹配了。【可修改】
    }

     # 项目E 前端项目匹配规则
    location /E {
        root                    /data/front/project; # 前端文件存放的地址【可修改】
        try_files               $uri $uri/ /index.html; # 这里要保证前端打包出来的index.html是在 root 根路径下,根据实际情况。
        index                   index.html;
         #设置某个文件不缓存读取本地,永远走200,拿到最新的,防止缓存情况
        if ($request_filename ~* .*\.(?:htm|html)$) {
            add_header        Cache-Control "private, no-store, no-cache, must-revalidate, proxy-revalidate";
        }
    }
    # 项目D 前端请求后端接口前缀 E-api,走代理
    location ^~ /E-api {
        proxy_pass            http://192.168.5.88:10002; # 代理后端接口地址,如果前、后端部署在同一台服务器上,这里可以写localhost 【可修改】
        rewrite               ^/E-api/(.*)$ /$1 break; # 这里的 $1 等于 (.*) 里的内容,break这里表示不需要在交给nginx进行location再次匹配了。【可修改】
    }

}

# wq保存


# 重新启动nginx,让nginx重新读取配置
[root@iZuf6eednvvtf310byi0kaZ nginx.d]# nginx -s reload
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
上次更新: 2022/12/30, 23:48:21
指南者留学nginx配置

指南者留学nginx配置→

Theme by Vdoing | Copyright © 2022-2025 bianpengfei
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×