基于SpringBoot工程开发Docker化微服务

时间:2022-12-28 09:52:32

目录

1. 微服务容器化治理的优缺点

1.1 微服务容器化的优点

 1.2 微服务容器化的缺点

2. 微服务的两种模式

2.1 Microservice SDK

2.2 ServiceMesh

3. 微服务容器化治理的推荐模式

4.Windows下开发容器化微服务(非K8S)

4.1 开发环境

4.2 代码框架

4.2.1 SpringBoot开发框架

4.2.2 增加docker支持

4.3 运行Docker化的微服务


1. 微服务容器化治理的优缺点

1.1 微服务容器化的优点

       最近一直在研究在项目中推进Docker化的可行性,原来项目组采用的技术栈是SpringCloud,而Docker化带来的价值主要包括以下几个SpringCloud体系所不具备的优势:

  1. 产品的安装部署和版本发布效率会提升。这里的背景是我们的产品主要是需要能够为不同的客户进行本地化部署,而不是目前主要的互联网公司的一个网站的模式。用SpringCloud,则产品的安装部署主要是用自己写安装部署脚本,或开发安装部署工具,较为复杂。
  2. 产品的动态伸缩能力会更强。基于K8S可以实现Docker容器的动态伸缩,而SpringCloud体系实现该能力要难度高一些。
  3. 灰度发布能力会更强。这点SpringCloud也能实现,但是需要借助第三方工具,且相对于K8S,实现起来会比较复杂。
  4. 写代码时可以更聚焦业务,不需要把微服务的治理和业务代码耦合。而SpringCloud体系本身需要业务代码和微服务治理体系耦合,如微服务需要知道Nacos,SpringCloud的SDK中也要求微服务对微服务治理相关的组件要了解,并做好配置。

 1.2 微服务容器化的缺点

       当然,采用全面的Docker化也存在一些缺点:

  1. 第一就是运维成本的升高。采用K8S对微服务进行治理,虽然将业务代码和微服务管理进行了剥离,但是K8S本质上是将微服务管理IaaS化了,所以对K8S运维的要求比较高,对人员技能要求也比较高。
  2. 第二就是这种模式并不太成熟。K8S对微服务的管理,本质上是ServiceMesh模式,而非SpringCloud的Microservice SDK模式。而ServiceMesh模式目前主流的技术方案是Istio+K8S,技术成熟度还不太高。

