持续集成之 Spring Boot 实战篇

本文作者: CODING 用户 - 何健

这次实战篇,我们借助「CODING 持续集成」,实现一个简单的 Spring Boot 项目从编码到最后部署的完整过程。本教程还有 B 站视频版,帮助读者更好地学习理解。

思路

在线上环境构建、测试、部署

这种情况,通常会将 jenkins 安装在服务器上,确保构建测试等操作环境和线上环境一致。

此时通常会在 jenkins 中配置好需要持续集成的仓库,以及具体流程。

这种方式非常简单粗暴,也非常有效,但是缺点也很明显。可能 jenkins 会成为线上环境的旁站漏洞,这是非常不安全的。

那么,我们就需要更高级的方式,可以线上环境之外的构建测试,最终部署到线上环境。「CODING 持续集成」正是提供这类持续集成模式的平台。

不在实际部署服务器上构建、测试

为了避免占用线上服务器的资源,也为了避免安全问题,我们可以使用单独的 jenkins (或者其它此类软件)完成构建、测试、分发,实际部署通过单独的 webhook 实现。这样就可以避免在线上环境安装 Jenkins,还可以避免更复杂的系统安全维护。

这样做的优点:不会影响在线服务; 缺点:部署地机器最好是可以公网访问的,否则会无法完成后续分发步骤。

终极解决方案:使用 SaaS 化的 Jenkins

Software as a Service,软件即服务。「CODING 持续集成」集成了 SaaS 化的 Jenkins 等主流企业开发流程工具,实现了 DevOps 流程全自动化。开箱即用,直接用它就好!

捋一下思路

我们这次实战针对后一种思路

  1. 检出代码

  2. 构建

  3. 测试

  4. 分发

  5. 触发部署

实战

实际体验,还是很不错的。

视频地址:CODING 持续集成 - Spring Boot 项目

第一步:初始化一个持续集成

  1. 首先,我们需要进入准备持续集成的项目。

    这里我用 start.spring.io 初始化一个 demo 示例项目,并推送到仓库。 为了方便大家,亲自体验,我准备了一个现成的仓库,可以直接 git clone 下来再 git push 到自己账户下使用。仓库地址:demoForCI

  2. 解压 demo 项目,进入 demo 目录,初始化仓库。

      cd g:\demo\git initgit set remote giturlgit add ./git commit -m 'init repo'git push -u origin master
复制代码

别忘了 git config user.name yournamegit config user.email youremail

  1. 开始体验 仓库准备好后,就可以开始体验「CODING 持续集成」。

    第一次的使用,需要先创建一个 Jenkinsfile,很多小伙伴会说,第一次用,不知道是啥。

    没关系,「CODING 持续集成」已经给我们准备好了模板,非常容易理解,可以认为是特定格式语法写一套 task 流程。

    点击一下 “简易模板”,更具实际情况修改一下就可以。

第二步:编写 Jenkinsfile

