关于「
如何将⼀个前后端分离的开源项⽬部署到⾃⼰的服务器上
」这个话题很早之前我就想做了。
⼀来是因为有很多初学的⼩伙伴们反馈说需要;⽽且经常也听到⼀部分⼩伙伴反馈说⾃⼰的云服务器买
了不知道⼲啥,有什么办法可以玩起来,等等之类的话题。
我还是先把本⽂的实验流程写在前⾯,并且画了个思维导图,这样好知道后⾯每⼀步在⼲嘛。
然后我们接下来⼀项项安排即可
环境交代
部署离不开服务器节点、
Linux
系统和⼀系列软件环境以及基础设施,这个在之前就已经出过⽂章、⽂档
以及视频聊过了,具体可以参看该系列⽂章:
服务器软件⼤科普
⼈⼿⼀套
Linux
环境搭建之:
macOS
版本教程
⼈⼿⼀套
Linux
环境搭建之:
Windows
版本教程
这些是本⽂实战的前提。
本实验投⼊了三台
Linux
主机节点,安排如下:
项⽬地址:
https://gitee.com/y_project/RuoYi-Vue
。
直接⽤
Git
命令下载到本地某个⽬录下即可。
下载完成的代码⽬录⾥包含两个⼦⽬录,分别为
前端项⽬
⽬录和
后端项⽬
⽬录。
我这⾥在本地宿主机和三个
Linux
节点上都各下载了⼀份项⽬源码,路径分别为:
本地代码:
/Users/codesheep/IdeaProjects/RuoYi-Vue
节点
1
代码路径:
/root/workspace/RuoYi-Vue
节点
2
代码路径:
/root/workspace/RuoYi-Vue
节点
3
代码路径:
/root/workspace/RuoYi-Vue
本地代码是为了稍后导⼊
IDEA
中⽅便运⾏、调试和代码阅读及修改,
Linux
系统节点上的三份代码待
会直接打包部署使⽤。
git
clone https://gitee.com/y_project/RuoYi-Vue
⼀个开源项⽬从⽹上下载之后,想直接⽴⻢就能完美运⾏起来不太现实,毕竟还有很多东⻄要根据⾃⼰
的实际情况进⾏配置,⽐如数据库、缓存、⽇志路径等等,都需要根据⾃⼰实际情况修改。
所以我们接下来⼀⼀配置。
1
、建库
⾸先我们需要新建⼀个名为
ry-vue
的数据库,出于演示考虑,这⾥直接通过软件
Navicat
可视化创
建:
2
、建表
在上述新建的
ry-vue
的数据库⾥导⼊位于路径
/Users/codesheep/IdeaProjects/RuoYi
Vue/ruoyi/sql
下的两个
.sql
⽂件:
ry_20200415.sql
quartz.sql
3
、修改
yml
中数据库连接配置
修改路径
/Users/codesheep/IdeaProjects/RuoYi-Vue/ruoyi/src/main/resources
下的
application-druid.yml
配置⽂件,修改其中的数据库
url
、
username
、
password
等字段为你
实际的数据库链接
修改缓存配置
由于该项⽬使⽤了
Redis
缓存,因此和上⾯的
MySQL
数据库⼀样需要根据实际情况配置。
修改路径
/Users/codesheep/IdeaProjects/RuoYi-Vue/ruoyi/src/main/resources
下的
application.yml
配置⽂件,修改其中
Redis
缓存的
host
、
password
等字段为你实际的
Redis
链
接:
修改⽇志配置
修改⽇志路径
修改路径
/Users/codesheep/IdeaProjects/RuoYi-Vue/ruoyi/src/main/resources
下的
logback.xml
配置⽂件,⾸先修改其中的⽇志存放路径为⾃⼰定义的路径
修改字符集
另外则是在每⼀对
<encoder></encoder>
中加上
UTF-8
的
字符集⽀持,避免后续服务器上看⽇志时
可能出现乱码的现象
本地运⾏
打开
IntelliJ IDEA
,直接打开本地代码⽬录
RuoYi-Vue
中的
ruoyi
⽂件夹即可:
第⼀次导⼊,会⾃动下载项⽬
pom.xml
中各种所需的依赖,所以需要等待⼀段时间。
导⼊成功后,直接点击启动按钮,查看启动效果
项⽬运⾏成功,这样后续就可以对其进⾏调试和代码的研读了。
项⽬打包
前端项⽬打包
我们准备将前端项⽬部署到
Linux
节点
1
上,所以进⼊
Linux
节点
1
的代码⽬录:
准备进⾏前端项⽬的打包操作。
1
、安装依赖
进⼊前端项⽬⼦⽬录
ruoyi-ui
,运⾏如下命令安装前端项⽬所需依赖:
2
、构建打包
因为我们要部署,所以这⾥直接打包正式环境即可:
/root/workspace/RuoYi-Vue/ruoyi-ui
npm
install
--unsafe-perm --registry
=
https://registry.npm.taobao.org
2
、构建打包
因为我们要部署,所以这⾥直接打包正式环境即可:
/root/workspace/RuoYi-Vue/ruoyi-ui
npm
install
--unsafe-perm --registry
=
https://registry.npm.taobao.org
npm
run build:prod
构建打包成功之后,会在根⽬录⽣成 dist ⽂件夹,⾥⾯就是构建打包好的前端项⽬⽂件:
该 dist ⽬录先留着,后⾯部署前端项⽬时,直接拿来使⽤。
后端项⽬打包
我们准备将后端项⽬部署到
Linux
节点
2
和
节点
3
,以
节点
2
为例,进⼊代码⽬录:
准备进⾏后端项⽬的打包操作。
打
jar
包
Spring Boot
由于⾃带
Tomcat
应⽤服务器,项⽬默认会打出可执⾏的
jar
包,⾮常⽅便。
直接在当前⽬录下执⾏
mvn package
命令即可构建打包:
该过程会延续⼀段时间,它会⾃动下载项⽬ pom.xml 中各种所需的依赖,并最终构建打包。
构建成功如图所示,并且会在当前路径下⽣成⼀个 target ⽂件夹:
进⼊ target ⽂件夹,构建并打包出来可执⾏ jar 包即位于其中,⼤⼩约六⼗⼏兆:
打
war
包
上⾯说了,
Spring Boot
由于默认内嵌
Tomcat
容器,所以打出来的
jar
包即可直接运⾏,但是我们
有时候希望将其部署于外置的
Tomcat
服务器中,这时候就要打
war
包了。
打
war
包之前需要做⼏个代码上的配置:
1
、修改
pom.xml
中的打包⽅式
修改
/root/workspace/RuoYi-Vue/ruoyi/pom.xml
⽂件,将:
修改为:
2
、剔除内嵌的
Tomcat
我们只需要将
Spring Boot
内置的
Tomcat
在发布时去除即可。
修改
/root/workspace/RuoYi-Vue/ruoyi/pom.xml
⽂件,在原先的配置:
下⾯加⼊如下配置即可:
<packaging>
jar
</packaging>
<packaging>
war
</packaging>
<dependency>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter-web
</artifactId>
</dependency>
本文档在 Github开源项目:https://github.com/hansonwang99/JavaCollection 中已收录,
有详细自学编程学习路线、面试题和面经、编程资料及系列技术文章等,资源持续更新中...
<dependency>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter-tomcat
</artifactId>
<scope>
provided
</scope>
</dependency>
provided
表示该包只在编译和测试中使⽤,在发布时去除。
3
、修改项⽬启动类
在
Spring Boot
中我们平常都⽤
main
⽅法启动的⽅式,都有⼀个
SpringBootApplication
的启动
类,⽐如本项⽬的启动主类⽂件:
/Users/codesheep/IdeaProjects/RuoYi
Vue/ruoyi/src/main/java/com/ruoyi/RuoYiApplication.java
⽽我们现在需要类似于
web.xml
的配置⽅式来启动
Spring
应⽤,为此,我们在
Application
类的同
级⽬录下再添加⼀个
SpringBootStartApplication
类:
其代码如下:
4、执⾏打包操作
切换到后台项⽬⽬录下:
/root/workspace/RuoYi-Vue/ruoyi
⾸先执⾏:
mvn clean
清理之前的打包结果:
然后再次执⾏ mvn package 命令即可构建打war包了,打包结果仍然位于⽣成的 target ⽬录下:
前端项⽬部署
上⽂刚刚阐述过前端项⽬的打包过程,是在
Linux
节点
1
上进⾏的,打包好的前端项⽬成品位于
dist
⽬录,具体路径为:
前端项⽬的部署⾮常简单,我们只需要将
dist
⽬录发布到你提前安装部署好的的
Web
服务器静态⽬录
即可。
我们这⾥选⽤的是
Nginx
这款⾼性能
Web
服务器,接下来我们简单配置下
Nginx
,并重启⽣效。
关于
Nginx
等基础设施和软件的安装部署过程,之前已经专⻔写过
PDF
了,可参考前⽂:
熬
10
天
夜,肝出了这个
PDF
版「软件安装⼿册」
我的
Nginx
安装于如下⽬录:
其配置⽂件位于⽬录:
简要配置
nginx.conf
⽂件如下所示:
/root/workspace/RuoYi-Vue/ruoyi-ui/dist
/usr/local/nginx
/usr/local/nginx/conf/nginx.conf
简要配置
nginx.conf
⽂件如下所示
{
user root;
worker_processes
1
;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections
1024
;
}
http {
include mime.types;
default_type application/octet-stream;
#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 on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout
65
;
#gzip on;
server {
listen
80
;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root /root/workspace/RuoYi-Vue/ruoyi-ui/dist;
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;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on
127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME
/scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
# another virtual host using mix of IP-, name-, and port-based
configuration
#
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm;
# }
#}
# HTTPS server
#
#server {
# listen 443 ssl;
# server_name localhost;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.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;
# }
#}
}
此处对原始
nginx.conf
⽂件只做了两处改动:
1
、配置
user root
2
、配置
location /
location / {
root /root/workspace/RuoYi-Vue/ruoyi-ui/dist;
index index.html index.htm;
}
⽬的很简单,⼀眼就能看明⽩。
接下来执⾏如下命令重新加载
Nginx
即可⽣效:
/usr/local/nginx/sbin/nginx
-s
reload
然后打开浏览器,输⼊
节点
1
的
IP
:
192.168.31.100
即可访问⽹站前端⻚⾯:
⾄此前端部署结束,接下来进⾏后端项⽬的部署
后端项⽬部署
JAR
包部署⽅式
jar
包部署⽅式⾮常简单,⼏乎只需要⼀⾏命令即可搞定,因为
Spring Boot
内嵌
Tomcat
,开箱即
⽤的感觉真的很爽。
上⽂阐述过后端项⽬的打
jar
包的过程,是在
Linux
节点
2
上进⾏的,打包好的后端项⽬
jar
包成品
位于
target
⽬录,具体路径为:
我们只需要进⼊
target
⽬录中执⾏如下命令即可在后台部署项⽬:
WAR
包部署⽅式
war
包部署⽅式就需要额外安装
Tomcat
应⽤服务器,我这⾥的
Tomcat
安装于如下⽬录:
/root/workspace/RuoYi-Vue/ruoyi/target/ruoyi.jar
nohup java
-jar
ruoyi.jar &
WAR
包部署⽅式
war
包部署⽅式就需要额外安装
Tomcat
应⽤服务器,我这⾥的
Tomcat
安装于如下⽬录:
/usr/local/tomcat/apache-tomcat-8.5.55
war
包的部署⽅式也⾮常简单,我们只需要将上⽂后端项⽬打包好的
war
包直接放⼊
Tomcat
的
webapps
⽬录即可。
上⽂阐述过后端项⽬的打
war
包的过程,是在
Linux
节点
2
上进⾏的,打包好的后端项⽬
war
包成品
位于
target
⽬录,具体路径为:
/root/workspace/RuoYi-Vue/ruoyi/target/ruoyi.war
这⾥我们直接使⽤
cp
命令拷⻉⼀份到
Tomcat
的
webapps
⽬录⾥即可:
cp
/root/workspace/RuoYi-Vue/ruoyi/target/ruoyi.war
/usr/local/tomcat/apache-tomcat-8.5.55/webapps/
这时候后端理论上就部署完毕,可以访问了,只不过现在还需要加
项⽬名
进⾏访问,就像这样:
http://192.168.31.101:8080/ruoyi/
很明显这样有点不⽅便。
所以我们接下来设置去掉项⽬名,直接根⽬录访问。
我们只需要修改⼀下
Tomcat
的配置⽂件
server.xml
:
/usr/local/tomcat/apache-tomcat-8.5.55/conf/server.xml
在其
<Host>
标签下⾯加⼊如下内容即可:
<Context path="/" docBase="/usr/local/tomcat/apache-tomcat-
8.5.55/webapps/ruoyi" reloadable="false"></Context>
最后重启 Tomcat 即可⽣效:
service
tomcat
stop
service
tomcat
start
配置
NGINX
代理和转发
接下来我们继续配置
节点
1
上的
Nginx
,在其配置⽂件中加上如下配置:
location /prod-api/{
proxy_set_header Host
$http_host
;
proxy_set_header X-Real-IP
$remote_addr
;
proxy_set_header REMOTE-HOST
$remote_addr
;
proxy_set_header X-Forwarded-For
$proxy_add_x_forwarded_for
;
proxy_pass http://192.168.31.101:8080/;
}
可以看出来,我们的⽬的是想将所有发往
节点
1
上的
/prod-api/
请求,全部转发到
节点
2
上部署的后端
项⽬⾥。
⾄于为什么这⾥配基础转发路径
/prod-api/
,这个需要看⼀下前端项⽬根⽬录⾥的隐藏⽂
件
.env.production
就明⽩了:
其内容如下:
#
⽣产环境配置
ENV
=
'production'
#
⽣产环境
VUE_APP_BASE_API
=
'/prod-api'
这就是需要设置的
基础转发路径
。
然后接下来执⾏如下命令重新加载
Nginx
即可⽣效:
/usr/local/nginx/sbin/nginx
-s
reload
然后打开浏览器,访问
节点
1
的
IP
:
192.168.31.100
,即可正常登录,进⼊项⽬的后台系统:
⾄此所有的部署全部结束!
后台项⽬多实例部署
对于上⾯的部署,我们对后台项⽬只部署了⼀个运⾏实例,位于
节点
2
上。
但实际情况我们处于提升性能或稳定性等考虑,我们希望对后台项⽬在多个节点上
部署多实例
,所以接
下来简要演示⼀下。
正好我们还准备了⼀个
节点
3
机器,重复上⽂的后端项⽬部署过程,在
节点
3
上也将后端项⽬给同样地运
⾏起来。
然后我们继续配置
节点
1
上的
Nginx
,在其配置⽂件中做如下配置:
upstream ruoyi{
server 192.168.31.101:8080 weight=5;
server 192.168.31.102:8080 weight=3;
}
server {
# ...
省略
...
location /prod-api/{
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For
$proxy_add_x_forwarded_for;
proxy_pass http://ruoyi/;
}
# ...
省略
...
}
⾸先我们配置了⼀个名为
ruoyi
的服务器集群地址,其包含两个实例(分别对应
节点
2
和
节点
3
),并
且分配了不同的权重
weight
(理论上来说权重
weight
越⼤,对应
Tomcat
上分配到的请求也会越
多)
.
同时将
location /prod-api/
⾥的代理转发路径指向了
ruoyi
多实例集群,这样当我们访问前端
时,
Nginx
会⾃动将我们的请求转发到两个实例中的任何⼀个中去处理。
这样即使后端实例
down掉⼀个,还有其他实例可以⽀撑系统的运⾏,稳定性和性能均要更⾼⼀些。
由于个⼈精⼒和能⼒有限,难免会有疏漏和不当的地⽅,还希望多多谅解。