
欢迎来到预见猿份,本站项目均为站长原创,学习中有问题可直接提交给站长老苗解决(微信:mrt_0607)。
苗润土老师,20余年一线项目经验,2014年加入黑马,星辰wms、云岚到家、学成在线项目作者,历任高级讲师、教学主管及课程研究员。 b站老苗
第七章 项目部署&总结
Linux命令速查:https://yjoffer.com/tools/linux-cheatsheet.html
Docker命令速查:https://yjoffer.com/tools/docker-cheatsheet.html
Java工程师高频面题:https://yjoffer.com/javaqa/readme.html
1 名词解释
什么是DevOps
一个软件的生命周期包括:需求分析、设计、开发、测试、上线、维护、升级、废弃。
项目的开发模型:瀑布模型、增量模型、敏捷模型
通过示例说明如下:
1、产品人员进行需求分析
2、设计人员进行软件架构设计和模块设计。
3、每个模块的开发人员并行开发,设计接口、进行编码,并进行单元测试
在开发阶段,开发人员统一连接公司局域网的服务器(maven私服、数据库、Git仓库、项目管理软件)进行开发。
4、开发完毕,将代码集成部署到测试服务器,测试人员进行测试。
5、测试人员发现bug,提交bug、开发人员修改bug
6、bug修改完毕再次集成、测试。
7、所有模块测试完成将项目部署到类生产环境,开始测试,测试完毕,将项目部署到生产环境,项目上线。
8、运维人员进行安装部署、培训。
9、用户提出问题,返回给运维人员。
10、运维人员反馈给项目经理,由项目经理分配给产品经理和开发人员,进行问题处理。
11、再次提交测试。
12、测试完毕,发布小版本,部署升级。
....
最后软件下线。
所以,在整体生命周期中比较核心的两个阶段是:开发阶段、维护阶段,开发阶段的成果是软件开发完成并成功上线,运维阶段则负责对软件进行维护和升级,而运维阶段通常在一个软件 的生命周期中占比最多。
提高开发阶段、运维阶段的工作效率是企业在进行软件项目管理的重点。
因此,专家提出了DevOps,DevOps是什么呢?
下边是摘自百度百科的定义:
DevOps(Development和Operations的组合词)是一组过程、方法与系统的统称,用于促进开发(应用程序/软件工程)、技术运营和质量保障(QA)部门之间的沟通、协作与整合。
它是一种重视“软件开发人员(Dev)”和“IT运维技术人员(Ops)”之间沟通合作的文化、运动或惯例。透过自动化“软件交付”和“架构变更”的流程,来使得构建、测试、发布软件能够更加地快捷、频繁和可靠。
它的出现是由于软件行业日益清晰地认识到:为了按时交付软件产品和服务,开发和运维工作必须紧密合作。

DevOps是一个工具吗?
DevOps是一个工作职位吗?
都不是。
DevOps是一种思想理念,它涵盖开发、测试、运维的整个过程。DevOps追求的目标是提高软件开发、测试、运维、运营等各部门的沟通与协作质量,DevOps强调软件开发人员与软件测试、软件运维、质量保障(QA)部门之间有效的沟通与协作,强调通过自动化的方法去管理软件变更、软件集成,使软件从构建到测试、发布更加快捷、可靠,最终按时交付软件。

什么是CI/CD
如何来落地实现DevOps呢?
DevOps兴起于2009年,近年来由于云计算、互联网的发展,促进了DevOps的基础设施及工具链的发展,涌现了一大批优秀的工具,这些工具包括开发、测试、运维的各各领域,例如:GitHub、Docker、Jenkins、Hudson、K8S、Ant/Maven/Gradle、Selenium、QUnit、JMeter等。下图是DevOps相关的工具集:

