Skip to content

2084team/2084team-vhr

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

2084team OA系统的部署

这里主要讲怎么部署项目,分布式部署,具体细节全在我们团队的仓库代码中

原项目地址

团队git仓库

界面精美,代码优美,系统并不复杂,适合初学者

可以前后端分离,也可以不分离

技术栈

前置知识:Spring Boot,Spring Security,MySQL,MyBatis,Redis

进阶知识:RabbitMQ,Spring Cache,WebSocket

前端:Vue,ElementUI,Axios,Vue-Router,WebSocket,Vue-Cli4

环境

这里是在单个机器上:Windows本地或者一台服务器上体验效果

  • 打开MySQL,创建空数据库vhr

  • 打开Redis

  • 打开Nginx

  • 安装rabbitmq,全部都用最新版本

  • 保证所有环境配置好,IDEA打开后端工程/vhr,WebStorm打开前端工程/vuehr

  • 注意:不要前后端目录一起打开,IDEA会识别不出springboot项目

代码

第一步:修改application.properties/application.yml中的MySQL,Redis,RabbitMQ配置

第二步:大体浏览代码,可见代码非常工整,是分布式分模块开发

第三步:启动mailserver模块,然后启动webserver模块

作者对于这个项目的总结与展望

我对于这个项目的态度:

代码清楚,易于集成,适合技术点的学习,可以融合其他的api

部署

用Docker部署

用docker部署,这样能便捷一些,省去很多不必要的麻烦

不会使用Docker命令的同学可以用Kitematic客户端或者Rancher客户端来管理容器

六个服务:前端,mailserver,vhr-web,MySQL,Redis,RabbitMQ

  • 前端:vuehr-8180

  • 后端:mailserver-8181

  • 后端:webserver-8182

  • 数据库:MySQL-3306 33060

  • 缓存:Redis-6379

  • 消息队列:RabbitMQ-5672 15672 25672 1883 61613

部署事项

  • 服务器要打开所有的服务端口

  • 因为都是容器内部的,所以要外网IP+外部端口号

  • 安装MySQL

    docker run --name sql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=2084team -dit --network host mysql:latest --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci

    数据库建空库vhr即可,注意数据库可以本地挂载数据

    通过一种MySQL客户端连接mysql,直接使用IDEA自带的插件就可以,注意调整时区Asia/Shanghai,连接通畅才能在代码中连接

  • 安装RabbitMQ,rabbitmq客户端:Docker方式

    docker run -dit --hostname vhr-rabbitmq --name vhr-rabbitmq -e RABBITMQ_DEFAULT_USER=2084team -e RABBITMQ_DEFAULT_PASS=2084team -p 5672:5672 -p 15672:15672 -p 25672:25672 -p 1883:1883 -p 61613:61613 --network host rabbitmq:3-management

    通过web访问客户端(ip:15672),连接通畅才能在代码中连接,否则调试

  • 安装Redis:Docker方式

    docker run --name vhr-redis -dit -p 6379:6379 --network host redis

    通过一种Redis客户端连接Redis,推荐使用这个,连接通畅才能在代码中连接

后端服务

本地构建包,将镜像推送到远程的服务器

IDEA连接Linux主机的Docker

  • IDEA远程连接Docker,推送镜像,用此方式来推送后端服务镜像,比较便捷

    vim /usr/lib/systemd/system/docker.service

    修改配置

    • 原配置: -H fd:// --containerd=/run/containerd/containerd.sock

    • 现配置: -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock

    配置文件修改好,保证后端一定可以连接上MySQL,Redis,RabbitMQ,就像我刚才说的,客户端或者web端连接成功才能在代码中连接,否则别说项目跑不起来,打包都不一定成功!

  • 编写Dockfile文件,放在能打包成为jar包的位置,本项目放置在mailservervhr-web各一个

打包方法

化重点,本人踩了很多坑,在某个论坛上发现某大佬的经验

