Jenkins 自动打包发布 SpringCloud 微服务项目(含脚本)

在这里插入图片描述

环境准备

1. 安装JDK

  • 查看jdk版本
java -version
[root@sinolee /]# java -version
java version "17.0.2" 2022-01-18 LTS
Java(TM) SE Runtime Environment (build 17.0.2+8-LTS-86)
Java HotSpot(TM) 64-Bit Server VM (build 17.0.2+8-LTS-86, mixed mode, sharing)

2. 安装Git

yum install -y git
  • 查看是否安装成功
git version
[root@sinolee /]# git version
git version 1.8.3.1

3. 安装 Maven

yum -y install maven
  • 查看maven版本
mvn -version
[root@sinolee /]# mvn -version
Apache Maven 3.8.4 (9b656c72d54e5bacbed989b64718c159fe39b537)
Maven home: /usr/local/apache-maven-3.8.4
Java version: 17.0.2, vendor: Oracle Corporation, runtime: /usr/java/jdk-17.0.2
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "3.10.0-1160.66.1.el7.x86_64", arch: "amd64", family: "unix"

4. 安装jenkins

  • yum安装
wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo
rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io.key
yum upgrade

异常处理

启动异常 : Jenkins Continuous Integration Server

  • 使用 systemctl start jenkins.service 命令启动可能抛异常:
[root@sinolee ~]# systemctl start jenkins.service
Job for jenkins.service failed because the control process exited with error code. See "systemctl status jenkins.service" and "journalctl -xe" for details.
[root@sinolee ~]# systemctl status jenkins.service
● jenkins.service - Jenkins Continuous Integration Server
   Loaded: loaded (/usr/lib/systemd/system/jenkins.service; disabled; vendor preset: disabled)
   Active: failed (Result: start-limit) since Wed 2022-06-29 15:53:38 CST; 3s ago
  Process: 6449 ExecStart=/usr/bin/jenkins (code=exited, status=1/FAILURE)
 Main PID: 6449 (code=exited, status=1/FAILURE)

Jun 29 15:53:37 sinolee systemd[1]: Failed to start Jenkins Continuous Integration Server.
Jun 29 15:53:37 sinolee systemd[1]: Unit jenkins.service entered failed state.
Jun 29 15:53:37 sinolee systemd[1]: jenkins.service failed.
Jun 29 15:53:38 sinolee systemd[1]: jenkins.service holdoff time over, scheduling restart.
Jun 29 15:53:38 sinolee systemd[1]: Stopped Jenkins Continuous Integration Server.
Jun 29 15:53:38 sinolee systemd[1]: start request repeated too quickly for jenkins.service
Jun 29 15:53:38 sinolee systemd[1]: Failed to start Jenkins Continuous Integration Server.
Jun 29 15:53:38 sinolee systemd[1]: Unit jenkins.service entered failed state.
Jun 29 15:53:38 sinolee systemd[1]: jenkins.service failed.
  • 解决方案:
    • 不使用systemctl的方式操作Jenkins, 直接用Jenkins自带的服务启动 (使用 systemctl 最终也是执行的这个命令)
    • 切换到 Jenkins 脚本目录 cd /etc/init.d, 执行以下命令
# 启动
./jenkins start
# 停止
./jenkins stop
# 状态
./jenkins status

执行结果:

[root@sinolee init.d]# ./jenkins restart
Shutting down Jenkins                                      [  OK  ]
Starting Jenkins                                           [  OK  ]
[root@sinolee init.d]# ./jenkins status
jenkins (pid  19113) is running...

访问 jenkins, 浏览器地址栏输入 主机IP : 端口号, 如:127.0.0.1:8080
在这里插入图片描述

访问异常

在这里插入图片描述

  • 解决方案:
    • 安装以下包
yum install dejavu-sans-fonts
yum install fontconfig
yum install xorg-x11-server-Xvfb

环境配置及插件

定制安装所需插件

  • 配置路径 : Manage Jenkins >>> Manage Plugins

在这里插入图片描述

  • 选择所需插件, 点击安装 ( Install without restart )
    在这里插入图片描述

  • 安装中文插件

    • Available 搜索 ChineseLocalization: Chinese (Simplified)
      在这里插入图片描述

配置全局工具

1. 配置 Java 工具

  • 配置路径 : 系统管理 >>> 全局工具配置 >>> JDK >>> 新增JDK

在这里插入图片描述

注 : 若服务器上没有 Java 环境,可以选择自动安装。
建议 : 请预先在服务器上配置好Java环境. 可参考文章 ( 阿里云 ) Linux 安装jdk1.8(rpm方式)

