Linux Nginx部署前后端分离的Java Web项目(Vue+Springboot)
系统(CentOS 8)环境准备工作:
- Java JDK的安装和配置(Java 8)
- Nginx的安装与配置
- MySQL的安装与配置、项目数据库的建立
测试找的一个项目demo地址:https://gitee.com/xqnode/springboot-vue-demo
一、项目分析
部署到Linux服务器之前需要明确该项目的运作模式。这里选取的前后端分离项目基于Vue+Springboot开发,前端与后端所有交互请求的url都是以/api
开头,以区分其他请求的url。前端端口为9876,后端端口为9090,在前端项目打包之前,项目通过前端的vue.config.js文件进行url重写暂时解决了跨域(主要是跨端口)问题,如下:
// 跨域配置
module.exports = {
devServer: { //记住,别写错了devServer
port: 9876, //设置本地默认端口
proxy: { //设置代理,必须填
'/api': { //设置拦截器 拦截器格式=>斜杠+拦截器名字,名字可以自己定
target: 'http://localhost:9090', //代理的目标地址
changeOrigin: true, //是否设置同源,输入是的
pathRewrite: { //路径重写
'/api': '' //选择忽略拦截器里面的单词
}
}
}
}
}
开发环境下(前端DevServer)没有问题。当通过npm run build
执行前端打包脚本形成一个前端项目(dist目录),这个配置失去其作用,需要通过Nginx的配置重写url来解决跨端口问题。
二、项目准备
将前端项目打包形成dist目录,归档成.tar文件,传入Linux虚拟机再还原,移动到/usr/local/nginx/html目录下。将后端项目打成jar包(包括项目及其依赖在内的一系列jar包),通过相同方法移动到/usr/src目录下。这里的目录并不要求一定是这两个,后期配置可以随之改动。重命名两个项目为vue、vuedemo方便查找。
三、Nginx配置
通过vim /usr/local/nginx/conf/nginx.conf
编辑Web服务器Nginx的配置文件进行配置。主要分为以下两部分配置:
1、前端资源请求
当访问http://localhost:9876/时需要出现项目的主界面,即打包后的index.html。找到http {…}节点,编辑server {…}节点以及当中的location / {…}节点如下:
server {
listen 9876; # 监听前端的端口
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
# root 指定前端资源的根目录
root html/vue;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
#...省略一些被注释掉的配置
location /nginx_status {
stub_status on;
access_log off;
}
}
重启nginx或者通过nginx -s reload
命令使修改后的配置生效。
2、前后端跨端口通信问题的解决。
没有了上面关于跨域的配置,前端所有与后端通信发出的请求都是以http://localhost:9876/开头,因此出现跨域问题。
后端基于Springboot(内嵌tomcat)因此无需另起tomcat容器,可以直接通过java -jar xxxx.jar(项目本身形成的那个jar包)
运行起来。所有的前后端通信请求的url都是http://localhost:9876/api/xxxxxx,因此可以在Nginx中配置处理/api为前缀的路径,类似于于拦截器。
可以先在http节点中(server节点外)添加上游服务器upstream节点,这个节点一般用于反向代理,这里在upstream节点中只添加一个server表示只代理一个服务器(tomcat-1及其9090端口),之后如果想反向代理多个服务器部署的同一个后端,可以往同一个upstream节点中添加多个不同的server地址(如下面tomcatserver节点的tomcat-2。weight是轮询的权重),当然通过添加不同的upstream节点还可以实现代理不同的后端(个人见解)。
# reverse proxy
upstream tomcatserver {
server localhost:9090 weight=10; # tomcat-1
# server localhost:9091 weight=10; # tomcat-2
}
在nginx.conf的server节点中添加location节点如下:
# 所有与后端交互的url都携带api作为标志,因此可以监听api
location /api {
# 重写url,通过正则取url当中的/api/之后的部分与proxy_pass组成新的url
rewrite ^/api/(.*)$ /$1 break;
# proxy_pass 用于配置访问这个location时所用代理
proxy_pass http://tomcatserver; # proxy name of a group of upstream servers
# proxy_pass http://localhost:9090$request_uri; =>有问题
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-Ip $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
有的人由于前后端分离时url约定的不同选择了下面那一行的proxy_pass配置,首先有问题的是这样写nginx会报localhost不认识的错产生502(查看nginx安装目录下的logs/error.log文件可看到nginx的错误日志,如图),需要使用resolver。通过代理上游服务器upstream不会有这个麻烦。
然后是$request_uri
,这个变量指代的是proxy_pass之后的全部的url,如一个url为http://localhost:9876/api/user/233,proxy_pass用于替代localhost:9876这个部分,request_uri
指的是/api/usr/233这一部分。因此没有去除/api
的url是找不到后端对应controller的,nginx不会生成错误日志,服务器返回的是404的错误。
配置完成后,生效新的配置。进入后端jar包所在目录,启动后端程序
然后在浏览器中访问http://localhost:9876/得到主界面
登录后得到相应的界面如下。