好的工具有利于DevOps的实施,但并不代表实施DevOps就一定需要去引入一堆工具。
问题的关键:如何解决问题,而不是具体应用工具。
CI/CD 是近年来企业有效实施DevOps的具体方案。
CI/CD 包含了一个 CI 和两个 CD,CI全称 Continuous Integration,表示持续集成,CD包含 Continuous Delivery和 Continuous Deployment,分别是持续交付和持续部署,三者具有前后依赖关系。
CI 持续集成:
持续集成倡导团队成员需要频繁的集成他们的工作,将开发分支合并到主分支,每次集成都通过自动化构建(包括编译、构建、自动化测试)来验证,从而尽快地发现集成中的错误,让产品可以快速迭代,同时还能保持高质量。

CD持续交付:
持续交付将集成后的代码部署到类生产环境(预发布),除了交付到类生产环境之外,还会执行一些集成测试、API测试。持续交付强调的是“交付”,交付给测试、产品验收,不管怎么更新,软件是随时随地可以交付的。

CD持续部署:
在持续交付的基础上由开发人员或运维人员自助式的定期向生产环境部署稳定的构建版本,持续部署的目标是代码在任何时刻都是可部署的,并可自动进入到生产环境。

完整的CI/CD方案:

1 安装基础软件
操作准备环境:
操作系统:Centos7
基础软件:docker及docker-compose。
1.1 拉取镜像
首先配置镜像加速地址
创建并编辑/etc/docker/daemon.json文件(如果文件不存在,则创建):
放大查看复制代码
{
"registry-mirrors" : [
"https://reg-mirror.qiniu.com/",
"https://guhuri1i.mirror.aliyuncs.com",
"https://0dj0t5fb.mirror.aliyuncs.com",
"https://docker.mirrors.ustc.edu.cn",
"https://6kx4zyno.mirror.aliyuncs.com",
"https://registry.docker-cn.com",
"http://hub-mirror.c.163.com",
"https://2a6bf1988cb6428c877f723ec7530dbc.mirror.swr.myhuaweicloud.com",
"https://docker.m.daocloud.io",
"https://hub-mirror.c.163.com",
"https://mirror.baidubce.com",
"https://your_preferred_mirror",
"https://dockerhub.icu",
"https://docker.registry.cyou",
"https://docker-cf.registry.cyou",
"https://dockercf.jsdelivr.fyi",
"https://docker.jsdelivr.fyi",
"https://dockertest.jsdelivr.fyi",
"https://mirror.aliyuncs.com",
"https://dockerproxy.com",
"https://docker.m.daocloud.io",
"https://docker.nju.edu.cn",
"https://docker.mirrors.sjtug.sjtu.edu.cn",
"https://docker.mirrors.ustc.edu.cn",
"https://mirror.iscas.ac.cn",
"https://docker.rainbond.cc"
]
}
重启docker:
systemctl restart docker
先通过 docker pull 命令拉取下边的镜像:
docker pull influxdb:2.7
docker pull emqx/emqx:5.8.6
docker pull redis:6.2.17
docker pull rabbitmq:4.0-management
docker pull mysql:8.0.29
docker pull pgvector/pgvector:pg16
docker pull mysql:8.0.291.2 安装MySQL
创建以下目录:
sudo mkdir -p /data/soft/mysql /data/soft/mysql/data /var/log/mysql
sudo chmod -R 777 /data/soft/mysql/ /var/log/mysql
创建配置文件
vim /data/soft/mysql/my.cnf
添加以下内容到上述创建的配置文件中
[client]
#socket = /usr/mysql/mysqld.sock
default-character-set = utf8mb4
[mysqld]
#
# Remove leading # and set to the amount of RAM for the most important data
# cache in MySQL. Start at 70% of total RAM for dedicated server, else 10%.
# innodb_buffer_pool_size = 128M
#
# Remove leading # to turn on a very important data integrity option: logging
# changes to the binary log between backups.
# log_bin
#
# Remove leading # to set options mainly useful for reporting servers.
# The server defaults are faster for transactions and fast SELECTs.
# Adjust sizes as needed, experiment to find the optimal values.
# join_buffer_size = 128M
# sort_buffer_size = 2M
# read_rnd_buffer_size = 2M
# Remove leading # to revert to previous value for default_authentication_plugin,
# this will increase compatibility with older clients. For background, see:
# https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_default_authentication_plugin
# default-authentication-plugin=mysql_native_password
lower_case_table_names=1
skip-host-cache
skip-name-resolve
datadir=/var/lib/mysql
socket=/var/run/mysqld/mysqld.sock
secure-file-priv=/var/lib/mysql-files
user=mysql
pid-file=/var/run/mysqld/mysqld.pid
[client]
socket=/var/run/mysqld/mysqld.sock
!includedir /etc/mysql/conf.d/创建启动容器
docker run -itd --name=mysql -v /data/soft/mysql/my.cnf:/etc/my.cnf -v /data/soft/mysql/data:/usr/mysql/data -v /var/log/mysql:/var/log/mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=mysql mysql:8.0.29说明: -v : 挂载宿主机目录和 docker容器中的目录,前面是宿主机目录,后面是容器内部目录 -d : 后台运行容器 -p 映射容器端口号和宿主机端口号 -e 环境参数,MYSQL_ROOT_PASSWORD设置root用户的密码
下边修改mysql的访问权限为所有客户端可以访问:
进入容器内部
sudo docker exec -it mysql /bin/bash
连接mysql
mysql -uroot -pmysql
使用mysql库
use mysql;
修改访问主机以及密码等,设置为所有主机可访问
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'mysql';
flush privileges;1.3 创建数据库
导入数据库