2. 微服务的两种模式

       刚刚学习Docker和K8S的时候,习惯性的想把SpringCloud的微服务治理体系装到K8S里面。但直觉上一直认为这种模式很别扭,因为K8S也有类似SpringCloud的完整微服务治理体系,如etcd、API Server等。只到后来看到一个华为大神写的文章《最佳实践:从Spring Cloud 到 Istio》(https://zhuanlan.zhihu.com/p/358891699),才恍然大悟:SpringCloud是Microservice SDK模式,K8S时ServiceMesh模式;两者完全是不同的两种设计思想,强行把他们揉到一起,有点儿要把马车和汽车焊在一起的赶脚。

2.1 Microservice SDK

       微服务SDK曾经是一个常用的解决方案。将微服务化后通用的能力封装在一个开发框架中,开发者使用这个框架开发写自己的业务代码,生成的微服务自然就内置了这些能力。这种模式中,业务代码和微服务框架代码是耦合在一起的的。SpringCloud就是这种模式的典型代表,采用SpringCloud框架,业务代码和SpringCloud框架的Nacos、Sentinel、SpringCloud Gateway等是强耦合的,业务代码的Maven工程和SpringCloud的这些工具集是强绑定的。如果后续不采用SpringCloud框架了,那业务代码基本上也要进行大面积的重构。

       这里适当展开一下,SpringCloud本身包含最核心的Spring Framework,和简化配置开发能力的SpringBoot框架,以及SpringCloud框架。

      早期SpringCloud大部分基于Netflix的版本,采用Eureka、Ribbon、Hystrix、Zuul/Zuul2、SpringCloud Config等工具库来实现微服务治理的基本框架。但随着框架的演进,Netflix版本目前已经不再维护了。

       当前业界采用的主要是SpringCloudAlibaba版本,是阿里基于SpringCloud开发的版本,采用Nacos、Sentinel、SpringCloud Gateway等工具实现了微服务治理的基本框架。

       目前SpringCloudAlibaba版本的主要工具库如下图所示。

基于SpringBoot工程开发Docker化微服务

 

2.2 ServiceMesh

       ServiceMesh,也就是常说的服务网格,是通过另一种形态提供治理能力。不同于SDK方式,服务治理的能力在一个独立的代理进程中提供,完全和业务代码开发解耦。从本质上讲,微服务SDK是一种开发框架,而ServiceMesh是一个基础设施。

       当前最流行的ServiceMesh模式是K8S + Istio,采用SideCar模式实现业务代码和服务治理的解耦。

3. 微服务容器化治理的推荐模式

       根据上一章的说明,大家应该可以看到,如果要将微服务容器化,建议大家采用ServiceMesh模式。在该模式下,可以灵活的采用不同的开发语言,如Golang、Node.js、Python、Java等;同时也不需要再绑定SpringCloud等微服务框架,只需要聚焦最核心的业务代码开发既可。

       仍然以Java语言为例,采用ServiceMesh模式,只需要采用Maven + SpringBoot框架开发既可。

4.Windows下开发容器化微服务(非K8S)

       按照前面的总结,我们将采用SpringBoot为开发框架,搭建容器化的微服务环境。

4.1 开发环境

       开发语言:Java

       代码框架:Maven + SpringBoot

       开发工具:VSCode

       开发插件:Extension Pack for Java, Spring Boot Extension Pack, Docker

       Docker环境:Docker Desktop

       K8S环境:利用Docker Desktop中自带的对Kubernetes的支持

基于SpringBoot工程开发Docker化微服务

       具体的安装部署这里不再赘述,大家可以上网搜索。配置国内的Maven库和Docker Registry也不再赘述,大家网上搜索既可。

       这里重点要说一下VSCode真的是很不错的开发环境,微软官方的开发插件对开发效率有极大的提升,上述几个开发插件大家一定要用好。

4.2 代码框架

4.2.1 SpringBoot开发框架

       VSCode的Extension Pack for Java和Spring Boot Extension Pack对SpringBoot的Maven工程创建支持非常好,可以在VSCode中按照引导一步步创建工程即可。

基于SpringBoot工程开发Docker化微服务

        这里建议创建Spring Boot类型的工程,然后再选择Maven类型工程,再按提示选择。

       不建议创建Maven类型的工程,然后再选择SpringBoot类型的archetype。因为这种模式,可选的archetype比较杂,对SpringBoot的版本配置也比较乱,需要手动做不少调整。

4.2.2 增加docker支持

4.2.2.1 pom中增加dockerfile-maven-plugin

       这里用到了dockerfile-maven-plugin插件,来为maven工程增加docker能力的支持。该插件是spotify公司开发的插件,将docker和maven进行了集成,可以在maven工程中,基于Dockerfile的配置,将工程打包成docker镜像,并支持push和tag等功能。具体的pom配置请见下图。

 基于SpringBoot工程开发Docker化微服务

        需要注意的是,该插件的前身是docker-maven-plugin,官方已经声明docker-maven-plugin不再继续演进,建议开发者切换到dockerfile-maven-plugin。目前往上有大量的docker-maven-plugin的教程,需要大家注意不要被误导采用老旧的插件。

4.2.2.2 工程中增加Dockerfile

       在VScode中按F1键,输入Docker: Add Docker File to Workspace,可以在工程中增加Dockerfile。默认增加Dockerfile到根目录,如果手动添加到其他目录,会出现编译错误。

基于SpringBoot工程开发Docker化微服务

       Dockerfile创建后,VSCode的Docker插件会根据Maven工程自动初始化Dockerfile的内容,如下图所示。

基于SpringBoot工程开发Docker化微服务

       这里需要注意的是,Docker镜像打包时,需要有底层OS和JDK的支持,开发人员可以根据自己工程采用的java版本,在hub.docker.com上搜索对应的底层docker依赖,并写到Dockerfile的FROM部分。如上图所示,这里用到的是JDK 19,在hub.docker.com中可以搜到很多版本,这里选择的事openjdk: 19-jdk-alpine。选择openjdk是为了避免被Oracle收费,19-jdk表示jdk 19版本,alpine表示基于alpine的linux,这个版本的linux比较小,占用的资源较少,连同jdk合计185.34MB。

基于SpringBoot工程开发Docker化微服务

       另外,根据工程的需要,刻在Dockerfile中通过EXPOSE port,开放指定端口,以便外部访问。示例工程中开放到是8080端口。

       Dockerfile配置完成后,启动本地的Docker Desktop,再执行Maven编译,可以生成docker image,并自动推送到Docker Desktop。如下图所示:

基于SpringBoot工程开发Docker化微服务

        至此,该工程的docker文件已编译打包完成,并成功push到本地的docker库上。

4.3 运行Docker化的微服务

       基于Docker Desktop可以启动上面创建的微服务的Docker容器,启动时需要配置一下端口映射,将容器暴露的端口映射到本地端口,以便可以通过本地浏览器访问发布的docker服务。具体操作可以用Docker Desktop提供的功能设置。

       如下图所示,选择要运行的image,点击Run按钮。

 基于SpringBoot工程开发Docker化微服务

        在弹出的窗口中可以配置Container name和端口映射,完成后点击Run:

基于SpringBoot工程开发Docker化微服务

       执行Run后,可以在Docker Desktop上看到启动日志,如下图所示,启动正常。

基于SpringBoot工程开发Docker化微服务       Terminal标签是该Container的shell,可以在里面执行shell命令,如下图所示。

 基于SpringBoot工程开发Docker化微服务

(未完待续。。。)