微人事是一个前后端分离的人力资源管理系统,项目采用 SpringBoot+Vue 开发,项目加入常见的企业级应用所涉及到的技术点,例如 Redis、RabbitMQ 等。
首先,不同的用户在登录成功之后,根据不同的角色,会看到不同的系统菜单,完整菜单如下:
不同用户登录上来之后,可能看到的会有差异,如下:
每个用户的角色是由系统管理员进行分配的,系统管理员给用户分配角色的页面如下:
系统管理员也可以管理不同角色可以操作的资源,页面如下:
git@github.com:lenve/vhr.git
OK,至此,服务端就启动成功了,此时我们直接在地址栏输入 http://localhost:8081/index.html
即可访问我们的项目,如果要做二次开发,请继续看第七、八步。
# 安装依赖
npm install
# 在 localhost:8080 启动项目
npm run serve
由于我在 vuehr 项目中已经配置了端口转发,将数据转发到 Spring Boot 上,因此项目启动之后,在浏览器中输入 http://localhost:8080
就可以访问我们的前端项目了,所有的请求通过端口转发将数据传到 Spring Boot 中(注意此时不要关闭 Sprin gBoot 项目)。
npm run build
该命令执行成功之后,vuehr 目录下生成一个 dist 文件夹,将该文件夹中的两个文件 static 和 index.html 拷贝到 Spring Boot 项目中 resources/static/ 目录下,然后就可以像第 6 步那样直接访问了(关于前后端分离部署,大家也可以参考这个使用 Nginx 部署前后端分离项目,解决跨域问题)。
分页不生效问题
SpringBoot 使用 @Transactional无效
分析:确实像往常一样在service上添加了注解 @Transactional,为什么查询数据库时还是发现有数据不一致的情况,想想肯定是事务没起作用,出现异常的时候数据没有回滚。 于是就对相关代码进行了一番测试,结果发现一下踩进了两个坑,确实是事务未回滚导致的数据不一致。
步骤 7 中需要大家对 NodeJS、NPM 等有一定的使用经验,不熟悉的小伙伴可以先自行搜索学习下,推荐 Vue 官方教程。
文档是对项目开发过程中遇到的一些问题的详细记录,主要是为了帮助没有基础的小伙伴快速理解这个项目。
<!-- docker 插件 begin -->
<plugin>
<!--三个坐标定位dockerfile插件-->
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
<version>1.4.13</version>
<!--放开这块注释,则运行mvn deploy命令就会打包镜像-->
<executions>
<execution>
<id>default</id>
<goals>
<!--如果package时不想用docker打包,就注释掉这个goal-->
<goal>build</goal>
<goal>push</goal>
</goals>
</execution>
</executions>
<configuration>
<!--这里指定打包镜像的名称-->
<repository>${docker.image.prefix}/${project.artifactId}</repository>
<useMavenSettingsForAuth>true</useMavenSettingsForAuth>
<!--<tag>${project.version}</tag>-->
<tag>latest</tag>
<!-- 提供参数向Dockerfile传递 这里是复制 jar 包到 docker 容器指定目录配置 -->
<buildArgs>
<JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE>
</buildArgs>
</configuration>
</plugin>
注意:最终打的包名要与<artifactId/>保持一致;
2.配置settings.xml
<pluginGroups>
<pluginGroup>com.spotify</pluginGroup>
</pluginGroups>
<servers>
<server>
<id>远程仓库空间名称</id>
<username>远程仓库登录名</username>
<password>远程仓库密码</password>
<configuration>
<email>邮箱</email>
</configuration>
</server>
</servers>
3.编写env文件
.env 文件包含了一些变量,这些变量可以在 docker-compose.yml 文件中通过 ${variable_name} 来引用。
.
│ .env
│ docker-compose.yml
│ ....................
└─────────
注意,EVN文件要与引用文件放置同一个目录,方便使用,否则会因目录问题不生效;
3.配置DockerFile
FROM openjdk:8-jdk-alpine
#引入一个父镜像,在此基础上进行添加只读层,FORM下面的命令,可以理解就是在已有的只读层,添加只读层
#设置编译镜像时加入的参数。 这里的JAR_FILE就是maven插件中的<JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE>
ARG JAR_FILE
#(只支持将本地文件复制到容器 ,还有个ADD更强大但复杂点。)把app.jar放在docker image的根目录下
COPY ${JAR_FILE} /opt/app.jar
#EXPOSE 指定于外界交互的端口
EXPOSE 8081
#解决验证码空指针问题,原因是 Alpine 太过精简,导致里面没有字体,只需要安装字体即可
RUN echo -e "https://mirror.tuna.tsinghua.edu.cn/alpine/v3.4/main\n\
https://mirror.tuna.tsinghua.edu.cn/alpine/v3.4/community" > /etc/apk/repositories
RUN apk --update add curl bash ttf-dejavu && \
rm -rf /var/cache/apk/*
#设置时区(定义了该镜像的时间格式及时区)
#RUN /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone
ENTRYPOINT java -Djava.security.egd=file:/dev/./urandom -Duser.timezone=Asia/Shanghai -Dfile.encoding=UTF-8 -jar /opt/app.jar
4.编写docker-compose.yml文件
version: '3'
services:
# ---------------------------
# 前台
# ---------------------------
hrserver-ui:
image: registry.cn-beijing.aliyuncs.com/hrserver/hrserver-ui:latest
volumes:
# 挂载nginx的配置文件
- ./nginx.conf:/etc/nginx/nginx.conf
container_name: web-service
restart: always
ports:
- "80:80"
networks:
- net
# ---------------------------
# 邮件服务
# ---------------------------
mailserver:
image: registry.cn-beijing.aliyuncs.com/hrserver/mailserver:latest
container_name: mailserver
restart: always
ports:
- "8082:8082"
networks:
- net
# ---------------------------
# 后台服务
# ---------------------------
vhr-web:
image: registry.cn-beijing.aliyuncs.com/hrserver/vhr-web:latest
container_name: vhr-web
env_file: docker-compose.env # 从文件中获取配置
restart: always
ports:
- "8081:8081"
networks:
- net
# ---------------------------
# Redis
# ---------------------------
redis:
image: redis:latest
container_name: redis
restart: always
env_file: docker-compose.env # 从文件中获取配置
command: redis-server /usr/local/etc/redis/redis.conf
ports:
- "6379:6379"
volumes:
- ./redis-data:/data
- ./redis.conf:/usr/local/etc/redis/redis.conf
networks:
- net
# ---------------------------
# rabbitMq
# ---------------------------
rabbit:
image: rabbitmq:3.6.6-management-alpine
container_name: rabbit-mq
restart: always
env_file: docker-compose.env # 从文件中获取配置
ports:
- "5672:5672"
- "15672:15672"
environment:
- RABBITMQ_DEFAULT_USER=guest
- RABBITMQ_DEFAULT_PASS=guest
networks:
- net
networks:
net:
driver: bridge
volumes:
data:
driver: local
Docker Compose是一个用来定义和运行复杂应用的Docker工具,一个使用Docker容器的应用,通常由多个容器组成。
注意:使用同一个docker-compose构建及服务编排文件,会将所有的container构建在同一网络下,涉及到负载均衡,分发请求至container时,
只需通过docker-compose里面的 service name 即可找到,而不是需要通过IP;
5.编写Shell脚本
#!/bin/sh
# 配置文件根目录,固定是hrserver
DOCKERHOME=/web/hnserver
# 镜像名称前缀、标签
BASE_IMAGE_NAME=registry.cn-beijing.aliyuncs.com/hrserver
BSEE_IMAGE_TAG=latest
# 各服务的镜像名称
UI_SERVICE=$BASE_IMAGE_NAME/hrserver-ui:$BSEE_IMAGE_TAG
MAIL_SERVICE=$BASE_IMAGE_NAME/mailserver:$BSEE_IMAGE_TAG
WEB_SERVICE=$BASE_IMAGE_NAME/vhr-web:$BSEE_IMAGE_TAG
case "$1" in
# 删除容器
removeAll)
echo "* 正在删除容器..."
time docker rm $(docker ps -aq) -f
echo "* 删除容器成功..."
;;
# 拉取镜像
pull)
echo "* 正在拉取后端镜像..."
time docker pull $MAIL_SERVICE
time docker pull $WEB_SERVICE
echo "* 开始拉取前端镜像..."
time docker pull $UI_SERVICE
echo "* 拉取镜像成功..."
;;
# 运行镜像
run)
echo "* 开始运行后端服务镜像..."
time docker-compose -f -p $DOCKERHOME/docker-compose-services.yml up -d
echo "* 等待10s..."
echo "* 运行成功..."
;;
# 拉取镜像并运行
pullrun)
echo "* 正在拉取后端镜像..."
time docker pull $MAIL_SERVICE
time docker pull $WEB_SERVICE
echo "* 开始拉取前端镜像..."
time docker pull $UI_SERVICE
echo "* 拉取镜像成功..."
echo "* 开始运行前端与后端服务镜像..."
time docker-compose -f $DOCKERHOME/docker-compose-services.yml up -d
echo "* 等待10s..."
echo "* 运行成功..."
;;
# 停止容器
stop)
echo "* 正在停止容器..."
time docker-compose -f $DOCKERHOME/docker-compose-services.yml stop
echo "* 停止容器成功..."
;;
# 重启容器
restart)
echo "* 正在停止镜像..."
time docker-compose -f $DOCKERHOME/docker-compose-services.yml restart
;;
# 其它
*)
echo "* ..."
;;
esac
exit 0
诠释:
该脚本主要用于从远程仓库拉取镜像、然后批量实现脚本的运行、删除、停止,执行的是对应的docker-compose.yml
6.使用命令将镜像推送至远程仓库
将镜像推送到Registry
$ sudo docker login --username=x心j静r如s水 registry.cn-beijing.aliyuncs.com
$ sudo docker tag [ImageId] registry.cn-beijing.aliyuncs.com/hrserver/vhr-web:[镜像版本号]
$ sudo docker push registry.cn-beijing.aliyuncs.com/vhr-web:[镜像版本号]
请根据实际镜像信息替换示例中的[ImageId]和[镜像版本号]参数。
$ sudo docker tag 6c69561208d2 registry.cn-beijing.aliyuncs.com/hrserver/vhr-web:latest
$ sudo docker tag 8aed8174e20f registry.cn-beijing.aliyuncs.com/hrserver/mailserver:latest
$ sudo docker tag 0d7826d3943c registry.cn-beijing.aliyuncs.com/hrserver/hrserver-ui:latest
$ docker push registry.cn-beijing.aliyuncs.com/hrserver/vhr-web:latest
$ docker push registry.cn-beijing.aliyuncs.com/hrserver/mailserver:latest
$ docker push registry.cn-beijing.aliyuncs.com/hrserver/hrserver-ui:latest
7.部署方式
将源码docs/deploy目录下的docker-compose.env、docker-compose-base.yml、
docker-compose-services.yml、nginx.conf、docker-compose.evn、
start.sh文件上传到服务器的自己创建的/web/hnserver目录下
(一)、批量执行脚本:通过脚本启动镜像、并生成容器
sed -i "s/\r//" start.sh
./start.sh run
./start.sh stop
(二)、单个执行
docker-compose -f docker-compose-services.yml up -d
(三)、实时查看docker容器日志
$ sudo docker logs -f -t --tail 行数 容器名
docker logs -f -t --tail 100 vhr-web
docker logs -f -t --tail 100 web-service
(四)、容器管理命令
列出所有处于停止状态的容器列表: docker ps -a -f status=exited
删除所有处于停止状态的容器 docker rm $(docker ps -a -f status=exited -q)
批量删除其他状态的容器方法同理。删除所有容器首先需要停止所有容器
docker stop $(docker ps -a -q)
删除所有容器: docker rm $(docker ps -a -q)
docker查看容器IP地址:docker inspect 容器名称或 id
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。