1.4 安装其它软件
自定义docker 网络:(方便docker容器通信)
docker network create wms-net然后创建工作目录:
mkdir -p /root/xingchencd /root/xingchen
vim docker-compose.yml
services:
redis:
image: redis:6.2.17
container_name: redis
ports:
- "6379:6379"
restart: always
rabbitmq:
image: rabbitmq:4.0-management
container_name: rabbitmq4
restart: always
ports:
- "15672:15672"
- "5672:5672"
volumes:
- rabbitmq-plugins:/plugins
environment:
- RABBITMQ_DEFAULT_USER=root
- RABBITMQ_DEFAULT_PASS=wms-root
emqx:
image: emqx/emqx:5.8.6
container_name: emqx
restart: always
ports:
- "1883:1883"
- "8083:8083"
- "8084:8084"
- "18083:18083"
volumes:
- emqx-data:/opt/emqx/data/configs
- emqx-log:/opt/emqx/log
networks:
- wms-net
influxdb:
image: influxdb:2.7
container_name: influxdb
restart: always
ports:
- "8086:8086"
volumes:
- /root/xingchen/influxdb/data:/var/lib/influxdb2
- /root/xingchen/influxdb/config:/etc/influxdb2
environment:
- DOCKER_INFLUXDB_INIT_MODE=setup
- DOCKER_INFLUXDB_INIT_USERNAME=root
- DOCKER_INFLUXDB_INIT_PASSWORD=wms-root
- DOCKER_INFLUXDB_INIT_ORG=itcast
- DOCKER_INFLUXDB_INIT_BUCKET=wms-iot
postgres:
image: pgvector/pgvector:pg16
container_name: postgres
restart: always
volumes:
- /root/xingchen/postgres/data:/var/lib/postgresql/data
ports:
- "5432:5432"
environment:
- POSTGRES_PASSWORD=postgresql
networks:
wms-net:
external: true
volumes:
rabbitmq-plugins:
emqx-data:
emqx-log:执行启动命令:
docker-compose up -d检查所有服务:
docker ps
1.5 关键验证
- emqx
管理页面访问:http://192.168.101.68:18083/
初始用户名密码:admin\public
登录后,系统要求修改密码,可以设置以下用户名密码,也可以直接跳过:
admin、wms-root(此密码只用于登录服务端控制台需要,客户端认证需要额外设置控制访问-客户端认证时才需要)
- influxdb
管理页面访问:http://192.168.101.68:8086
用户名密码:root/wms-root
应用中如果需要连接 influxdb需要配置token,可以在 influxdb 容器中,找到 /etc/influxdb2/influx-configs 文件
# 进入容器内部
docker exec -it influxdb /bin/bash
# 查看influxdb 连接token
cat /etc/influxdb2/influx-configs查看配置:http://192.168.101.68:8086/api/v2/config
查看 Token:http://192.168.101.68:8086/api/v2/authorizations
查看用户:http://192.168.101.68:8086/api/v2/users
查看数据库:http://192.168.101.68:8086/api/v2/buckets
Token:
zQwlfcO6tsC4ILwrSRvaURcNf3K9fQEnl9EbU1rl4awGF698Hwgg_KggXWGwbuiyHHsjCqG9GhgasQHQIA5PXA==将控制台输出的token内容,替换到应用中的 influxdb.token 配置中:
influx:
url: http://<ip>:<port>/
token: zQwlfcO6tsC4ILwrSRvaURcNf3K9fQEnl9EbU1rl4awGF698Hwgg_KggXWGwbuiyHHsjCqG9GhgasQHQIA5PXA==
bucket: wms-iot
org: itcast
username: root
password: wms-root- rabbitmq
管理页面:http://192.168.101.68:15672
用户名:root、wms-root
登录后,创建虚拟机:/wms-iot