2. 配置 Maven

  • 配置路径 : 系统管理 >>> 全局工具配置 >>> Maven 配置

在这里插入图片描述

当前配置页下,新增 Maven 安装路径,请手动配置,不选自动安装
在这里插入图片描述

settings.xml 文件 一般都是在 Maven 安装路径的 conf 目录下
建议 : 请预先在服务器上配置好Maven环境. 可参考文章 Linux 配置 Maven

基本使用

任务全部使用传统配置模式

CI 的整体逻辑 : 拉取代码 >>> 设置编译命令(方法) >>> 编译 >>> 生成结果(二进制文件或包)

创建一个Java任务

新建任 >>> 输入任务名称 >>> 构建一个Maven项目

Ps : 没有 构建一个Maven项目 选项的处理办法

在这里插入图片描述

  • 点击 可选插件 输入关键字 : Maven Integration 搜索并安装

在这里插入图片描述

  • 重启jenkins即可看到选项

在这里插入图片描述

源码管理

Ps : Jenkins源码管理无Git选项

在这里插入图片描述

  • 点击 可选插件 输入关键字 : Github 搜索并安装

在这里插入图片描述

配置项目Git账号
在这里插入图片描述

在这里插入图片描述

需构建的代码分支,此处是固定写死的。 当参数化构建的时候,可以填入指定的分支和tag
在这里插入图片描述

构建触发器

在这里插入图片描述

构建环境

在这里插入图片描述

Build

在这里插入图片描述

指定pom.xml的位置,maven类型的任务在编译的时候是根据代码中pom.xml的定义进行代码的编译动作

Post Steps

在这里插入图片描述

构建设置

在这里插入图片描述

构建后操作

可设置编译成功后的操作,如归档、触发其他的任务、清理工作空间,或其他一些自定义的操作。操作依赖插件的支持。在代码编译成功后增加发布的动作即整体实现CD的功能,从代码到服务器

在这里插入图片描述

run.sh 打包脚本

# 项目模块统一变量设置

# 消息队列服务
MQ_CONTAINER="mq"
MQ_IMAGE="mq_server"
MQ_PORT=8081

# 网站服务
WEB_CONTAINER="web"
WEB_IMAGE="web_server"
WEB_PORT=8082

# 用户服务
USER_CONTAINER="user"
USER_IMAGE="user_server"
USER_PORT=8083

