一、什么是持续集成

项目的版本控制工具有git,svn等,程序员提交项目要提交到版本控制工具中

只要把代码提交到CI,CI服务器负责从版本控制工具中拉取代码,并且会自动化的构建脚本,负责拉取、编译、打包、测试、部署

用户访问WEB服务器即可看到并且构建项目

CI的优点:

1.降低风险

2.减少重复工作(部署编译打包等,CI会自动完成)

二、软件开发模式

需求分析:确定需求

设计:系统框架设计、页面设计、数据库设计

实现:代码开发

测试:代码测试、压力测试

净化:修改bug、功能增加

三、软件开发模式

分为瀑布模型和敏捷开发

迭代开发

增量开发

四、Jenkins介绍

Jenkins  是一款流行的开源持续集成(Continuous Integration)工具,广泛用于项目开发,具有自动化构建、测试和部署等功能。官网:  http://jenkins-ci.org/。

五、Jenkins安装配置

六、Jenkins安装-插件安装

部署后端用到的插件,是这五个

Maven Integration plugin:对项目进行编译打包管理项目

Docker plugin:项目是基于DockerFile来创建镜像和容器的,要集成docker相关的插件

GitLab Plugin:负责版本控制,码云

Publish Over SSH和SSH:基于这两插件实现项目部署到不同服务器

高级:可以下载网上的插件并导入到Jenkins

七、服务器环境准备

192.168.200.100这台服务器中拉取代码、编译、打包、远程部署,需要先准备对应的环境

Docker安装配置(已安装)

Jdk安装配置(已安装)

检查Java,git,docker版本

Git安装配置:

         1.yum 安装方式

yum -y install git

        2.检查git版本

git version

Maven安装配置:

        1.上传本地的maven和本地仓库(有了本地仓库就无需在网上下载依赖了)

        2.解压安装包        

cd /usr/local
unzip -o apache-maven-3.6.1.zip

        3.环境变量配置(指定Maven的安装位置)

vi /etc/profile

增加:

export MAVEN_HOME=/usr/local/maven/apache-maven-3.6.1
export PATH=$PATH:$MAVEN_HOME/bin

如果权限不够,则需要增加当前命令的权限(给Maven命令设置权限)

chmod 777 /usr/local/maven/apache-maven-3.6.1/bin/mvn

        4.修改镜像仓库配置

vi /usr/local/maven/apache-maven-3.6.1/conf/settings.xml

修改setting文件,仓库为上传的仓库

在FinalShell中操作

解压Maven和本地仓库

删除压缩包

pwd:

pwd是"print working directory"的缩写,用于显示当前的工作目录路径。在这里,它显示了当前目录为/usr/local/maven/apache-maven-3.3.9,帮助我们确认确实位于Maven的安装目录中。

vi /etc/profile:

这条命令使用的是vi编辑器来打开并编辑/etc/profile文件。/etc/profile是一个全局的shell脚本文件,在用户登录时会被读取,可以用来设置环境变量、别名等。在这个上下文中,很可能是为了添加Maven的环境变量,如MAVEN_HOME和将Maven的bin目录添加到系统的PATH中,以便可以在任何地方直接通过命令行调用Maven。

进入vim文本编辑后,修改内容为:

设置权限

测试输入mvn,发现权限不够

chmod 777 /usr/local/maven/apache-maven-3.6.1/bin/mvn

这条命令 chmod 777 /usr/local/maven/apache-maven-3.6.1/bin/mvn 的意思是修改指定文件的权限

让我们分解来看:

  • chmod: 这是 Linux/Unix 系统中的一个命令,全称是 "change mode",专门用来改变文件或目录的访问权限。

  • 777: 这是一个用八进制数字表示的权限模式。它由三个数字组成,分别代表三类用户的权限:

    1. 第一个 7: 表示文件所有者 (Owner) 的权限。
    2. 第二个 7: 表示文件所有者所属的组 (Group) 的权限。
    3. 第三个 7: 表示其他所有用户 (Others) 的权限。

    在权限系统中,每个数字是以下权限值的总和:

    • 4 = 读 (read, r)
    • 2 = 写 (write, w)
    • 1 = 执行 (execute, x)

    因此,7 (4 + 2 + 1) 代表 读、写、执行 三种权限全部拥有。

     

    所以,777 意味着:文件的所有者、所属组的成员以及其他所有用户,都拥有对该文件的读、写和执行权限

  • /usr/local/maven/apache-maven-3.6.1/bin/mvn: 这是命令作用的目标文件的完整路径

    • /usr/local/maven/apache-maven-3.6.1/ 是 Maven 的安装目录。
    • /bin/mvn 是 Maven 的主执行脚本(一个 shell 脚本)。

总结

