作者|北蔡
引用 ThoughtWorks 公司的首席科学家 Martin Fowler 的一段话:简而言之,微服务架构风格是一种将单个应用程序作为一套小型服务开发的方法,每种应用程序都在自己的进程中运行,并与轻量级机制(通常是HTTP资源API)进行通信。这些服务是围绕业务功能构建的,可以通过全自动部署机制独立部署。这些服务的集中管理最少,可以用不同的编程语言编写,并使用不同的数据存储技术。说到微服务,就要从单体服务开始,很多应用初期,都是单体应用,因为初期讲究迭代速度,人员也很少,没有那么清晰的业务划分和边界,从敏捷开发的角度,单体服务是最适合初期的。但随着业务发展,业务越来越复杂,单体应用由于部署在一个进程里面,修改一个小功能,上线就会影响其他功能。随后系统逐步开始拆分:从数据库到应用,微服务就开始登场了。
什么是Spring Cloud ?
Spring Cloud是一个微服务框架,相比Dubbo等RPC框架, Spring Cloud提供全套的分布式系统解决方案,它依赖于 Spring Boot ,有快速开发、持续交付和容易部署等特点。
Spring Cloud不像其他Spring子项目那样相对独立,它是一个拥有诸多子项目的大型综合项目。
Spring Cloud有很多组件。
下面可以看下一个由Spring Cloud组成的架构图:
这里包含的Spring相关组件,有这些,下面一一介绍一下。
服务注册和发现组件 Eureka
介绍
利用 Eureka 组件可以很轻松地实现服务的注册和发现功能。Eureka 组件提供了服务的健康监测,以及界面友好的 UI 。通过 Eureka 组件提供的 UI,Eureka 组件可以让开发人员随时了解服务单元的运行情况。另外 Spring Cloud 也支持 Consul 和Zookeeper ,用于注册和发现服务。
Eureka原理
Eureka Server:服务注册中心。Eureka Server本身也集成了Eureka Client,彼此通过Eureka Client同步数据给其它实例又或者从其他实例同步数据。包含功能:服务剔除。
Application Service:服务提供者。包含功能:服务注册,服务同步,服务续约,服务下线。
Application Client:服务消费者。包含功能:获取服务,服务调用。
Make Remote Call:RESTful API的调用
us-east-1c,us-east-1d:表示一个集群。
- CP VS AP
CAP原则又称CAP定理,指的是在一个分布式系统中,一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)。CAP 原则指的是,这三个要素最多只能同时实现两点,不可能三者兼顾。CAP理论提出就是针对分布式数据库环境的,所以,P这个属性是必须具备的。Eureka保证AP,zookeeper保证CP。zookeeper通过zab协议维持强一致性,服务注册相对Eureka会慢一些,要求过半数节点都写入成功才认为注册成功,Leader挂掉时,需要重新选举,整个集群不可用。Eureka为了实现更高的服务可用性,牺牲了一定的一致性。
客户端负载均衡 Spring Cloud Ribbon
- 介绍
Spring Cloud Ribbon是一个基于HTTP和TCP的客户端负载均衡工具,它基于Netflix Ribbon实现,可以将面向服务的REST模板请求自动转换成客户端负载均衡的服务调用。
- 使用
在Spring Cloud中,当Ribbon与Eureka配合使用时,Ribbon可自动从Eureka Server获取服务提供者地址列表,并基于负载均衡算法,选择其中一个服务提供者实例。
- 架构
- RestTemplate
RestTemplate实现了对HTTP请求的封装处理,形成了一套模板化的调用方式。
- 几种负载均衡策略
- RandomRule:随机选取负载均衡策略,随机Random对象,在所有服务实例中随机找一个服务的索引号,然后从上线的服务中获取对应的服务。
- RoundRobinRule:线性轮询负载均衡策略。
- WeightedResponseTimeRule:响应时间作为选取权重的负载均衡策略,根据平均响应时间计算所有服务的权重,响应时间越短的服务权重越大,被选中的概率越高。刚启动时,如果统计信息不足,则使用线性轮询策略,等信息足够时,再切换到WeightedResponseTimeRule。
- RetryRule:使用线性轮询策略获取服务,如果获取失败则在指定时间内重试,重新获取可用服务。
- ClientConfigEnabledRoundRobinRule:默认通过线性轮询策略选取服务。通过继承该类,并且对choose方法进行重写,可以实现更多的策略,继承后保底使用RoundRobinRule策略。
- BestAvailableRule:继承自ClientConfigEnabledRoundRobinRule。从所有没有断开的服务中,选取到目前为止请求数量最小的服务。
- PredicateBasedRule:抽象类,提供一个choose方法的模板,通过调用AbstractServerPredicate实现类的过滤方法来过滤出目标的服务,再通过轮询方法选出一个服务。
- AvailabilityFilteringRule:按可用性进行过滤服务的负载均衡策略,会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,还有并发的连接数超过阈值的服务,然后对剩余的服务列表进行线性轮询。
- ZoneAvoidanceRule:本身没有重写choose方法,用的还是抽象父类PredicateBasedRule的choose。
一般情况,选择默认的就可以了。
▐ 声明式服务调用 Spring Cloud Feign
- 介绍
Feign是一个声明式的 Web Service 客户端,只需要创建一个接口,并加上对应的 Feign Client 注解,即可进行远程调用。
- 特性
- 可插拔的注解支持
- 可插拔的 HTTP 编码器、解码器
- 支持 Hystrix 断路器、Fallback
- 支持 Ribbon 负载均衡
- 支持 HTTP 请求、响应压缩
▐ 熔断组件 Spring Cloud Hystrix
- 介绍
Hystrix是Netflix开源的一款容错框架,包含常用的容错方法。在高并发访问下,系统所依赖的服务的稳定性对系统的影响非常大,依赖有很多不可控的因素,比如网络连接变慢,资源突然繁忙,暂时不可用,服务脱机等。Hystrix利用熔断、线程池隔离、信号量隔离、降级回退等方法来处理依赖隔离,使系统变得高可用。
- 线程池VS信号量
相对于其他的熔断器,Hystrix可以采用线程池来做隔离,好处是通过将发送请求线程与执行请求的线程分离,可有效防止发生级联故障,但是弊端是就是它增加了计算的开销,每个业务请求(被包装成命令)在执行的时候,会涉及到请求排队,调度和上下文切换。而且他的线程池是针对每个服务,所以服务较多的场景下,那就会有很多个线程池,这也增加了系统本身的开销。
▐ 服务网关 Spring Cloud Gateway
- 介绍
Spring Cloud Gateway是Spring官方推出的服务网关的实现框架,相对于服务网关的概念有点类似于传统的反向代理服务器(如nginx),但反向代理一般都只是做业务无关的转发请求,而服务网关与服务的整合程度更高,可以看作也是整个服务体系的组成部分,通过过滤器等组件可以在网关中集成一些业务处理的操作(比如权限认证等)。
- 核心概念
- Route: 负责将某个外部请求路由到一个合适的地址,包含一个ID,一个目标地址,一系列的Predicate和Filter;
- Predicate: 基于Java 8 Function Predicate的断言机制,用于将请求匹配到某一个Route
- Filter: 类似于Servlet filter,可以在请求传递给下一级处理器之前对请求或响应进行修改,用于实现权限验证,日志记录,限流等功能
- 原理图
Gateway Client发送请求给Spring Cloud Gateway,Gateway Handler Mapping会判断请求的路径是否匹配路由的配置,如果匹配则会进入Gateway Web Handler,Web Handler会读取路由上所配置的过滤器,然后将该请求交给过滤器去处理,最后转发到路由配置的微服务。
▐ 消息驱动的微服务 Spring Cloud Stream
- 介绍
Spring Cloud Stream是一个用来为微服务应用构建消息驱动能力的框架。
- 特点
- 屏蔽底层 MQ 实现细节,Spring Cloud Stream 的 API 是统一的。如果从 Kafka 切到 RocketMQ,可以直接修改配置。
- 与 Spring 生态整合更加方便。Spring Cloud Data Flow的流计算都是基于 Spring Cloud Stream;Spring Cloud Bus 消息总线内部也是用的 Spring Cloud Stream。
Spring Mesh 下一代的Spring Cloud
▐ 介绍
根据Linkerd CEO William Morgan定义,Service Mesh是用于处理服务间通信的基础设施层,用于在云原生应用复杂的服务拓扑中实现可靠的请求传递。在实践中,Service Mesh通常是一组与应用一起部署,但对应用透明的轻量级网络代理。目前集团也有很多落地的场景,蚂蚁金服在双11大规模落地了 SOFAMosn,阿里巴巴在双11的部分电商核心应用上落地了完整的 Service Mesh 解决方案,可以侧面说明这块的确是未来的发展趋势。目前比较流行的开源软件 Istio 和 Linkerd 都是Service Mesh的实现。
▐ 架构
Service Mesh,它将分布式服务的通信抽象为单独一层,在这一层中实现负载均衡、服务发现、认证授权、监控追踪、流量控制等分布式系统所需要的功能,作为一个和服务对等的代理服务,和服务部署在一起,接管服务的流量,通过代理之间的通信间接完成服务之间的通信请求。替换的组件包括网关(gateway或者Zuul,由Ingress gateway或者egress替换),熔断器(hystrix,由SideCar替换),注册中心(Eureka及Eureka client,由Polit,SideCar替换),负责均衡(Ribbon,由SideCar替换),链路跟踪及其客户端(Pinpoint及Pinpoint client,由SideCar及Mixer替换)。
▐ 优点
- 屏蔽分布式系统通信的复杂性(负载均衡、服务发现、认证授权、监控追踪、流量控制等等),服务只用关注业务逻辑;
- 真正的语言无关,服务可以用任何语言编写,只需和Service Mesh通信即可;
- 对应用透明,Service Mesh组件可以单独升级;
推荐学习书籍
- 《Spring Cloud 微服务实战》:这本书比较初级,适合大概了解一下所有组件的实用方式。
- 《分布式服务架构》:虽然不是Spring Cloud的,不过有不少分布式的实战案例,也比较推荐。