注意:多模块项目仅仅需要在启动类所在的模块添加打包插件即可,不要在父类添加打包插件,因为那样会导致全部子模块都使用spring-boot-maven-plugin的方式来打包(例如BOOT-INF/com/hehe/xx),而mm-web模块引入mm-xx 的jar 需要的是裸露的类文件,即目录格式为(/com/hehe/xx)。

  • Docker也是应该如此,首先:不应该有两个端口出现在同一个jar包内,第二:pom的打包方式不能获得我们要的程序,父工程只是分模块开发而已,我们最后要的是jar包->交付的是Linux内的Docker镜像

  • 对于本项目,mailserver和vhrserver是两个不同的项目,只是用RabbitMQ通信而已,pom.xml中的层级关系要理清

  • 回顾maven基础:maven中唯一确定一个包的三个因素是:

  <dependency>
      <groupId></groupId>
      <artifactId></artifactId>
      <version></version>
  </dependency>
  • 所以,我们只需要在有jar包的位置放置我们的docker打包插件,最后打包时,直接打包整个后端工程/vhr即可,因为模块有依赖关系,我们不必关心先打包哪一个,打包以及构建镜像需要5min多,耐心等待,打包完成之后可看到远程服务器多了镜像

  • 本地重启idea可以看到右下角多了个提示,提示我们可以发布容器,我们连接远程服务器,发布我们的容器,Create Docker Configuration,拼凑我们的命令将容器运行起来

    关于idea的docker图标在哪里找:在Run/Debug Configurations里面,就是MVC阶段我们配置tomcat的地方

  • jdk版本要对应 都用11,docker在构建镜像时的jdk版本也要对应,否则项目启动失败,我重构了3次,推荐镜像构建用adoptopenjdk/openjdk11:latest

  • 最后,运行容器即可

    docker run -dit -p 8182:8182 --name vhr-web --network host 2084team/vhr-web
  • 公网访问

  • 这些所有的细节,错一点你的项目都不能成功!

前端服务

  • 可以用docker构建前端工程或可以用第三方平台来放置前端服务,减少服务器压力

  • 这里nginx配置转发策略,所以用直接主机,而不是容器内

    远程服务器配置前端工程

  • 本地构建前端工程,静态资源直接放到服务器即可

    npm run build 
  • 因为nginx做内网转发,所以后端不用做https证书配置

  • 服务器太小导致卡顿,这里可以选择第三方平台放置服务或者大的服务器

  • Docker 打包部署前端工程,如果是这样那么需要停止掉主机上的原来的nginx systemctl stop nginx

    WebStorm连接os1机器的Docker

    编写Dockerfile文件暴露端口80,注意vue.config.js配置中的端口也要暴露这个端口,因为前端镜像基于nginx,nginx监听不允许其他端口否则运行不了,default.conf中转发的路径要写真实ip和真实端口号,当然了,可以部署3个后端,然后进行分权重转发

    点击Edit Configuration开始写配置打包,编译并上传镜像

    启动

    docker run -dit  --name vuehr --network host  vuehr

分机器部署策略

最后虽然部署成功,但是消息队列,数据库,后端服务,前端服务,缓存服务都在一台主机上,本人的1核2G的阿里云学生机太小,导致瞬间卡顿,自己的博客都挂了,所以不得不使用别的方法,因为我们实验室有机器,这种分配策略适合三台机器配置一样的情况

我们实验室有三台机器,互相来讲都是内网,可以考虑分配策略

服务器密码忘了,可以上网搜索(WinSCP密码忘了怎么办),别问我为什么搜索😂

服务\平台 第三方平台托管 os1 c1 web1
前端服务 暂不考虑 静态直接放在本地80端口或者Docker 80
后端服务 Docker 8181 8182
消息队列 Docker 5672 15672 25672 1883 61613
缓存 Docker 6379
数据库 Docker 3306 33060