这条命令的作用是:将 Maven 的执行脚本 mvn 的权限设置为 777,即让系统上的每一个用户都拥有读取、修改和执行这个脚本的权限。

为什么这样做?(以及潜在风险)

  • 目的:通常在安装 Maven 后,mvn 脚本可能没有对所有用户开放执行权限。运行 chmod 777 是一种快速确保任何用户都能执行 mvn 命令的方法,尤其是在配置环境变量后测试是否能正常运行时。

  • 风险777 权限是非常宽松且不安全的

    • 写权限 (w):任何用户都可以修改 mvn 脚本。恶意用户可以篡改这个脚本,例如在其中植入后门或恶意代码,当其他用户(尤其是 root 用户)执行 mvn 时,恶意代码就会被执行。
    • 最佳实践:更安全的做法是使用 chmod 755。这表示:
      • 所有者:读、写、执行 (7)
      • 所属组:读、执行 (5 = 4 + 1)
      • 其他用户:读、执行 (5 = 4 + 1) 这样既能保证脚本可以被正常执行,又避免了不必要的安全风险。

在Maven的setting.xml文件中设置仓库地址

拿到仓库的路径

修改Maven中的settings.xml文件

八、Jenkins工具配置

因为Jenkins上安装了docker,jdk,maven、git

所以都需要指定环境的目录,在Jenkins中指定

打开全局工具配置

取消勾选自动安装jdk

配置jdk

配置git

配置maven

docker

然后单击应用保存,这样git、jdk、maven、docker就都集成到了Jenkins

接着就可以完成项目部署了

九、后端项目部署--整体思路

项目部署的整体思路

必须保证在同一个网段:192.168.200这个网段,用Ping命令检查是否ping通

为什么130服务器也需要:因为ES,Kafka,Nacos都在 130服务器,所以100服务器要能脸上130服务器

使用dcokerfile去部署项目

十、服务集成Docker配置

目标:部署的每一个微服务都是先创建docker镜像后创建对应容器启动

方式一:本地微服务打包以后上传到服务器,编写Dockerfile文件完成。

方式二:使用dockerfile-maven-plugin插件,可以直接把微服务创建为镜像使用(更省事)

服务集成Docker配置

每个微服务都引入该依赖

       <properties> 
<docker.image>docker_storage</docker.image>
 </properties>
 <build>
        <finalName>heima-leadnews-user</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.7.0</version>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>com.spotify</groupId>
                <artifactId>dockerfile-maven-plugin</artifactId>
                <version>1.3.6</version>
                <configuration>
                    <repository>${docker.image}/${project.artifactId}</repository>
                    <buildArgs>
                        <JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE>
                    </buildArgs>
                </configuration>
            </plugin>
        </plugins>
    </build>

<repository>${docker.image}/${project.artifactId}</repository>:

        repository用于指定镜像属于的仓库,因为在100服务器创建镜像,想在130服务器上启动容器,就应该在当前镜像上创建仓库,然后让130服务器下载,所以要指定仓库

<JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE>:

        自定义存储,可以指定项目打包后存放的位置,存放在target目录,并指定名称为项目名称

服务集成Dockerfile文件

每个微服务的根目录:

# 设置JAVA版本
FROM java:8
# 指定存储卷, 任何向/tmp写入的信息都不会记录到容器存储层
VOLUME /tmp
# 拷贝运行JAR包
ARG JAR_FILE
COPY ${JAR_FILE} app.jar
# 设置JVM运行参数, 这里限定下内存大小,减少开销
ENV JAVA_OPTS="\
-server \
-Xms256m \
-Xmx512m \
-XX:MetaspaceSize=256m \
-XX:MaxMetaspaceSize=512m"
#空参数,方便创建容器时传参
ENV PARAMS=""
# 入口点, 执行JAVA运行命令
ENTRYPOINT ["sh","-c","java -jar $JAVA_OPTS /app.jar $PARAMS"]

ARG JAR_FILE
COPY ${JAR_FILE} app.jar:

        找jar文件存放位置,对应pom文件中的<JAR_FILE>标签

ENV PARAMS="":

        后期启动项目可以添加一些参数

十一、Jenkins部署项目

所有微服务打包的方式类似,以heima-leadnews-user微服务为例

1,新建任务

如果构建失败,要看控制台输出

最终构建成功(第一次构建没有的jar包都会在网络下载,所以耗时会久一点)

模块都下载完成了

这些模块都安装到了maven的本地仓库,指的是100这台服务器的本地仓库

十二、微服务打包配置

dockerfile:build     会自动创建镜像

选择执行shell指令

if [ -n  "$(docker ps -a -f  name=$JOB_NAME  --format '{{.ID}}' )" ]
 then
 #删除之前的容器
 docker rm -f $(docker ps -a -f  name=$JOB_NAME  --format '{{.ID}}' )
