SpringBoot 2.3.0 新特性来了,还不快学一波
Spring Boot 2.3 已经发布一个月了,这两天才想起来尝一尝鲜儿。除了常规的升级外,很大部分的升级是针对 Docker 的,让你不得不相信,Docker 容器化微服务已然大势所趋。还没有用过的同学,再不下手就晚了。
此次升级主要包括如下几个方面,接下来就跟着我一起来尝一尝吧。
准备工作
为了说明 Spring Boot 2.3 的新特性,必须创建一个项目,以便试验。
创建一个项目并启动
1、创建一个 Spring Boot 项目,可以到 https://start.spring.io/ 上创建,也可以使用 IDEA 自带的功能创建。选择版本 2.3.1,JDK 还是选择亲爱的 Java 8,引入 Web 和 Actuator 两个依赖包。
![2.jpg 2.jpg](/upload/images/2020/7/bebfca7567ca9607.jpg)
有一点要注意一下,在我写本文的时候,Spring Boot 2.3.1 还不能从中央仓库下载,需要添加 Spring Boot 官方的里程碑仓库。
<repositories>
<repository>
<id>spring-milestone</id>
<name>Spring Milestone Repository</name>
<url>https://repo.spring.io/milestone</url>
</repository>
</repositories>
2、在 pom 文件中引入 Maven 插件
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.3.1.RELEASE</version>
</plugin>
</plugins>
</build>
3、添加一个 Controller,做测试用。
@RestController
public class PlayController {
@GetMapping(value = "play")
public String play(){
return "hey, play with me!";
}
}
4、启动项目
mvn spring-boot:run
5、访问 http://localhost:8080/play,说明项目启动成功
![3.jpg 3.jpg](/upload/images/2020/7/d90ef2c2c1701687.jpg)
更好的 Docker 支持
如果不使用 Docker 呢,那就直接打成 jar
包,使用如下命令
mvn package spring-boot:repackage
![4.jpg 4.jpg](/upload/images/2020/7/a813135c8cf2f34f.jpg)
然后就可以把这个 Jar
包部署到服务器了,当然这个过程可能是用自动化部署工具实现的,不如 jenkins 或者自研系统。
之前 Docker 打包方式
抛开公司(尤其是大厂)里成熟的自动化部署流程不谈,我这里说的是一般性小厂或者是个人项目。
如果你在之前的版本就已经用 Docker 方式,那基本上都是自己写 Dockerfile ,然后自己写脚本使用 Dockerfile 打镜像包,或者使用 Maven
插件,比如 dockerfile-maven-plugin
。
Cloud Native Buildpacks
如果你了解 Dockerfiles 的话,那你肯定了解用 Dockerfiles 构建镜像的过程,需要你创建一个 Dockerfile 文件然后在里面写上构建镜像所需的一系列动作,而 Cloud Native Buildpacks 则无需配置类似的过程文件,很大程度上减轻了开发者的工作,提高了效率。这还不是最重要的,最重要的是它提供了更高层次的抽象能力,使镜像的分层更加清晰,并且合理有效的利用层缓存,这样一来,当我们对应用程序进行修改之后,再次构建镜像时的速度飞快,比如我们的应用只改了几行代码,那当我们使用 Buildpacks 构建镜像时,只需要在应用程序层进行重新构建,其他层使用缓存就可以,也就是只对变化了的层重新构建。
Spring Boot 2.3 Docker 方式
首先要确保你本地已经正常启动了 Docker 服务。
Spring Boot 2.3 官方的 Docker Maven 插件,从此不用再借助第三方了。我们前面创建项目的时候已经引入了这个 Maven 插件。
此插件不仅提供了打镜像包的功能,还有其他的常用功能,比如 run、repackage 等。
![5.jpg 5.jpg](/upload/images/2020/7/9ce30d10583a734f.jpg)
为什么前面要说 Cloud Native Buildpacks 呢,不是跑题啊,是因为 Spring Boot 2.3 生成 Docker 镜像包的方式就是集成了 Cloud Native Buildpacks。
那我们就打个镜像包试一下吧
mvn spring-boot:build-image
你以为马上就能看到成果了吗,还是太年轻。
大中华区开发者怎么了
对于中国的开发者来说,打包这一步不会太顺利,原因大家都很清楚。不出意外的话,应该会出现这样的错误,不出错可能才是意外。
[ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:2.3.1.RELEASE:build-image (default-cli) on project play: Execution default-cli of goal org.springframework.boot:spring-boot-maven-plugin:2.3.1.RELEASE:build-image failed: Docker API call to 'localhost/v1.24/images/create?fromImage=gcr.io%2Fpaketo-buildpacks%2Fbuilder%3Abase-platform-api-0.3' failed with status code 500 "Internal Server Error" and message "Get https://gcr.io/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)" -> [Help 1]
出现这个问题的原因是因为 Buildpacks 调用 Docker API 创建镜像的方法,要访问 https://gcr.io ,从上面 pull 一些基础镜像下来,这是 Google 的 Google Cloud ,是 Google 的容器仓库,然而对于中国的开发者来说,这个地址是 404 的。
所以我们要加个系统级别代理,或者专门为 Docker 配置代理。我是在 Docker 中配置的代理,系统代理的影响太大。我本机安装的是 Docker Desktop,直接打开设置,在里面加上代理就可以了(别问我代理怎么搞,问我就是没有代理)。
好了,通过上面一顿猛如虎的操作,再次运行命令
mvn spring-boot:build-image
根据你的网速,等上一段时间,就会出现下面的结果,说明镜像创建成功了。
之后你可以使用 docker images
命令查看。这时间也是醉了,40 years ago。
![8.jpg 8.jpg](/upload/images/2020/7/a5202267e5b35f48.jpg)
使用此镜像启动容器
使用命令直接启动容器。
docker run -it -p8080:8080 play:0.0.1-SNAPSHOT
然后访问 8080 端口,得到正确的返回结果,说明启动成功了。
![9.jpg 9.jpg](/upload/images/2020/7/c4f70a31962e2f48.jpg)
Docker Image 的一个特点是,每个层都是前一层变化的增量。有一个工具叫做 dive,可以清楚的查看分层结构里面包含的内容。具体安装和使用请自行搜索。
使用 dive 查看的一个小技巧,因为镜像层包含的指令很多,所以我们选择只查看相对于上一层的增量内容,使用 Ctrl+L
组合键。
Tab
进入视图,然后按 Ctrl+U
,去掉没有更改的选项,也就是只看变化的部分。然后上下箭头可以切换层查看,比如下面这个图展示了一个 18 M 的层相对于上一层的变化内容,可以看出来这个层实际上就是应用程序层,包含了很多当前应用程序的类和第三方依赖包等。