spring-cloud-kubernetes 的服务发现和轮询实战 (含熔断)
欢迎访问我的 GitHub
这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos
本文是《spring-cloud-kubernetes 实战系列》的第四篇,主要内容是在 kubernetes 上部署两个应用:Web-Service 和 Account-Service,通过 spring-cloud-kubernetes 提供的注册发现能力,实现 Web-Service 调用 Account-Service 提供的 http 服务;
全文概览
本文由以下段落组成:
环境信息
常见的 SpringCloud 注册发现服务一览
分析 kubernetes 上如何实现服务注册发现
本章实战源码下载链接
实战开发 Account-Service 服务(服务提供方)
实战开发 Web-Service 服务(服务消费方)
扩容验证 ribbon 轮询能力
验证熔断能力
环境信息
本次实战的环境和版本信息如下:
操作系统:CentOS Linux release 7.6.1810
minikube:1.1.1
Java:1.8.0_191
Maven:3.6.0
fabric8-maven-plugin 插件:3.5.37
spring-cloud-kubernetes:1.0.1.RELEASE
上面的 linux、minikube、java、maven,请确保已准备好,linux 环境下 minikube 的安装和启动请参考《Linux 安装 minikube 指南 》。
常见的 SpringCloud 注册发现服务一览
SpringCloud 环境最重要的功能是注册发现服务,因此将 SpringCloud 应用迁移到 kubernetes 环境时,开发者最关心的问题是在 kubernetes 上如何将自身服务暴露出去,以及如何调用其他微服务。
先看看普通 SpringCloud 环境下的注册发现,下图来自 spring 官方博客,地址是:https://spring.io/blog/2015/07/14/microservices-with-spring,
由上图可见,应用 Account-Service 将自己注册到 Eureka,这样 Web-Service 用"account-service"就能在 Eureka 找到 Account-Service 服务的地址,然后顺利发送 RestFul 请求到 Account-Service,用上其提供的服务。
分析 kubernetes 上如何实现服务注册发现
如果将上面的 Web-Service 和 Account-Service 两个应用迁移到 kubernetes 上之后,注册发现机制变成了啥样呢?
第一种:沿用上图的方式,将 Eureka 也部署在 kubernetes 上,这样的架构和不用 kubernetes 时没有啥区别;
第二种,就是今天要实战的内容,使用 spring-cloud-kubernetes 框架,该框架可以调用 kubernetes 的原生能力来为现有 SpringCloud 应用提供服务,架构如下图所示:
上图表明,Web-Service 应用在调用 Account-Service 应用的服务时,会用 okhttp 向 API Server 请求服务列表,API Server 收到请求后会去 etcd 取数据返回给 Web-Service 应用,这样 Web-Service 就有了 Account-Service 的信息,可以向 Account-Service 的多个 Pod 轮询发起请求;
上图有个细节请注意:WebService 应用并不是直接将请求发送给 Account-Service 在 kubernetes 创建的 service,而是直接发送到具体的 Pod 上了,之所以具有这个能力,是因为 spring-cloud-kubernetes 框架通过 service 拿到了 Account-Service 对应的所有 Pod 信息(endpoint),此逻辑可以参考源码 KubernetesServerList.java,如下所示:
理论分析已经完成,接下来就开始实战吧
源码下载
如果您不打算写代码,也可以从 GitHub 上下载本次实战的源码,地址和链接信息如下表所示:
这个 git 项目中有多个文件夹,本章的 Account-Service 源码在 spring-cloud-k8s-account-service 文件夹下,Web-Service 源码在 spring-cloud-k8s-web-service 文件夹下,如下图红框所示:
下面是详细的编码过程;
开发和部署 Account-Service 服务
Account-Service 服务是个很普通的 springboot 应用,和 spring-cloud-kubernetes 没有任何关系:
通过 maven 创建一个 springboot 应用,artifactId 是 account-service,pom.xml 内容如下:
由上面的 pom.xml 内容可见,account-service 应用是个简单的 web 应用,和 SpringCloud、spring-cloud-kubernetes 都没有任何关系,和其他 springboot 唯一的不同就是用到了 fabric8-maven-plugin 插件,可以方便的将应用部署到 kubernetes 环境;
application.yml 内容如下,依旧很简单:
对外提供服务的是 AccountController ,方法 getName 返回了当前容器的 hostname,方法 health 用于响应 kubernetes 的两个探针,方法 ribbonPing 用于响应使用了 ribbon 服务的调用方,它们会调用这个接口来确定当前服务是否正常:
将上述工程的源码放在 minikube 机器上,确保 maven 设置正常,然后在 pom.xml 文件所在目录执行以下命令,即可编译构建工程并部署到 kubernetes 上:
执行成功后控制台输出如下:
检查 kubernetes 上的部署和服务是否正常:
minikube 的 service 命令可以得到指定服务的访问地址:
可见 account-service 的服务可以通过这个 url 访问:http://192.168.121.133:32596
用浏览器访问地址:http://192.168.121.133:32596/name ,如下图所示,可以正常访问 account-service 提供的服务:
现在 account-service 服务已经就绪,接下来是开发和部署 web-service 应用。
开发和部署 Web-Service 服务
Web-Service 服务是个 springboot 应用,用到了 spring-cloud-kubernetes 提供的注册发现能力,以轮询的方式访问指定服务的全部 pod:
通过 maven 创建一个 springboot 应用,artifactId 是 web-service,pom.xml 内容如下,要重点关注的是 spring-cloud-starter-kubernetes-ribbon 的依赖:
application.yml 的内容如下,增加了熔断的配置:
创建一个 ribbon 的配置类 RibbonConfiguration:
应用启动类如下,注意增加了服务发现、熔断、ribbon 的配置,还定义了 restTemplte 实例,注意 @LoadBalanced 注解:
远程调用 account-service 的 http 接口的逻辑被放进服务类 AccountService 中,注意 URL 中用的是服务名 account-service:
最后是响应 web 请求的 WebServiceController 类,这里面调用了 AccountService 的服务,这样我们从 web 发起请求后,web-service 就会远程调用 account-service 的服务:
将上述工程的源码放在 minikube 机器上,确保 maven 设置正常,然后在 pom.xml 文件所在目录执行以下命令,即可编译构建工程并部署到 kubernetes 上:
执行成功后控制台输出如下:
检查 kubernetes 上的部署和服务是否正常:
minikube 的 service 命令可以得到指定服务的访问地址:
可见 web-service 的服务可以通过这个 url 访问:http://192.168.121.133:30519
用浏览器访问地址:http://192.168.121.133:30519/account ,如下图所示,页面上展示的内容都是 web-service 调用了 account-service 的接口返回的,证明 kubernetes 上的注册发现能力正常:
扩容验证 ribbon 轮询能力
虽然 web-service 可以正常调用 account-service 的服务,但始终访问的是一个 pod,接下来我们就对 account-service 的 pod 进行扩容,将数量调整为 2 个,看看 web-service 是否可以轮询调用每个 account-service 的 pod:
执行以下命令即可将 pod 数量调整为 2 个:
2. 检查 account-service 的 pod,发现已经有两个了(account-service-5554576647-m29xr 和 account-service-5554576647-zwwml):
用浏览器访问地址:http://192.168.121.133:30519/account ,如下图所示,account-sercice 返回的 hostname 已经变成了两种,和前面查到的 pod 的 name 一致,可见 web-service 的确是通过 ribbon 轮询访问了多个 account-service 的 pod:
验证熔断能力
接下来验证 web-service 配置的熔断服务是否可以生效:
执行以下命令将 account-service 的 deployment 删除:
再浏览器访问地址:http://192.168.121.133:30519/account ,如下图所示,页面上的"Fallback"是配置的熔断方法返回的内容,可见熔断配置已经生效:
3. 再回到 web-service 的 pom.xml 所在位置执行以下命令,这样会重新构建部署一次 web-service 服务:
再浏览器访问地址:http://192.168.121.133:30519/account ,如下图所示,服务成功恢复:
至此,spring-cloud-kubernetes 的服务发现和轮询实战(含熔断)就全部完成了,利用 API Server 提供的信息,spring-cloud-kubernetes 将原生的 kubernetes 服务带给了 SpringCloud 应用,帮助传统微服务更好的融合在 kubernetes 环境中,如果您也在考虑将应用迁移到 kubernetes 上,希望本文能给您一些参考。
欢迎关注 InfoQ:程序员欣宸
版权声明: 本文为 InfoQ 作者【程序员欣宸】的原创文章。
原文链接:【http://xie.infoq.cn/article/9aab527d7142c9f7727b5765c】。文章转载请联系作者。
评论