fi
 # 清理镜像
docker image prune -f 
 # 启动docker服务
docker run -d --net=host -e PARAMS="--spring.profiles.active=prod"  --name $JOB_NAME docker_storage/$JOB_NAME

这个shell脚本表示:判断容器是否存在,如果存在,删除容器再创建。所以每次执行这个脚本都会去创建镜像

-d --net=host   :   创建的容器要使用宿主机的端口

-e PARAMS="--spring.profiles.active=prod"    :  指定使用的环境是prod(有dev(默认环境)test和prod)

--name $JOB_NAME    :  给容器起名

docker_storage/$JOB_NAME    :   基于哪个镜像去创建容器

十三、部署服务到远程服务器上

目标:使用jenkins(192.168.200.100)把微服务打包部署到192.168.200.130服务器上

1,安装私有仓库

①:下载最新Registry镜像

docker pull registry:latest

②:启动Registry镜像服务

docker run -d -p 5000:5000 --name registry -v /usr/local/docker/registry:/var/lib/registry registry:latest

③:查看仓库资源

访问地址:http://192.168.200.100:5000/v2/_catalog

④:配置Docker客户端,重启docker后生效

vi /lib/systemd/system/docker.service

修改内容:(因为当前仓库默认不允许上传,所以需要设置信任的操作)

ExecStart=/usr/bin/dockerd --insecure-registry 192.168.200.100:5000

2,jenkins中安装插件

3,jenkins系统配置远程服务器链接

4,jenkins项目创建与其他微服务相同

Dockerfile

pom.xml文件

bootstrap.yml

在nacos,prod环境的配置

相关数据库

5,设置参数

6,构建执行Execute shell

maven命令

clean install -Dmaven.test.skip=true dockerfile:build -f heima-leadnews/heima-leadnews-service/heima-leadnews-article/pom.xml

还要再本地执行shell命令,在130服务器上创建镜像,如果已经存在先删除在创建,然后推送到远程仓库,推送完成再清理

image_tag=$docker_registry/docker_storage/$JOB_NAME
echo '================docker镜像清理================'
if [ -n  "$(docker ps -a -f  name=$JOB_NAME  --format '{{.ID}}' )" ]
 then
 #删除之前的容器
 docker rm -f $(docker ps -a -f  name=$JOB_NAME  --format '{{.ID}}' )
fi
 # 清理镜像
docker image prune -f 

# 创建TAG
docker tag docker_storage/$JOB_NAME $image_tag
echo '================docker镜像推送================'
# 推送镜像
docker push $image_tag
# 删除TAG
docker rmi $image_tag
echo '================docker tag 清理 ================'

7,在远程服务器上执行脚本

在130服务器上执行

拉取最新镜像,删除清理容器镜像,启动容器

使用的环境为prod:

docker run -d   --net=host -e PARAMS="--spring.profiles.active=prod" --name $JOB_NAME $docker_registry/docker_storage/$JOB_NAME

echo '================拉取最新镜像================'
docker pull $docker_registry/docker_storage/$JOB_NAME

echo '================删除清理容器镜像================'
if [ -n  "$(docker ps -a -f  name=$JOB_NAME  --format '{{.ID}}' )" ]
 then
 #删除之前的容器
 docker rm -f $(docker ps -a -f  name=$JOB_NAME  --format '{{.ID}}' )
fi
 # 清理镜像
docker image prune -f 

echo '===============启动容器================'
docker run -d   --net=host -e PARAMS="--spring.profiles.active=prod" --name $JOB_NAME $docker_registry/docker_storage/$JOB_NAME

点击根据参数构建即可

100服务器创建镜像,并push到远程仓库

创建镜像成功,在130服务器上

8.构建完成以后,可以登录130服务器,查看是否有相关的镜像和容器

去查看镜像是否创建成功

创建容器成功

可以查看微服务日志  docker logs -f  容器名称

也可以在nacos中查看到

总体思路:

在100服务器上创建微服务镜像,然后把镜像push到远程仓库里面,然后100服务器删除镜像和容器,然后130服务器会先去拉取下载最新镜像,如果之前有镜像和容器会先进行清理,然后创建容器

十四、联调测试

1.参考jenkins中heima-leadnews-user微服务把app端网关部署起来

pom.xml添加build,bootstrap.yml中添加生效配置,Dockerfile,nacos添加配置

原先基础上只需要改个名字即可

复制heima-leadnews-user的配置都拷贝到当前项目中

修改

然后直接去构建

进行测试,看是否部署

2.修改本地nginx中的配置反向代理地址为100这台服务器:heima-leadnews-app.conf

upstream  heima-app-gateway{    
    server 192.168.200.100:51601;
}

这样他就会去寻找远程服务器上的网关

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