目录
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化的微服务
最近一直在研究在项目中推进Docker化的可行性,原来项目组采用的技术栈是SpringCloud,而Docker化带来的价值主要包括以下几个SpringCloud体系所不具备的优势:
当然,采用全面的Docker化也存在一些缺点:
刚刚学习Docker和K8S的时候,习惯性的想把SpringCloud的微服务治理体系装到K8S里面。但直觉上一直认为这种模式很别扭,因为K8S也有类似SpringCloud的完整微服务治理体系,如etcd、API Server等。只到后来看到一个华为大神写的文章《最佳实践:从Spring Cloud 到 Istio》(https://zhuanlan.zhihu.com/p/358891699),才恍然大悟:SpringCloud是Microservice SDK模式,K8S时ServiceMesh模式;两者完全是不同的两种设计思想,强行把他们揉到一起,有点儿要把马车和汽车焊在一起的赶脚。
微服务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版本的主要工具库如下图所示。
ServiceMesh,也就是常说的服务网格,是通过另一种形态提供治理能力。不同于SDK方式,服务治理的能力在一个独立的代理进程中提供,完全和业务代码开发解耦。从本质上讲,微服务SDK是一种开发框架,而ServiceMesh是一个基础设施。
当前最流行的ServiceMesh模式是K8S + Istio,采用SideCar模式实现业务代码和服务治理的解耦。
根据上一章的说明,大家应该可以看到,如果要将微服务容器化,建议大家采用ServiceMesh模式。在该模式下,可以灵活的采用不同的开发语言,如Golang、Node.js、Python、Java等;同时也不需要再绑定SpringCloud等微服务框架,只需要聚焦最核心的业务代码开发既可。
仍然以Java语言为例,采用ServiceMesh模式,只需要采用Maven + SpringBoot框架开发既可。
按照前面的总结,我们将采用SpringBoot为开发框架,搭建容器化的微服务环境。
开发语言:Java
代码框架:Maven + SpringBoot
开发工具:VSCode
开发插件:Extension Pack for Java, Spring Boot Extension Pack, Docker
Docker环境:Docker Desktop
K8S环境:利用Docker Desktop中自带的对Kubernetes的支持
具体的安装部署这里不再赘述,大家可以上网搜索。配置国内的Maven库和Docker Registry也不再赘述,大家网上搜索既可。
这里重点要说一下VSCode真的是很不错的开发环境,微软官方的开发插件对开发效率有极大的提升,上述几个开发插件大家一定要用好。
VSCode的Extension Pack for Java和Spring Boot Extension Pack对SpringBoot的Maven工程创建支持非常好,可以在VSCode中按照引导一步步创建工程即可。
这里建议创建Spring Boot类型的工程,然后再选择Maven类型工程,再按提示选择。
不建议创建Maven类型的工程,然后再选择SpringBoot类型的archetype。因为这种模式,可选的archetype比较杂,对SpringBoot的版本配置也比较乱,需要手动做不少调整。
4.2.2.1 pom中增加dockerfile-maven-plugin
这里用到了dockerfile-maven-plugin插件,来为maven工程增加docker能力的支持。该插件是spotify公司开发的插件,将docker和maven进行了集成,可以在maven工程中,基于Dockerfile的配置,将工程打包成docker镜像,并支持push和tag等功能。具体的pom配置请见下图。
需要注意的是,该插件的前身是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到根目录,如果手动添加到其他目录,会出现编译错误。
Dockerfile创建后,VSCode的Docker插件会根据Maven工程自动初始化Dockerfile的内容,如下图所示。
这里需要注意的是,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。
另外,根据工程的需要,刻在Dockerfile中通过EXPOSE port,开放指定端口,以便外部访问。示例工程中开放到是8080端口。
Dockerfile配置完成后,启动本地的Docker Desktop,再执行Maven编译,可以生成docker image,并自动推送到Docker Desktop。如下图所示:
至此,该工程的docker文件已编译打包完成,并成功push到本地的docker库上。
基于Docker Desktop可以启动上面创建的微服务的Docker容器,启动时需要配置一下端口映射,将容器暴露的端口映射到本地端口,以便可以通过本地浏览器访问发布的docker服务。具体操作可以用Docker Desktop提供的功能设置。
如下图所示,选择要运行的image,点击Run按钮。
在弹出的窗口中可以配置Container name和端口映射,完成后点击Run:
执行Run后,可以在Docker Desktop上看到启动日志,如下图所示,启动正常。
Terminal标签是该Container的shell,可以在里面执行shell命令,如下图所示。
(未完待续。。。)