- postgresql
docker容器运行成功后,使用DataGrip连接PostgreSQL
账号/密码:postgres/postgresql
添加扩展:
CREATE EXTENSION vector;然后查询生效的扩展:
SELECT * FROM pg_extension WHERE extname = 'vector';
执行以下脚本建表:
CREATE EXTENSION IF NOT EXISTS hstore
CREATE EXTENSION IF NOT EXISTS "uuid-ossp"
CREATE TABLE public.vector_store (
id uuid DEFAULT public.uuid_generate_v4() NOT NULL,
content text,
metadata json,
embedding public.vector(768)
);
CREATE INDEX IF NOT EXISTS spring_ai_vector_index ON public.vector_store USING HNSW (embedding vector_cosine_ops)
alter table public.vector_store
add constraint vector_store_pkey
primary key (id);创建成功:

2 手动部署
2.1 前端打包
2.1.1 修改文件
修改后端地址

执行:pnpm run build 进行打包。
打包过程中会出现错误:
根据错误提示进行处理:
处理内容如下:
将下边目录中的..backup文件删除



修改后:

根据上边的处理方法处理其它文件。
2.1.2 打包
执行:pnpm run build 进行打包。
打包成功在项目根目录生成 dist目录。

将dist目录压缩为dist.zip,上传到Linux的/root/xingchen/wms/wms-web目录下
进入/root/xingchen/wms/wms-web,执行下边的命令解压缩:
unzip dist.zip2.1.3 制作镜像
进入:/root/xingchen/wms/wms-web
创建Dockerfile文件:
FROM registry.cn-hangzhou.aliyuncs.com/dockerhub_mirror/nginx
MAINTAINER jeecgos@163.com
VOLUME /tmp
ENV LANG en_US.UTF-8
RUN echo "server { \
listen 80; \
location /jeecgboot/ { \
proxy_pass http://192.168.101.68:28080/jeecg-boot/; \
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; \
} \
#解决Router(mode: 'history')模式下,刷新路由地址不能找到页面的问题 \
location / { \
root /var/www/html/; \
index index.html index.htm; \
if (!-e \$request_filename) { \
rewrite ^(.*)\$ /index.html?s=\$1 last; \
break; \
} \
} \
access_log /var/log/nginx/access.log ; \
} " > /etc/nginx/conf.d/default.conf \
&& mkdir -p /var/www \
&& mkdir -p /var/www/html
ADD dist/ /var/www/html/
EXPOSE 80
EXPOSE 443执行docker build 命令:
docker build -t itcast/wms-web:1.0 .启动命令:
docker run -d \
--name=wms-web \
-p 80:80 \
--restart=always \
-v /root/xingchen/wms/wms-web/dist:/var/www/html \
itcast/wms-web:1.0docker容器启动成功:


2.2 服务端打包
2.2.1 打包
1)修改pom.xml
修改工程根目录下的pom.xml,将所有模块全部添加到到modules下。

2) 修改配置文件
修改application.yml:
spring.profiles.active=prod
拷贝原application-dev.yml到application-prod.yml
修改MySQL、RabbitMQ、influxDB、mqtt配置参数。
3)打包

