# 前后端分离项目服务器部署
## Into
学习若依前后端分离项目,进行二次开发,同时部署的经验,并进行简单的总结记录。特别说明: 学习使用的若依项目为前后端分离版,版本为2021年的3.7.0。开展部署前提条件:至少拥有2台服务器(如若采用多节点部署,可采用3台服务器, 一台部署前端,二台部署后端)基本的开发工具包括不限于Xshell、Xftp、RedisDeskopManager(RDM)
IDEA、Navicat、Webstorm等。同时需要配置好服务器的开发环境:JDK、Maven、MySQL、Redis、Node、Nginx、Tomcat、Git等。并确保服务器的防火墙的相应端口开放。
### 实际配置
Linux服务器的配置,作为学生党使用而言,一般采用虚拟机配置出多台Linux服务器。这样配置要确保多台服务器都能项目访问,并且可以访问外网和宿主机。其好处就是可以随意配置,随意折腾,只要宿主机的性能足够好,随便配置几台Linux服务器 。开箱即用。就算“玩坏了”,大不了重新配置。但是俺的本机电脑性能属实拉胯, 风扇开足马力,电脑也是铁铁的小火炉。(小米电脑,为供暖而生。东北的供暖公司见到都要汗颜。),没办法在虚拟机配置2-3台的Linux服务器。因此,趁活动期间租用阿里云的云服务器,作为部署试用。一般双十一活动期间,加上学生优惠,买服务器比较便宜。使用云服务器,一定配置好安全组,授权访问,开放指定端口,必要时采用秘钥对的方式登录到云服务器实例。关于阿里云的云服务器的使用,参考阿里云的官方文档比较好,非常详细。
关键说明:
阿里云的服务器的安全组配置
![image-20211203143310827](https://mybolg-typora.oss-cn-beijing.aliyuncs.com/%20blogPic/202112031433555.png)
使用秘钥对登录 (前提绑定)
![image-20211203143839779](https://mybolg-typora.oss-cn-beijing.aliyuncs.com/%20blogPic/202112051305410.png)
使用Xshell登录
![image-20211203214340142](https://mybolg-typora.oss-cn-beijing.aliyuncs.com/%20blogPic/202112032143251.png)
## 上传
分别在两台服务器下(前端部署在阿里云-杭州服务器,后端在部署在阿里云-张家口服务器,MySQL采用阿里云数据库RDS,Redis同时部署在后端服务器),创建 `/root/workspace/` 目录
```
mkdir /root/worksapce/
cd /root/worksapce/
```
分别将本地的项目进行zip打包(也可在Gitee仓库获得zip包文件),获得Ruoyi-admin-master.zip 、Ruoyi-vue-master.zip。
使用Xftp将项目包传输到`/root/workspace/`目录下,同时进行解压。
```
unzip Ruoyi-admin-master.zip
unzip Ruoyi-vue-master.zip
```
分别使用`ll`命令进行查看,获得相应的目录,并删除zip包。
```
rm -rf Ruoyi-admin-master.zip
rm -rf Ruoyi-vue-master.zip
```
## 后端打包构建部署(以jar包为例)
进入Ruoyi-admin-master目录下
```shell
[root@iZ8vb6brzzk9znc58563cdZ workspace]# pwd
/root/workspace
[root@iZ8vb6brzzk9znc58563cdZ workspace]# ll
total 78192
drwxr-xr-x 11 root root 256 Nov 3 12:17 Ruoyi-admin-master
[root@iZ8vb6brzzk9znc58563cdZ workspace]# cd Ruoyi-admin-master
[root@iZ8vb6brzzk9znc58563cdZ Ruoyi-admin-master]#
```
构建
```shell
[root@iZ8vb6brzzk9znc58563cdZ Ruoyi-admin-master]# mvn package
-bash: mvn: command not found
[root@iZ8vb6brzzk9znc58563cdZ Ruoyi-admin-master]# mvn -v
-bash: mvn: command not found
[root@iZ8vb6brzzk9znc58563cdZ Ruoyi-admin-master]# source /etc/profile
[root@iZ8vb6brzzk9znc58563cdZ Ruoyi-admin-master]# mvn -v
Apache Maven 3.8.4 (9b656c72d54e5bacbed989b64718c159fe39b537)
Maven home: /usr/local/maven/apache-maven-3.8.4
Java version: 1.8.0_311, vendor: Oracle Corporation, runtime: /usr/local/java/jdk1.8.0_311/jre
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "4.18.0-305.19.1.el8_4.x86_64", arch: "amd64", family: "unix"
[root@iZ8vb6brzzk9znc58563cdZ Ruoyi-admin-master]# mvn package
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Build Order:
[INFO]
[INFO] ruoyi [pom]
[INFO] ruoyi-common [jar]
[INFO] ruoyi-system [jar]
[INFO] ruoyi-framework [jar]
[INFO] ruoyi-quartz [jar]
[INFO] ruoyi-generator [jar]
[INFO] ruoyi-admin [jar]
[INFO]
[INFO] --------------------------< com.ruoyi:ruoyi >---------------------------
[INFO] Building ruoyi 3.7.0 [1/7]
[INFO] --------------------------------[ pom ]---------------------------------
.......
.......
.......
[INFO] Reactor Summary for ruoyi 3.7.0:
[INFO]
[INFO] ruoyi .............................................. SUCCESS [ 0.002 s]
[INFO] ruoyi-common ....................................... SUCCESS [ 1.967 s]
[INFO] ruoyi-system ....................................... SUCCESS [ 0.191 s]
[INFO] ruoyi-framework .................................... SUCCESS [ 0.307 s]
[INFO] ruoyi-quartz ....................................... SUCCESS [ 0.092 s]
[INFO] ruoyi-generator .................................... SUCCESS [ 0.106 s]
[INFO] ruoyi-admin ........................................ SUCCESS [ 0.893 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
# PS 这里为了演示,重新打包构建
```
这里特别说明一下,在分离项目多模块的版本中,打包后的jar包放在`ruoyi-admin/target/`路径下。因为每次打包,jar包都会被重新写入,原由的jar包不存在。所以每次打完包后,需要将jar包备份。我的备份在`/root/workspace/`目录下。
部署
建议初次使用`java -jar XXX.jar`方式,可以直接看到日志信息。
```shell
java -jar ruoyi-admin.jar
```
出现佛祖保佑头像及Ruoyi的打印信息,表示部署成功。
![image-20211204110651503](https://mybolg-typora.oss-cn-beijing.aliyuncs.com/%20blogPic/202112041107497.png)
同时,第二次部署可采用`nohup java -jar ruoyi-admin.jar &`的方式部署。后台默默运行,并将打印信息输出到nohup.out文件。如下
```
[root@iZ8vb6brzzk9znc58563cdZ ~]# pwd
/root
[root@iZ8vb6brzzk9znc58563cdZ ~]# cd workspace
[root@iZ8vb6brzzk9znc58563cdZ workspace]# ll
total 78192
-rw------- 1 root root 19901 Nov 3 12:03 nohup.out
-rw-r--r-- 1 root root 80044598 Nov 3 12:28 ruoyi-admin.jar
drwxr-xr-x 11 root root 256 Nov 3 12:17 Ruoyi-admin-master
```
## 后端打包构建部署(以Nginx为例)
只需要运行一行命令就可以打包应用
```NPM
# 打包正式环境
npm run build:prod
```
构建打包成功之后,会在根目录生成 `dist` 文件夹,里面就是构建打包好的文件,通常是 `***.js` 、`***.css`、`index.html` 等静态文件。如下所示。
```shell
[root@iZbp14au3oyt7wawokbvrfZ ~]# pwd
/root
[root@iZbp14au3oyt7wawokbvrfZ ~]# ll
total 28
-rw-r--r-- 1 root root 24849 Nov 18 16:59 install.sh
drwxr-xr-x 3 root root 30 Nov 2 20:32 workspace
[root@iZbp14au3oyt7wawokbvrfZ ~]# cd workspace
[root@iZbp14au3oyt7wawokbvrfZ workspace]# ll
total 4
drwxr-xr-x 8 root root 4096 Nov 2 20:43 Ruoyi-vue-master
[root@iZbp14au3oyt7wawokbvrfZ workspace]# cd Ruoyi-vue-master
[root@iZbp14au3oyt7wawokbvrfZ Ruoyi-vue-master]# ll
total 604
-rw-r--r-- 1 root root 463 Nov 2 20:03 babel.config.js
drwxr-xr-x 2 root root 61 Nov 2 20:03 bin
drwxr-xr-x 2 root root 22 Nov 2 20:03 build
drwxr-xr-x 4 root root 87 Nov 2 20:43 dist
drwxr-xr-x 919 root root 28672 Nov 2 20:42 node_modules
-rw-r--r-- 1 root root 2169 Nov 2 20:03 package.json
-rw-r--r-- 1 root root 549639 Nov 2 20:38 package-lock.json
drwxr-xr-x 3 root root 73 Nov 2 20:03 public
-rw-r--r-- 1 root root 573 Nov 2 20:03 README.md
drwxr-xr-x 12 root root 218 Nov 2 20:03 src
-rw-r--r-- 1 root root 4206 Nov 2 20:03 vue.config.js
[root@iZbp14au3oyt7wawokbvrfZ Ruoyi-vue-master]# cd dist
[root@iZbp14au3oyt7wawokbvrfZ dist]# ll
total 28
-rw-r--r-- 1 root root 5663 Nov 2 20:43 favicon.ico
drwxr-xr-x 2 root root 21 Nov 2 20:43 html
-rw-r--r-- 1 root root 12911 Nov 2 20:43 index.html
-rw-r--r-- 1 root root 25 Nov 2 20:43 robots.txt
drwxr-xr-x 6 root root 51 Nov 2 20:43 static
[root@iZbp14au3oyt7wawokbvrfZ dist]# ll static
total 8
drwxr-xr-x 2 root root 4096 Nov 2 20:43 css
drwxr-xr-x 2 root root 75 Nov 2 20:43 fonts
drwxr-xr-x 2 root root 225 Nov 2 20:43 img
drwxr-xr-x 2 root root 4096 Nov 2 20:43 js
```
通常情况下 `dist` 文件夹的静态文件发布到 Nginx 或者静态服务器即可(这里只介绍Nginx),其中的 `index.html` 是后台服务的入口页面。
接下来进行Nginx配置。
```shell
# 编辑nginx配置文件
vim /usr/local/nginx/conf/nginx.conf
```
修改配置如下
```sh
# 设置 root用户,初次部署。直接使用root权限最高用户
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;
# 设置根路径位置,并设置路由。try_files的作用类似重定向
location / {
root /root/workspace/Ruoyi-vue-master/dist;
try_files $uri $uri/ /index.html;
index index.html index.htm;
}
#转发
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://8.142.164.160:8080/;
}
#error_page 404 /404.html;
```
重新加载 Nginx
```
/usr/local/nginx/sbin/nginx -s reload
```
## 部署成功
输入前端的地址,测试访问。
![image-20211204110306107](https://mybolg-typora.oss-cn-beijing.aliyuncs.com/%20blogPic/202112041107017.png)
![image-20211204110314011](https://mybolg-typora.oss-cn-beijing.aliyuncs.com/%20blogPic/202112041108912.png)
到此就算部署成功。但是其中有一些细节没有提及,如云服务器的安全组的设置,Redis的配置与管理,数据库的配置与使用。当然还可以有更多补充的,后端采用War包部署,采用多节点部署,负载均衡,或采用docker容器部署等。
## 拓展
### war包部署
如若采用war包部署,那么需要修改`ruoyi-admin`模块下的pom.xml文件,更改打包方式,修改如下
```
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>
<artifactId>ruoyi-admin</artifactId>
```
修改为
```
<modelVersion>4.0.0</modelVersion>
<packaging>war</packaging>
<artifactId>ruoyi-admin</artifactId>
```
同时需要剔除SprinngBoot内置Tomcat,修改如下
```xml
<!-- 多模块排除内置tomcat -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 单应用排除内置tomcat 1 -->
<exclusions>
<exclusion>
<artifactId>spring-boot-starter-tomcat</artifactId>
<groupId>org.springframework.boot</groupId>
</exclusion>
</exclusions>
<!-- 单应用排除内置tomcat 2 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
```
同时新建启动项,`ruoyi-admin/src/main/java/com/ruoyi` 下的`SpringBootStartApplication`类
```java
package com.ruoyi;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
public class SpringBootStartApplication extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
// 指向原启动类
return builder.sources(RuoYiApplication.class);
}
}
```
与此同时,进行Tomcat配置。修改server.xml,Host节点下添加
```xml
<Context path="/" docBase="/root/apache-tomcat-8.5.56/webapps/ruoyi" reloadable="false"></Context>
```
并在前端打包生成的dist目录的文件夹下新建WEB-INF文件夹,并在里面添加web.xml文件。
```xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1" metadata-complete="true">
<display-name>Router for Tomcat</display-name>
<error-page>
<error-code>404</error-code>
<location>/index.html</location>
</error-page>
</web-app>
```
修改完毕后,进行打包,并放入到服务器里的Tomcat中
```
mvn package
```
### 多节点部署
如果采用多节点部署,那么至少要再准备一台服务器。同理,再次把后端部署到另外一台服务器,打包构建部署过程一样。只需要修改在前端的Nginx的配置。
```shell
vim /usr/local/nginx/conf/nginx.conf
```
修改配置如下:
```
# 设置 root用户,初次部署。直接使用root权限最高用户
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;
#轮询并配置权重 如权重设置分别为5,3
upstream ruoyi{
server 8.142.164.160:8080 weight=5;
server 8.142.164.134: 8080 weight=3;
}
#gzip on;
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
# 设置根路径位置,并设置路由。try_files的作用类似重定向
location / {
root /root/workspace/Ruoyi-vue-master/dist;
try_files $uri $uri/ /index.html;
index index.html index.htm;
}
#转发
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/;
}
#error_page 404 /404.html;
```
其中要添加轮询
```
#轮询并配置权重 如权重设置分别为5,3
upstream ruoyi{
server 8.142.164.160:8080 weight=5;
server 8.142.164.134: 8080 weight=3;
}
```
`proxy_pass` 的配置修改为 `http://ruoyi/`
最后重新加载Nginx
```
/usr/local/nginx/sbin/nginx -s reload
```
到此,简单的多节点部署就是实现完成,算是简单实现了一下负载均衡。
Ruoyi前后端分离项目服务器部署