Featured image of post 终于,我还是开始学习 Spring Cloud

终于,我还是开始学习 Spring Cloud

Spring Cloud 的基本概念介绍文章

终于,还是到了该学习Spring Cloud的时间了,其实一直不太愿意学习Spring Cloud,不是因为它有多难,反而觉得它比较简单,上手比较容易,需要了拿来几个例子学学就能上手了。而是觉得,自己本身关于jvmjdk源码、Mybatis源码甚至Spring源码都没有去深入研究和掌握,同时自己实际开发中还没有涉及到微服务相关使用技术,因此不太想浪费时间去掌握一些太表面的东西,然而春节期间看源码看的不太能静下心,同时看到隔壁微服务小组整天左口一个“配置中心”,右口一个“网关”的,想着不如趁最近看看微服务基本概念和使用方法,方便后续有机会了直接上手。

Spring Cloud

微服务

Any organization that designs a system (defined broadly) will produce a design whose structure is a copy of the organization’s communication structure.

– Melvyn Conway, 1967

我们从Melvyn Conway的这句话入手,当我们设计一个系统时,将人员划分为 UI 团队,中间件团队,DBA 团队,那么相应地,软件系统也就会自然地被划分为 UI 界面,中间件系统,数据库。而微服务的划分方法不同,它倾向于围绕业务功能组织进行服务的划分,通过这些服务的组合来形成最终的商业领域的软件,每一个服务中包括用户界面,持久化存储等等,所以每一个小团队也不再像传统的方式进行划分,每一个小团队都需要拥有独立开发一个项目的所有技能。

而这些服务之间,通过消息总线、rpc以及http等方式进行相互通信,以此来构成整个项目。

微服务与分布式

先来说说分布式,分布式侧重系统的部署模式,强调服务部署在不同的机器上,将系统部署在超过一台机器上,且通过各种通讯协议进行交互的设计,就可以算是分布式。所以分布式强调并解决的问题主要是高并发

而微服务则更加强调架构的设计,通过将具有不同职责和功能的应用进行拆分,使得单个服务满足职责单一的设计原则,并在这些原则之上设计出来的系统变可以称做微服务。微服务并没有强调机器数量,可以在一台机器上部署多个服务,只要每一个服务的职责单一即可。所以微服务强调的是职责单一

随着微服务的不断发展,也带动了基于DDD的设计开发模式的发展,所以DDD也逐渐开始成为了设计微服务的最佳实践。

Spring Cloud

前面我们简单介绍了微服务的概念和注意点,我在这里还需要再次说明一下,微服务强调职责单一,强调团队划分。

接下来我们来看看微服务在java中的思想实现结晶 – Spring Cloud

Spring Cloud是一系列框架的集合,它利用Spring Boot的开发便利性简化了分布式系统基础设施的开发,一般来说一个基于Spring Cloud的微服务应用,会具有服务注册发现配置中心消息总线负载均衡熔断器数据监控等功能组成。Spring Cloud针对这些功能通对现有框架的包装,在满足Spring Boot的约定大于配置的基础上,整合出了一套简单易用、易部署、易维护的分布式系统开发包。

图片来源:请回答1994

Spring Cloud组成

我们从分布式系统实现功能角度出发,分析Spring Cloud以及实现类似功能的框架,它们每一个都属于哪一类功能框架。

服务注册发现

传统类rpc框架中,如果我们想要远程调用某个服务,那么我们肯定需要知道目标服务的ip地址和端口,然后在调用者的配置文件中配置好这些端口号和ip地址,然后通过注解的方式获取到这些信息进行调用。

传统.jpg

但是这样的方式可能会出现麻烦,如果目标服务的这些信息出现更改,那么调用者也需要随之更改相关信息,也就是说我们作为调用者会随着被调用者的信息更改而被迫更改某些信息,这是一件十分糟糕的事情。如果仅仅是一两个系统我们况且还可以容忍,但是如果是成百上千的系统都是以这样的方式进行调用,那么将会十分地影响开发和维护的效率,因为调用者完全不应该去关心被调用者的这些信息更改,它只需要这个接口能够通信即可。

为了解决类似这样的问题,有人想到让所有的服务将各自的这些信息都注册到统一平台去,然后让服务调用者通过服务别名去寻找目标服务的信息,再去进行远过程调用,这样就能够满足当目标服务的信息变更的时候,也不会影响到服务调用者,降低了服务与服务之间的耦合性。

微服务.jpg

Spring Cloud中,拥有和实现此功能的框架有Spring Cloud EurekaSpring Cloud ConsulSpring Cloud Zookeeper等。

Spring Cloud Eureka提供在分布式环境下的服务发现和服务注册功能,Eureka主要由服务端和客户端组成,Eureka客户端是一个java客户端,用来简化与服务器的交互、作为轮询负载均衡器,并提供服务的故障切换支持。

Consul是一个支持多数据中心分布式高可用的服务发现和配置共享的服务软件,由 HashiCorp 公司用 Go语言开发,基于 Mozilla Public License 2.0 的协议进行开源。Consul支持健康检查,并允许 HTTPDNS协议调用API存储键值对。Spring Cloud Consul封装了Consul操作,Consul是一个服务发现与配置工具,与Docker容器可以无缝集成。

除了Spring Cloud的注册中心之外,Spring Cloud Zookeeper也是一个用来实现分布式服务注册发现的好工具。Spring Cloud ZookeeperZookeeper的封装,ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是GoogleChubby一个开源的实现,是HadoopHbase的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。