注意我刚才写的用Docker部署*的命令,都加了--network host,就是使用和本机一样的端口,而不创建虚拟端口,这样做是不让docker创建新的网卡,后面有说为什么这样做

三台服务器安装配置Docker

安装看官方文档

配置docker的国内镜像

# 进入文件
vim /etc/docker/daemon.json

# 修改镜像源
{"registry-mirrors": ["https://registry.cn-hangzhou.aliyuncs.com"]}

# 重启docker
systemctl daemon-reload
systemctl restart docker

# 查看镜像源
docker info|grep Mirrors -A 1

服务器配置

查看服务器内存,可看到服务器内存相当大

# ubuntu
watch free -h
# centos
free -m 
打开centos端口
# 查询端口是否打开
firewall-cmd --query-port=[port]/tcp

# 查看防火墙状态 
systemctl status firewalld
# 开启防火墙 
systemctl start firewalld  
# 关闭防火墙 
systemctl stop firewalld
# 开启防火墙 
service firewalld start 
# 若遇到无法开启
# 先用:
systemctl unmask firewalld.service 
# 然后:
systemctl start firewalld.service

# 添加指定需要开放的端口:
firewall-cmd --add-port=123/tcp --permanent
# 重载入添加的端口:
firewall-cmd --reload
# 查询指定端口是否开启成功:
firewall-cmd --query-port=123/tcp
# 移除指定端口:
firewall-cmd --permanent --remove-port=123/tcp

# 安装iptables-services :
yum install iptables-services 
# 进入下面目录进行修改:
/etc/sysconfig/iptables
打开ubuntu端口
sudo apt-get install iptables
sudo apt-get install iptables-persistent
锐捷上网

搞了半天,发现服务器上网断断续续,查看日志发现多网卡配置,锐捷会禁用多网卡上网,所以才会出现只能上网一分钟然后退出的问题,Windows也是如此,最终一台机器上允许存在:docker0,ens*,lo三个网卡,不能出现其他的网卡

ifconfig 
sudo ifconfig [网卡] down

上网了,但是删除网卡导致了容器网络消失,我将网卡停掉,发现web1和c1两台机器(MySQL,Redis和RabbitMQ)客户端都连不上了

这是因为锐捷认证上网,除了本地的网卡不能有其他虚拟网卡,但是Docker在运行容器时会创建新的网卡(docker0本身没事),所以docker和ruijie上网冲突,不得不选择--netowrk host的容器启动方式

这里要说:锐捷上网和Docker容器并存的解决方案是我摸索出来的(幸亏学了Docker网络原理),关于Docker可以上B站找狂神说

原文链接

host模式 如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。

使用host模式的容器可以直接使用宿主机的IP地址与外界通信,容器内部的服务端口也可以使用宿主机的端口,不需要进行NAT,host最大的优势就是网络性能比较好,但是docker host上已经使用的端口就不能再用了,网络的隔离性不好。

这样既能保证网络通畅,又能保证docker容器服务,也就是说-p没有用了,你在运行MySQL,Redis,RabbitMQ和两个后端服务时加不加-p都没事,直接使用主机端口,而不是虚拟端口的映射

os1主机反向代理,分发请求

  • os1安装nginx
apt-get install nginx 

配置文件位置:/etc/nginx/nginx.conf

