spring-cloud-kubernetes 的服务发现和轮询实战 (含熔断)

  • 本文是《spring-cloud-kubernetes 实战系列》的第四篇,主要内容是在 kubernetes 上部署两个应用:Web-Service 和 Account-Service,通过 spring-cloud-kubernetes 提供的注册发现能力,实现 Web-Service 调用 Account-Service 提供的 http 服务;

全文概览

  • 本文由以下段落组成:

  1. 环境信息

  2. 常见的 SpringCloud 注册发现服务一览

  3. 分析 kubernetes 上如何实现服务注册发现

  4. 本章实战源码下载链接

  5. 实战开发 Account-Service 服务(服务提供方)

  6. 实战开发 Web-Service 服务(服务消费方)

  7. 扩容验证 ribbon 轮询能力

  8. 验证熔断能力

环境信息

  • 本次实战的环境和版本信息如下:

  1. 操作系统:CentOS Linux release 7.6.1810

  2. minikube:1.1.1

  3. Java:1.8.0_191

  4. Maven:3.6.0

  5. fabric8-maven-plugin 插件:3.5.37

  6. 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 没有任何关系:

  1. 通过 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>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 2019年黑马项目-畅购商城springcloud微服务实战是一门以实战为主的课程,旨在通过项目实践的方式,帮助学员深入理解和掌握SpringCloud微服务架构以及相关技术的应用。 课程的主要内容包括搭建基础的微服务架构、使用SpringCloud构建服务注册与发现、实现服务间的负载均衡、实现分布式配置中心、服务间的调用与容错处理、使用网关统一接入服务等。通过这些实战练习,学员不仅能够熟悉SpringCloud架构与组件,还能够了解微服务架构下的常见问题与解决方案。 畅购商城项目是一个典型的电商应用,通过实现该项目,学员可以接触到真实的业务场景与需求,并能够将所学知识应用到实际项目中。课程中通过模块化的方式逐步完善商城的功能,包括用户注册登录、商品浏览、购物车管理、订单生成与支付等。通过这些实践,学员除了掌握SpringCloud微服务的开发技术,还能够了解和掌握电商项目的开发流程和注意事项。 该课程的目标是让学员通过实战项目,全面了解和掌握SpringCloud微服务架构的设计与开发,在此基础上能够独立完成具有较高要求的微服务项目。通过参与实战项目的过程,学员还能够提升团队协作能力、解决问题的能力以及项目管理能力。 通过这门课程的学习,学员将会对SpringCloud微服务架构有更深入的理解,并能够将这些知识应用到实际项目中,提高自己在微服务开发领域的竞争力。 ### 回答2: 2019年黑马项目-畅购商城springcloud微服务实战是一个基于springcloud微服务架构的商城项目。该项目的目标是通过运用微服务的理念和技术,构建一个高可用、可扩展的商城系统。 在该项目中,使用了springcloud的多个组件,如Eureka注册中心、Feign负载均衡、Ribbon客户端负载均衡、Hystrix服务降级和容错、Zuul网关等。这些组件共同协作,实现了系统的弹性伸缩和高可用性。 畅购商城的功能包括商品展示、购物车、订单管理、支付、用户管理等。通过将这些功能拆分成独立的微服务,使得系统更加灵活和可维护。同时,使用分布式事务和消息队列来保障数据的一致性和可靠性。 在项目的开发过程中,采用了敏捷开发的方法,以迭代的方式进行开发和测试。通过使用Jenkins进行持续集成和部署,保证了代码的质量和系统的稳定性。 在项目的实战过程中,面临了许多挑战和困难,如微服务之间的通信、服务的负载均衡、服务的容错等。但通过团队的共同努力和不断的学习,最终成功地完成了该项目的开发和部署。 在该项目的实施过程中,不仅学到了springcloud微服务架构的相关知识和技术,还体会到了团队合作和解决问题的能力。该项目的成功实施,不仅为公司带来了商业价值,也提升了团队的技术水平和项目管理能力。 ### 回答3: 2019年黑马项目-畅购商城springcloud微服务实战是一个以Spring Cloud为基础的微服务项目。微服务架构是一种将应用拆分成多个小型服务的架构模式,这些服务可以独立开发、部署、扩展和管理。 畅购商城项目使用了Spring Cloud的一系列子项目,如Eureka、Ribbon、Feign、Hystrix、Zuul等,来实现各个微服务之间的通信、负载均衡、服务降级与熔断等功能。 在项目中,我们会通过Eureka来实现服务的注册与发现,每个微服务都会向Eureka注册自己的地址,其他微服务可以通过Eureka来发现并调用这些服务。而Ribbon则负责实现客户端的负载均衡,可以轮询、随机、加权等方式分发请求。 Feign是一种声明式的HTTP客户端,它简化了服务间的调用方式。我们只需编写接口,并通过注解来描述需要调用的服务和方法,Feign会自动实现远程调用。 Hystrix是一个容错机制的实现,可以通过断路器来实现服务的降级与熔断,当某个服务出现故障或超时时,Hystrix会快速响应并返回一个可控制的结果,从而保证系统的稳定性。 另外,Zuul作为微服务网关,可以实现请求的统一入口和路由转发,提高系统的安全性和性能。 通过这些Spring Cloud的组件,畅购商城项目可以实现高可用、容错、自动扩展等优质的微服务架构。 总之,2019年黑马项目-畅购商城springcloud微服务实战是一个基于Spring Cloud的微服务项目,通过使用Spring Cloud的各个子项目,可以实现微服务之间的通信、负载均衡、服务降级与熔断等功能,为项目的开发、部署和管理提供了便利。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值