echo "========== 删除旧代码 =========="
rm -rf /home/project/demo/*

# 拷贝新代码到应用服务器
echo "========== 拷贝代码 =========="
scp -r ./* /home/project/demo/

# 切换到项目文件夹下
cd /home/project/demo/

echo "========== 项目开始构建打包 =========="
mvn clean package -Dmaven.test.skip=true

echo "========== 拷贝 jar 文件 =========="
mkdir -p /project/demo
\cp -r /home/project/demo/*/target/*server*.jar /project/demo

echo "========== 拷贝 DockerFile 文件 =========="
\cp /home/project/demo/DockerFile /project/demo

# 停止并删除旧的容器
echo "========== 停止并删除旧的容器 =========="
docker ps -a | grep $MQ_CONTAINER && docker stop $MQ_CONTAINER && docker rm $MQ_CONTAINER || echo "mq service not exist"
docker ps -a | grep $WEB_CONTAINER && docker stop $WEB_CONTAINER && docker rm $WEB_CONTAINER || echo "web service not exist"
docker ps -a | grep $USER_CONTAINER && docker stop $USER_CONTAINER && docker rm $USER_CONTAINER || echo "user service not exist"

# 删除旧的镜像
echo "========== 删除旧的镜像 =========="
docker images | grep MQ_IMAGE && docker rmi -f MQ_IMAGE || echo "mq old image not exist"
docker images | grep WEB_IMAGE && docker rmi -f WEB_IMAGE || echo "web old image not exist"
docker images | grep USER_IMAGE && docker rmi -f USER_IMAGE || echo "user old image not exist"

# 构建新的镜像
echo "========== 构建新的镜像 =========="
docker build --build-arg JAR_FILE=mq-server-1.0-SNAPSHOT.jar -t $MQ_IMAGE -f DockerFile /project/demo/
docker build --build-arg JAR_FILE=web-server-1.0-SNAPSHOT.jar -t $WEB_IMAGE -f DockerFile /project/demo/
docker build --build-arg JAR_FILE=user-server-1.0-SNAPSHOT.jar -t $USER_IMAGE -f DockerFile /project/demo/

# 运行镜像容器
echo "========== 运行镜像容器 =========="
docker run -it -d --name $MQ_CONTAINER -p $MQ_PORT:$MQ_PORT $MQ_IMAGE
docker run -it -d --name $WEB_CONTAINER -p $WEB_PORT:$WEB_PORT $WEB_IMAGE
docker run -it -d --name $USER_CONTAINER -p $USER_PORT:$USER_PORT $USER_IMAGE

echo "部署成功"

DockerFile 内容

FROM openjdk:17
ARG JAR_FILE
MAINTAINER cccccc@qq.com # 邮箱
COPY ${JAR_FILE} app.jar
ENV JAVA_OPTS="-Xmx512m -Xms512m -Xmn512m -Xss256K -XX:SurvivorRatio=8 -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=128m -XX:+UseConcMarkSweepGC -XX:ConcGCThreads=4 -XX:+CMSClassUnloadingEnabled -Dfile.encoding=UTF-8 -XX:+DisableExplicitGC -XX:+PrintGC -XX:+PrintGCTimeStamps -Xloggc:./gc.log"
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]

踩坑记录

1. 无法找到 mvn 命令 ( mvn: command not found )

  • Jenkins 构建历史 控制台输出

在这里插入图片描述

  • run.sh 文件, 第46行代码

在这里插入图片描述

  • 服务器项目文件夹下执行 mvn clean package -Dmaven.test.skip=true 可正常打包

  • 原因分析:
    对于java或maven的路径的环境变量是放在/etc/profile中的, 而/etc/profile只有在用户登录的时候才会被load,Jenkins在运行命令时,使用的是Non-login的方式,而这种方式在运行命令时,/etc/profile是不会被load进来的,所以jenkins只能在当前路径下寻找可执行文件

  • 解决方案:
    jenkins (主界面) Dashboard -> (系统管理) Manage Jenkins -> (系统配置) Configure System -> (全局属性) Global Properties -> (环境变量) Environment variables -> (键值对列表) List of variables
    在Jenkins设置全局变量,新增如下内容:

    • JAVA_HOME/usr/java/jdk-17.0.2
    • MAVEN_HOME/usr/local/apache-maven-3.8.4
    • PATH+EXTRA$MAVEN_HOME/bin

JAVA_HOME、MAVEN_HOME 对应的值分别为各自安装目录
PATH+EXTRA 表示 PATH=EXTRA:$PATH, 即扩展当前的PATH变量

在这里插入图片描述

2. 运行失败 ( Exception in thread “main” java.lang.NoClassDefFoundError )

[root@sinolee demo]# docker ps -a
CONTAINER ID   IMAGE                COMMAND                  CREATED              STATUS                          PORTS     NAMES
b7a7addce8bd   user_server            "java -Djava.securit…"   About a minute ago   Exited (1) About a minute ago             es
[root@sinolee linu]# docker logs b7a7addce8bd
Exception in thread "main" java.lang.NoClassDefFoundError: org/springframework/boot/SpringApplication
        at com.test.demo.UserApplication.main(EsApplication.java:14)
Caused by: java.lang.ClassNotFoundException: org.springframework.boot.SpringApplication
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
        at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
        ... 1 more
  • 解决方法 子项目 pom.xml 中新增 build
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.4.11</version>
                <executions>
                    <execution>
                        <id>repackage</id>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

3. 一定要注意 SpringBoot SpringCloud SpringCloudAlibaba 之间的版本, 建议别用新版本, 各依赖之间的 jar 包冲突整的人头皮发麻…

本文采用版本
jdk 17
maven 3.8.4
Spring 5.3.20
SpringBoot 2.6.8
SpringCloud 2021.0.3
SpringCloudAlibaba 2021.1

  • 父项目 pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <artifactId>spring-boot-starter-parent</artifactId>
        <groupId>org.springframework.boot</groupId>
        <version>2.6.8</version>
    </parent>

    <groupId>com.test</groupId>
    <artifactId>demo</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    
    <modules>
        <module>user-service</module>
        <module>web-service</module>
    </modules>

    <properties>
        <java.version>17</java.version>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <spring-cloud-alibaba.version>2021.1</spring-cloud-alibaba.version>
        <spring-cloud.version>2021.0.3</spring-cloud.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <!-- Spring Cloud 依赖 -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <!-- SpringCloudAlibaba 依赖 -->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${spring-cloud-alibaba.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

</project>

ps:如有错误,欢迎批评指正,谢谢!

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 2019年黑马项目-畅购商城springcloud微服务实战是一门以实战为主的课程,旨在通过项目实践的方式,帮助学员深入理解和掌握SpringCloud微服务架构以及相关技术的应用。 课程的主要内容包括搭建基础的微服务架构、使用SpringCloud构建服务注册与发现、实现服务间的负载均衡、实现分布式配置中心、服务间的调用与容错处理、使用网关统一接入服务等。通过这些实战练习,学员不仅能够熟悉SpringCloud架构与组件,还能够了解微服务架构下的常见问题与解决方案。 畅购商城项目是一个典型的电商应用,通过实现该项目,学员可以接触到真实的业务场景与需求,并能够将所学知识应用到实际项目中。课程中通过模块化的方式逐步完善商城的功能,包括用户注册登录、商品浏览、购物车管理、订单生成与支付等。通过这些实践,学员除了掌握SpringCloud微服务的开发技术,还能够了解和掌握电商项目的开发流程和注意事项。 该课程的目标是让学员通过实战项目,全面了解和掌握SpringCloud微服务架构的设计与开发,在此基础上能够独立完成具有较高要求的微服务项目。通过参与实战项目的过程,学员还能够提升团队协作能力、解决问题的能力以及项目管理能力。 通过这门课程的学习,学员将会对SpringCloud微服务架构有更深入的理解,并能够将这些知识应用到实际项目中,提高自己在微服务开发领域的竞争力。 ### 回答2: 2019年黑马项目-畅购商城springcloud微服务实战是一个基于springcloud微服务架构的商城项目。该项目的目标是通过运用微服务的理念和技术,构建一个高可用、可扩展的商城系统。 在该项目中,使用了springcloud的多个组件,如Eureka注册中心、Feign负载均衡、Ribbon客户端负载均衡、Hystrix服务降级和容错、Zuul网关等。这些组件共同协作,实现了系统的弹性伸缩和高可用性。 畅购商城的功能包括商品展示、购物车、订单管理、支付、用户管理等。通过将这些功能拆分成独立的微服务,使得系统更加灵活和可维护。同时,使用分布式事务和消息队列来保障数据的一致性和可靠性。 在项目的开发过程中,采用了敏捷开发的方法,以迭代的方式进行开发和测试。通过使用Jenkins进行持续集成和部署,保证了代码的质量和系统的稳定性。 在项目的实战过程中,面临了许多挑战和困难,如微服务之间的通信、服务的负载均衡、服务的容错等。但通过团队的共同努力和不断的学习,最终成功地完成了该项目的开发和部署。 在该项目的实施过程中,不仅学到了springcloud微服务架构的相关知识和技术,还体会到了团队合作和解决问题的能力。该项目的成功实施,不仅为公司带来了商业价值,也提升了团队的技术水平和项目管理能力。 ### 回答3: 2019年黑马项目-畅购商城springcloud微服务实战是一个以Spring Cloud为基础的微服务项目微服务架构是一种将应用拆分成多个小型服务的架构模式,这些服务可以独立开发、部署、扩展和管理。 畅购商城项目使用了Spring Cloud的一系列子项目,如Eureka、Ribbon、Feign、Hystrix、Zuul等,来实现各个微服务之间的通信、负载均衡、服务降级与熔断等功能。 在项目中,我们会通过Eureka来实现服务的注册与发现,每个微服务都会向Eureka注册自己的地址,其他微服务可以通过Eureka来发现并调用这些服务。而Ribbon则负责实现客户端的负载均衡,可以轮询、随机、加权等方式分发请求。 Feign是一种声明式的HTTP客户端,它简化了服务间的调用方式。我们只需编写接口,并通过注解来描述需要调用的服务和方法,Feign会自动实现远程调用。 Hystrix是一个容错机制的实现,可以通过断路器来实现服务的降级与熔断,当某个服务出现故障或超时时,Hystrix会快速响应并返回一个可控制的结果,从而保证系统的稳定性。 另外,Zuul作为微服务网关,可以实现请求的统一入口和路由转发,提高系统的安全性和性能。 通过这些Spring Cloud的组件,畅购商城项目可以实现高可用、容错、自动扩展等优质的微服务架构。 总之,2019年黑马项目-畅购商城springcloud微服务实战是一个基于Spring Cloud微服务项目,通过使用Spring Cloud的各个子项目,可以实现微服务之间的通信、负载均衡、服务降级与熔断等功能,为项目的开发、部署和管理提供了便利。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

leeindex

感谢您的鼓励~~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值