证书位置:/home/tls_certificate/*

  • 我们将域名证书和前端打包好的服务上传到服务器

用scp将Windows本地的文件传给服务器

# 关闭ubuntu防火墙要
ufw disable
# 开放端口
sudo ufw allow 21
ufw default allow 21
# 传文件
scp -P 21 -r /dist/ [email protected]:/etc/nginx/sites-available
ufw enable

将Windows本地生成的公钥粘贴至/root/.ssh下的authorized_keys即可,否则提示密码输入错误

这篇文章讲述了两个主机建立信任的过程

或者用root改文件操作权限,直接拖拽文件即可

chmod 777 

小结

域名要解析到os1主机上,这样静态资源( * .html,字体图标,* .js ,*.css)等会直接读取服务器磁盘,nginx会转发请求给后端,对于三台机器来讲都是内网,这样前后端分离,数据库,缓存,消息队列都分开访问速度肯定快,如果不需要外网访问,那么到这里就可以了,但是我们为了外网访问,需要frp内网穿透

内网穿透

简介

frp官方文档

那么现在已经可以通过内网(校园网)访问我们的系统 https://oa.2084team.com ,但是想要通过外网还要配置frp内网穿透

Windows本地下载,正常解压上传止服务器即可

文件目录

frps公网服务器root /home/frps

frpc内网服务器os1 /home/frpc

SSH 外网连接内网服务器

用SSH命令行方式连接内网服务器

  • 确保对应端口打开:内网外网端口都打开
  • 确保内网服务器能上网,连接外网

按照文档的配置文件编写,然后我们使用一个不连接内网的机器,比如iPad连接内网服务器试试能否成功

# 连接
ssh -oPort=6000 [内网用户名]:[外网ip]
# 密码是内网服务器密码

确实是成功了,这里会看起来有些奇怪:用的是内网用户名,外网ip,内网服务器密码,这里只是frp的转发作用将外网的流量通过6000端口转发到了内网22端口上,通信协议为tcp

域名访问内网web服务

这里我们不用这种方式,而是直接采用https的方式

那么我们的域名也要解析到外网服务器上了

外网服器的端口开放一个,用来设置web服务的转发端口,需要说明:外网的服务器80和443端口不能占用

域名证书:/home/tls_certificate/oa.2084team.com.pem

这部分可以自己摸索,没弄明白就看这篇播客

如果frpc不能转发80或者443端口,那么可以将前端服务打包在Docker中运行,端口为非80端口

启动服务

配置文件编写好以后

先启动公网服务器的服务端

./frps -c ./frps.ini

然后启动内网服务器的客户端

./frpc -c ./frpc.ini

长期运行frp需要编写shell脚本放在客户端和服务端的/etc/systemd/system目录下

编写shell脚本,后台长期启动frps,frpc

公网服务端frps

vim /etc/systemd/system/frps.service

# shell脚本
[Unit]
Description=frp-server daemon
Wants=NetworkManager-wait-online.service network-online.target
After=NetworkManager-wait-online.service network.target network-online.target
#After=network.target
[Service]
Type=simple
#User=root
Restart=on-failure
RestartSec=5s
WorkingDirectory=/home/frps
ExecStart=/home/frps/frps -c /home/frps/frps.ini
[Install]
WantedBy=multi-user.target

然后就可以指挥脚本了

sudo systemctl daemon-reload
sudo systemctl enable frps.service
sudo systemctl disable frps.service
sudo systemctl start frps.service
sudo systemctl stop frps.service
sudo systemctl restart frps.service
sudo systemctl status frps.service

内网客户端frpc

这个类似于frps的

vim /etc/systemd/system/frpc.service

# shell脚本
[Unit]
Description=frp-client daemon
Wants=NetworkManager-wait-online.service network-online.target
After=NetworkManager-wait-online.service network.target network-online.target
#After=network.target
[Service]
Type=simple
#User=root
Restart=on-failure
RestartSec=5s
WorkingDirectory=/home/frpc
ExecStart=/home/frpc/frpc -c /home/frpc/frpc.ini
ExecReload=/home/frpc/frpc reload -c /home/frpc/frpc.ini
[Install]
WantedBy=multi-user.target

指挥脚本

sudo systemctl daemon-reload
sudo systemctl enable frpc.service
sudo systemctl disable frpc.service
sudo systemctl start frpc.service
sudo systemctl stop frpc.service
sudo systemctl restart frpc.service
sudo systemctl status frpc.service

至此已经可以通过外网访问了,结束!!!

Releases

No releases published

Packages

No packages published