配置中心

了解了上面的注册中心,那么配置中心就很简单了,配置中心主要是用来集中管理集群的配置,这样统一的管理方式可以方便之后的升级的配置。

Spring Cloud Config主要是用来实现该功能的框架,Spring Cloud Config把应用原本放在本地文件的配置抽取出来放在中心服务器,本质是配置信息从本地迁移到云端。从而能够提供更好的管理、发布能力。 Spring Cloud Config分服务端和客户端,服务端负责将git(svn)中存储的配置文件发布成REST接口,客户端可以从服务端REST接口获取配置。但客户端并不能主动感知到配置的变化,从而主动去获取新的配置,这需要每个客户端通过POST方法触发各自的/refresh

除此之外,还有携程的Apollo也提供了集中化管理应用不同环境、不同集群的配置的功能,目前Apollo所提供的功能相对于Spring Cloud Config更加强大。

消息总线

Spring Cloud Bus,分布式消息队列,是对KafkaMQ的封装可与Spring Cloud Config联合实现热部署。

负载均衡

Spring Cloud Ribbon针对Ribbon包装,Ribbon客户端组件提供一系列完善的配置选项,比如连接超时、重试、重试算法等。Ribbon内置可插拔、可定制的负载均衡组件。它是一个基于 HTTPTCP 客户端 的负载均衡的工具。它可以 在客户端 配置 RibbonServerList(服务端列表),使用 HttpClientRestTemplate 模拟http请求,步骤相当繁琐。

Spring Cloud Feign针对netflix-feign的封装,Feign 是在 Ribbon的基础上进行了一次改进,是一个使用起来更加方便的 HTTP 客户端。采用接口的方式, 只需要创建一个接口,然后在上面添加注解即可 ,将需要调用的其他服务的方法定义成抽象方法即可, 不需要自己构建HTTP请求。然后就像是调用自身工程的方法调用,而感觉不到是调用远程方法,使得编写 客户端变得非常容易。

熔断器

熔断机制在任何场景都是十分必要的,为了避免因为单个服务不可用而导致整个系统不可用的雪崩效应出现,熔断机制能够在服务不可用的第一时间内,返回相应的替代结果,而非停留在服务调用过程中,避免问题的出现。

Spring cloud Hystrix 主要就是为了实现熔断的功能,它是netflix-hystrix的封装,Hystrix的主要特性有:

  • 断路由机制

Hystrix Command请求后端服务失败数量超过一定比例(默认50%), 断路器会切换到开路状态(Open)。这时所有请求会直接失败而不会发送到后端服务。 断路器保持在开路状态一段时间后(默认5秒),自动切换到半开路状态(HALF-OPEN),这时会判断下一次请求的返回情况, 如果请求成功, 断路器切回闭路状态(CLOSED),否则重新切换到开路状态(OPEN)。Hystrix的断路器就像我们家庭电路中的保险丝,一旦后端服务不可用,断路器会直接切断请求链,避免发送大量无效请求影响系统吞吐量,并且断路器有自我检测并恢复的能力。

  • Fallback

Fallback相当于是降级操作。对于查询操作,我们可以实现一个fallback方法,当请求后端服务出现异常的时候,可以使用fallback方法返回的值。fallback方法的返回值一般是设置的默认值或者来自缓存。

  • 资源隔离

Hystrix中,主要通过线程池来实现资源隔离。通常在使用的时候我们会根据调用的远程服务划分出多个线程池。例如调用产品服务的Command放入A线程池,调用账户服务的Command放入B线程池。这样做的主要优点是运行环境被隔离开了。这样就算调用服务的代码存在bug或者由于其他原因导致自己所在线程池被耗尽时,不会对系统的其他服务造成影响。但是带来的代价就是维护多个线程池会对系统带来额外的性能开销。如果是对性能有严格要求而且确信自己调用服务的客户端代码不会出问题的话,可以使用Hystrix的信号模式(Semaphores)来隔离资源。

服务网关

1
服务网关 = 路由转发 + 过滤器
  • 路由转发

接收外部请求,转发到后端微服务上去,有点类似Nginx的转发和代理功能。

  • 过滤器

在服务网关处完成一些操作,例如权限校验、限流以及监控等等。有点类似于Spring中的拦截器和过滤器的功能。

单系统开发条件下,这部分功能我们一般都是交给了NginxSpring代为处理,但是在微服务下,如果还是交给这两者进行处理的话,那么就会显得有点乱和重复,在多个系统中会存在重复的过滤功能,而Nginx一般是处于最外层进行路由转发,这里不会涉及到业务逻辑,服务网关中往往会涉及到业务逻辑在其中(请求的url中携带逻辑)。

Spring Cloud GateWay作为Spring官方基于Spring 5.0Spring Boot2.0Project Reactor等技术开发的网关,它的目标是替代Spring Cloud Zuul,旨在提供一种简单而有效的方式来对API进行路由,并为他们提供切面。

总结

本文其实并没有介绍任何框架的使用和操作方式,所以阅读起来可能比较费劲,但是这篇文章的目的也是十分明确,就是为了让我们针对微服务中的一些常见概念进行解释和说明,以及这些概念对应的Spring Cloud中的框架进行说明,期望通过这篇文章的介绍,能够让我们对Spring Cloud有个基本的印象。

Licensed under CC BY-NC-SA 4.0
comments powered by Disqus