为了方便理解,我们从简易模板开始,分别修改对应阶段的任务。

  1. 配置构建环境,「CODING 持续集成」目前支持 java-8、python-3.5、ruby-2.3、go-1.11 等等。 在 Jenkinsfile 的 pipeline 里添加:
    agent {// 此处设定构建环境,目前可选有// default, java-8, python-3.5, ruby-2.3, go-1.11 等// 详情请阅 https://dev.tencent.com/help/knowledge-base/how-to-use-ci#agentslabel "java-8"}
复制代码
  1. 检出 这里不得不说,「CODING 持续集成」这里做的还是很方便的,提供了适用于好几种不同场景的模板。默认简易模板是带有检出部分的,我们可以根据实际情况进行修改。默认情况下,env.GIT_BUILD_REF 的值就是 master 主分支,实际上我们可以定制为其它专门用于构建发的分支。

    这里,大家可以自己修改具体要检出的分支。

    stage("检出") {steps {sh 'ci-init'checkout([$class: 'GitSCM', branches: [[name: env.GIT_BUILD_REF]], userRemoteConfigs: [[url: env.GIT_REPO_URL]]])}}
复制代码
  1. 构建
    stage("构建") {steps {echo "构建中..."sh 'java -version'sh 'mvn package'echo "构建完成."archiveArtifacts artifacts: '**/target/*.jar', fingerprint: true // 收集构建产物}}
复制代码

这里需要注意,Spring Boot 的 pom 中需要添加一个插件。 修改后:

    <plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin><!-- 下面是添加的插件 --><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin</artifactId><version>2.6</version><configuration><skipTests>true</skipTests></configuration></plugin>
复制代码
  1. 测试 这里我偷个懒,只做了单元测试, 没有提取测试报告,大家可以根据实际项目定制这个流程。
    stage("测试") {steps {echo "单元测试中..."sh 'mvn test'echo "单元测试完成."//junit 'target/surefire-reports/*.xml' // 收集单元测试报告的调用过程}}
复制代码
  1. 分发 jar 包到目标服务器 这里比较无奈,我没有单独针对这次演示写部署 jar 包和上传 jar 包的 webhookApi,但是构建好的 jar 包需要要放置到待部署的服务器。

    于是有了这个过程,借助 scp私钥来上传构建好的jar包。

    这里千万记着提前部署好密钥。并且将密钥放到仓库一份,用于分发jar包。

    stage("分发jar包") {steps {echo "分发中..."echo "chmod 600 pkey"sh 'chmod 600 authorized_keys.pem'echo "upload"sh 'scp -i authorized_keys.pem ./target/*.jar root@yourip:/root/'echo "准备部署"}}
复制代码
  1. 部署

    前面有提到,这里部署仍然需要触发一个钩子,否则只能手动部署了。 这里我写了一个最简单的,实际上我们可以写细致一点,判断一下接口返回的结果再根据结果输出部署情况。

    stage("部署") {steps {sh 'curl http://youapi'echo "部署完毕"}}
复制代码

第三步:保存 Jenkinsfile 并运行

修改好 Jenkinsfile 和 pom.xml。

我们要保存 Jenkinsfile,编辑框可以直接编辑内容,编辑好可以直接提交到仓库下的 ./Jenkinsfile

接下来, 平台会自动读取 Jenkinsfile 并开始走持续集成的流程:

持续集成的流程是可以看到的:

每个阶段都对应 Jenkinsfile 一个 stage, 我们可以点击查看对应阶段的构建结果。

第四步:排查持续集成的报错

如果某个过程出错,「CODING 持续集成」的流程会停止,并提示失败。此时我们可以进入具体节点查看具体失败原因。

比如现在是提示“分发 jar 包失败”,那么我们可以点击对应节点展开看看日志,排查具体分发失败的原因。

现在可以清晰地看到,报错原因是我没有填写正确的主机 ip。

文中涉及的文件及代码

Jenkinsfile

pipeline {agent {// 此处设定构建环境,目前可选有// default, java-8, python-3.5, ruby-2.3, go-1.11 等// 详情请阅 https://dev.tencent.com/help/knowledge-base/how-to-use-ci#agentslabel "java-8"}stages  {// 检出仓库stage("检出") {steps {// 这里sh调用ci-init 初始化sh 'ci-init'// 这里检出仓库,默认检出分支为环境变量中的GIT_BUILD_REFcheckout([$class: 'GitSCM', branches: [[name: env.GIT_BUILD_REF]], userRemoteConfigs: [[url: env.GIT_REPO_URL]]])}}// 构建jar包stage("构建") {steps {echo "构建中..."// 输出java版本sh 'java -version'// 调用maven 构建jar包sh 'mvn package'echo "构建完成."//收集构建产物,这一步成功,我们就可以在平台上看到构建产物archiveArtifacts artifacts: '**/target/*.jar', fingerprint: true // 收集构建产物}}// 测试stage("测试") {steps {echo "单元测试中..."// 做单元测试sh 'mvn test'echo "单元测试完成."}}// 分发jar包,这里只是简单的通过scp分发jar包到目标机器指定目录stage("分发jar包") {steps {echo "分发中..."echo "chmod 600 pkey"sh 'chmod 600 authorized_keys.pem'echo "upload"sh 'scp -i authorized_keys.pem ./target/*.jar root@youip:/root/'echo "准备部署"}}// 部署jar包stage("部署") {// 这里需要触发一个部署的webhook,可以是一个很简单的重启java进程的操作steps {// 用curl 来触发hooksh 'curl http://baidu.com'echo "请登录服务器手动部署"}}}
}
复制代码

pom.xml

文中所用 Spring Boot 示例项目的 pom.xml

实际上,大家可以直接去 start.spring.io 参考照这份 pom 来创建一个 demo。

<?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><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.2.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>tech.hejian</groupId><artifactId>codingj8</artifactId><version>0.0.1-SNAPSHOT</version><name>codingj8</name><description>coding project for Spring Boot</description><properties><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin</artifactId><version>2.6</version><configuration><skipTests>true</skipTests></configuration></plugin></plugins></build></project>
复制代码

总结

CODING 是一个面向开发者的云端开发平台,提供 Git/SVN 代码托管、任务管理、在线 WebIDE、Cloud Studio、开发协作、文件管理、Wiki 管理、提供个人服务及企业服务,其中「CODING 持续集成」集成了 SaaS 化的 Jenkins 等主流企业开发流程工具,实现了 DevOps 流程全自动化,为企业提供软件研发全流程管理工具,打通了从团队构建、产品策划、开发测试到部署上线的全过程。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/536834.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java静态工厂方法模式_设计模式:简单工厂模式(静态工厂方法模式)

简单工厂的构成包括三个角色&#xff1a;1)抽象产品类2)具体产品类(继承抽闲产品类)3)工厂类(生产具体产品)具体代码实现1、抽象产品类/*** 抽象类*/public abstract class Car {/*** 产品抽象方法&#xff0c;将会由具体产品类实现*/public abstract void driving();}2、具体产…

Kibana中的Coordinate Map地图报索引错误的问题

今天做地图定位展示&#xff0c;展示的是ApacheWeb服务器的访问日志文件中的来源IP。但是中间出现了报错环节&#xff0c;说是索引不能匹配到geo_point类型&#xff0c;实在是不懂这是在说什么&#xff0c;后来在网站找了方法就解决了。主要报错如下&#xff1a; 报错信息&…

mysql数据库安装在unix_Linux下的数据库二:在Linux/Unix平台安装MySQL

推荐使用RPM工具来进行Linux下的MySQL数据库安装。目前的MySQLrpm安装文件包是在SuSE Linux7.3系统平台上打造而成的&#xff0c;但是在绝大多数支持RPM和glibc的其他Linux平台中也可以进行安装。如果选择通用的RPM安装包&#xff0c;那么RPM将静态链接到Linux的线程中。下面步…

mysql时区设置gmt_将MySQL数据库时区设置为GMT

不,不可能在MySQL实例中更改单个数据库的时区.您可以检索服务器和客户端time_zone设置&#xff1a;SELECT global.time_zone, session.time_zone;您还可以更改整个MySQL实例的客户端时区或时区.但要敏锐地了解现有客户端连接的含义,以及如何解释已存储在实例中的DATETIME和TIME…

javaSE知识点汇总

javaSE知识点汇总Java基础知识精华部分写代码&#xff1a;1&#xff0c;明确需求。我要做什么&#xff1f;2&#xff0c;分析思路。我要怎么做&#xff1f;1,2,3。3&#xff0c;确定步骤。每一个思路部分用到哪些语句&#xff0c;方法&#xff0c;和对象。4&#xff0c;代码实现…

java中412是什么错_HTTP 412 错误 – 先决条件失败 (Precondition failed)

HTTP 412 错误 – 先决条件失败 (Precondition failed)介绍您的 Web 服务器认为&#xff0c;该服务器检测到客户端发送的 HTTP 数据流包括一个没有满足的‘先决条件’规范。HTTP 循环中的 412 错误任何客户端 ( 例如您的浏览器或我们的 CheckUpDown 机器人 ) &#xff0c;都需要…

细谈页面回流与重绘

你将了解到&#xff1a; 什么是回流 什么是重绘 回流何时发生 重绘何时发生 如何避免回流和重绘 复制代码带着上面的问题&#xff0c;我们一探究竟 什么是回流 回流&#xff1a;英文是reflow 当render tree中的一部分(或全部)&#xff0c;因为元素的规模尺寸、布局、隐藏等改变…

安卓 java中改布局_android-选项卡布局中的地图视图throwing,java....

我创建了一个具有选项卡布局的应用程序,单击选项卡后,我将打开一个使用Web视图的新活动.另外另一个选项卡使用地图视图,列表视图,图像视图.现在,我在Samsung Galaxy Y上安装了我的应用程序-运行正常.当我在Samsung Galaxy Tab 2上安装相同的应用程序时,当我第一次打开地图视图,…

怎么样修改PuTTY的默认字体和字符集

1.在窗口标题上点击右键&#xff0c;选择 Change Settings...2.在打开的配置窗口左边选择 Appearance&#xff0c;在右边点 Font settings 里面的 Change 按钮&#xff0c;选择好中文字体&#xff0c;比如&#xff1a;宋体、新宋体之类的3.选择配置窗口左边的 Translation&…

python 元组比较大小_为什么元组比列表更快?

所报道的“build设速度”比率只适用于常量元组(项目用文字表示)。 仔细观察(并在机器上重复 – 只需在shell /命令窗口input命令&#xff01;)…&#xff1a;$ python3.1 -mtimeit -sx,y,z1,2,3 [x,y,z] 1000000 loops, best of 3: 0.379 usec per loop $ python3.1 -mtimeit […

windows软链接的建立及删除

2019独角兽企业重金招聘Python工程师标准>>> 1.建立举例 # 建立d:develop链接目录&#xff0c;指向远程的目标服务器上的e盘的对应目录。 mklink /d d:\develop \\138.20.1.141\e$\develop# 建立d:develop链接目录&#xff0c;指向远程的目标服务器上的e盘的对应目录…

php原生类,反序列化之PHP原生类的利用

正文文章围绕着一个问题&#xff0c;如果在代码审计中有反序列化点&#xff0c;但是在原本的代码中找不到pop链该如何?N1CTF有一个无pop链的反序列化的题目&#xff0c;其中就是找到php内置类来进行反序列化。基础知识首先还是来回顾一下序列化中的魔术方法&#xff0c;下面也…

Spectral Bounds for Sparse PCA: Exact and Greedy Algorithms[贪婪算法选特征]

目录 概括Sparse PCA Formulation非常普遍的问题Optimality ConditionsEigenvalue Bounds算法代码概括 这篇论文&#xff0c;不像以往的那些论文&#xff0c;构造优化问题&#xff0c;然后再求解这个问题&#xff08;一般都是凸化&#xff09;。而是&#xff0c;直接选择某些特…

js php调用webservice,php调用web services两种方法soap和curl

以http://www.webxml.com.cn/zh_cn/index.aspx一、使用soap调用//服务器支持soap扩展:/*Example 1:$client new SoapClient("http://fy.webxml.com.cn/webservices/EnglishChinese.asmx?wsdl");$parameters array("wordKey">"test");//中英…

JS基础-3

1.for in 对象中有多少组键值对,我们的FOR IN 循环就遍历多少次(不一定) 每一次循环KEY这个变量存储的都是当前循环这组键对值的属性名 1、KEY存储的值都是字符串格式的(不管属性名是否为数字) 2、在FOR IN 循环遍历的时候&#xff0c;大部分浏览器都是先把对象中的键值对进行排…

Python常用的几个函数

print()函数&#xff1a;用于打印输出信息到控制台。 input()函数&#xff1a;用于从控制台获取用户输入。 len()函数&#xff1a;用于获取字符串、列表、元组、字典等对象的长度。 range()函数&#xff1a;用于生成一个整数序列&#xff0c;常用于循环中。 type()函数&…

数据结构——常见的定义

问题答案Ο标记法&#xff08;大Ο标记法&#xff09;是一种用于衡量算法时间复杂度的表示方法。它描述了算法在最坏情况下的运行时间增长率。当我们使用Ο标记法时&#xff0c;我们关注的是算法的上界&#xff0c;即算法的运行时间不会超过Ο(f(n))&#xff0c;其中 f(n) 是输…

TikTok与环保:短视频如何引领可持续生活方式?

在数字时代&#xff0c;社交媒体平台扮演着塑造文化和价值观的关键角色。而TikTok&#xff0c;作为一款全球短视频平台&#xff0c;不仅塑造着用户的娱乐方式&#xff0c;还在悄然地引领着可持续生活方式的潮流。本文将深入探讨TikTok与环保之间的关系&#xff0c;分析短视频如…

Spring源码分析---Bean 的生命周期 03

来源&#xff1a;Spring 3. Bean 的生命周期 自定义一个 SpringBoot 的主启动类&#xff1a; SpringBootApplication public class A03Application {public static void main(String[] args) {ConfigurableApplicationContext context SpringApplication.run(A03Applicatio…

go-carbon v2.3.0 圣诞特别版发布,轻量级、语义化、对开发者友好的 Golang 时间处理库

go-carbon v2.3.0 圣诞节特别版发布&#xff0c;这应该是 2023 年的最后一个版本&#xff0c;祝大家圣诞节快乐&#xff01; carbon 是一个轻量级、语义化、对开发者友好的 golang 时间处理库&#xff0c;支持链式调用。 目前已被 awesome-go 收录&#xff0c;如果您觉得不错…