打包完成,找到jar包

进入 Linux,创建 /root/xingchen/wms 目录。
将该jar包上传到 /root/xingchen/wms/wms-system 目录,并改名为 wms-system.jar
2.2.2 本地测试jar
在本地测试jar是否正确运行
java -jar wms-system.jar2.2.3 服务器测试jar
在服务器安装maven、jdk17软件,并运行jar
java -jar wms-system.jar2.2.4 制作镜像
创建Dockerfile 文件:
注意端口号写正确。
FROM openjdk:17-jdk
MAINTAINER jeecgos@163.com
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
WORKDIR /app
EXPOSE 28080
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/app/app.jar"]保存后,执行docker build,创建镜像
docker build -t itcast/wms-system:1.0 .创建成功:

查询镜像

2.2.5 启动容器
创建 docker-compose.yml,依然是在当前目录下:
version: '3.8'
services:
wms-system:
image: itcast/wms-system:1.0
container_name: wms-system
ports:
- "28080:28080"
volumes:
- /root/xingchen/wms/wms-system/config:/app/config
- /root/xingchen/wms/wms-system/static:/opt/upFiles/temp
- /root/xingchen/wms/wms-system/wms-system.jar:/app/app.jar
restart: always进入 /root/xingchen/wms 目录,启动容器:
docker-compose up -d可以通过 docker logs 查看启动日志,检查系统是否启动成功:
docker logs -f wms-system3 Jenkins部署
3.1 准备环境
在宿主机安装以下软件:
- 安装jdk
下载:jdk-17_linux-x64_bin.tar.gz
将jdk-17_linux-x64_bin.tar.gz上传到/root/xingchen下。
进入/root/xingchen,解压:
tar -zxvf /root/jdk-17_linux-x64_bin.tar.gz
配置环境变量
vi /etc/profile
在上面打开的文件末尾加上:
export JAVA_HOME=/root/xingchen/jdk-17.0.1
export PATH=/root/xingchen/jdk-17.0.1/bin:$PATH让配置生效
source /etc/profile
- 安装maven
将 apache-maven-3.8.6-bin.zip拷贝到/root/xingchen下,并解压
1.编辑 /etc/profile
vi /etc/profile
2. 在上面打开的文件末尾加上
#Maven Env
export MAVEN_HOME=/root/xingchen/apache-maven-3.8.6-bin
export PATH=$PATH:$MAVEN_HOME/bin
3.让配置生效
source /etc/profile- 安装Git
yum install -y git配置个人信息:
git config --global user.name 'xx'
git config --global user.email 'xx@qq.com'3.2 系统配置
访问jenkins:http://192.168.101.68:18080/

账号:admin
密码:123456
需要在jenkins中配置maven、java、git。
点击下图链接进入配置页面:

点击:Tools

配置maven的settings.xml文件位置。

配置java_home的位置:

配置maven_home的位置:

配置git:

3.3 提交代码到Git
我们使用虚拟机中的gogs作为git仓库,方便与jenkins交互。
进入gogs(http://192.168.101.68:3000),创建仓库


提交成功:

3.4 创建构建任务
- 创建一个任务
选择自由风格的任务


点击上图的保存,创建成功:

下一步进行配置:



3.5 构建项目
首先创建视图:





点击上图箭头位置,查询控制台输出

查询控制台,项目启动成功

3.6 自动构建
当有代码提交至Git,Git通知Jenkins开始构建项目,实现持续集成。
接口调用方式:gogs调用jenkins
3.6.1 安装插件
在jenkins上安装gogs插件

插件文档:https://plugins.jenkins.io/gogs-webhook/

3.6.2 配置webhook
首先从jenkins中配置密钥

在gogs上填写钩子地址:
进入仓库设置

填写钩子地址:http://192.168.101.68:18080/gogs-webhook/?job=wms
注意:上边地址中job对应jenkins上任务的名称
在gogs的“管理web钩子”页面输入密钥,此密钥就是在jenkins上配置的密钥。

3.6.3 测试
进入IDEA,修改代码并向git仓库推送,观察jenkins中对应的任务是否自动构建。

