-
本文是《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,如下所示:
public List<Server> getUpdatedListOfServers() {//用namespace和serviceId做条件,得到该服务对应的所有节点(endpoints)信息Endpoints endpoints = this.namespace != null? this.client.endpoints().inNamespace(this.namespace).withName(this.serviceId).get(): this.client.endpoints().withName(this.serviceId).get();List<Server> result = new ArrayList<Server>();if (endpoints != null) {if (LOG.isDebugEnabled()) {LOG.debug("Found [" + endpoints.getSubsets().size()+ "] endpoints in namespace [" + this.namespace + "] for name ["+ this.serviceId + "] and portName [" + this.portName + "]");}//遍历所有的endpoint,取出IP地址和端口,构建成Server实例,放入result集合中for (EndpointSubset subset : endpoints.getSubsets()) {if (subset.getPorts().size() == 1) {EndpointPort port = subset.getPorts().get(FIRST);for (EndpointAddress address : subset.getAddresses()) {result.add(new Server(address.getIp(), port.getPort()));}}else {for (EndpointPort port : subset.getPorts()) {if (Utils.isNullOrEmpty(this.portName)|| this.portName.endsWith(port.getName())) {for (EndpointAddress address : subset.getAddresses()) {result.add(new Server(address.getIp(), port.getPort()));}}}}}}else {LOG.warn("Did not find any endpoints in ribbon in namespace ["+ this.namespace + "] for name [" + this.serviceId+ "] and portName [" + this.portName + "]");}return result;}
复制代码
-
理论分析已经完成,接下来就开始实战吧
源码下载
-
如果您不打算写代码,也可以从 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 内容如下:
<?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.1.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.bolingcavalry</groupId><artifactId>account-service</artifactId><version>0.0.1-SNAPSHOT</version><name>account-service</name><description>Demo project for Spring Cloud service provider run in kubernetes</description><properties><java.version>1.8</java.version><spring-boot.version>2.1.1.RELEASE</spring-boot.version><maven-checkstyle-plugin.failsOnError>false</maven-checkstyle-plugin.failsOnError><maven-checkstyle-plugin.failsOnViolation>false</maven-checkstyle-plugin.failsOnViolation><maven-checkstyle-plugin.includeTestSourceDirectory>false</maven-checkstyle-plugin.includeTestSourceDirectory><maven-compiler-plugin.version>3.5</maven-compiler-plugin.version><maven-deploy-plugin.version>2.8.2</maven-deploy-plugin.version><maven-failsafe-plugin.version>2.18.1</maven-failsafe-plugin.version><maven-surefire-plugin.version>2.21.0</maven-surefire-plugin.version><fabric8.maven.plugin.version>3.5.37</fabric8.maven.plugin.version><springcloud.version>2.1.1.RELEASE</springcloud.version></properties><dependencyManagement><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependenc

本文介绍了如何在Kubernetes环境中使用spring-cloud-kubernetes进行服务注册和发现,通过Ribbon实现负载均衡。实战内容包括开发和部署Account-Service和Web-Service,展示在Kubernetes上实现微服务间的调用,并验证了服务扩容后的轮询能力和熔断机制。
最低0.47元/天 解锁文章
923

被折叠的 条评论
为什么被折叠?



