Spring Cloud 是一个相对比较新的微服务框架,2016 年才推出 1.0 的 release 版本. 虽然 Spring Cloud 时间最短, 但是相比 Dubbo 等 RPC 框架, Spring Cloud 提供的全套的分布式系统解决方案。
Spring Cloud 是一系列框架的有序集合。它利用 Spring Boot 的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用 Spring Boot 的开发风格做到一键启动和部署。
Spring 并没有重复制造轮子,它只是将目前各家公司(主要是 Netflix )开发的比较成熟、经得起实际考验的服务框架组合起来,通过 Spring Boot 风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。
Eureka 是 Spring Cloud 微服务架构中的注册中心,专门负责服务的注册与发现,里面有一个注册表,保存了各个服务器的 机器和端口。
Eureka Server 的高可用实际上就是将自己作为服务向其他注册中心注册自己,这样就可以形成一组互相注册的服务注册中心,以实现服务清单的互相同步,达到高可用效果。
Zuul 网关负责转发请求给对应的服务,这个组件是负责网络路由的。
Spring Cloud Zuul 通过与 Spring Cloud Eureka 进行整合,将自身注册为 Eureka 服务治理下的应用,同时从 Eureka 中获得了所有其他微服务的实例信息
对于路由规则的维护,Zuul 默认会将通过以服务名作为 ContextPath 的方式来创建路由映射
Zuul 提供了一套过滤器机制,可以支持在 API 网关无附上进行统一调用来对微服务接口做前置过滤,已实现对微服务接口的拦截和校验
提供云端负载均衡,有多种负载均衡策略可供选择,可配合服务发现和断路器使用。
Ribbon 是一个基于 HTTP 和 TCP 的客户端负载均衡器,它可以在通过客户端中配置的 ribbonServerList 服务端列表去轮询访问以达到服务均衡的作用。
当 Ribbon 和 Eureka 联合使用时,Ribbon 的服务实例清单 RibbonServerList 会被 DiscoveryEnabledNIWSServerList 重写,扩展成从 Eureka 注册中心中获取服务端列表。同时它也会用 NIWSDiscoveryPing 来取代 IPing,它将职责委托给 Eureka 来去定服务端是否已经启动
在客户端负载均衡中,所有客户端节点都维护着自己要访问的服务端清单,而这些服务端的清单来自于服务注册中心(比如 Eureka)。在客户端负载均衡中也需要心跳去维护服务端清单的健康性,只是这个步骤需要与服务注册中心配合完成。
通过 Spring Cloud Ribbon 的封装,我们在微服务架构中使用客户端负载均衡调用只需要如下两步:
熔断器,容错管理工具,旨在通过熔断机制控制服务和第三方库的节点,从而对延迟和故障提供更强大的容错能力。提供线程池不同的服务走不同的线程池,实现了不同服务调用的隔离,避免了服务器雪崩的问题。
在微服务架构中,存在着那么多的服务单元,若一个单元出现故障,就很容易因依赖关系而引发故障的蔓延,最终导致整个系统的瘫痪,这样的架构相较传统架构更加不稳定。为了解决这样的问题,产生了断路器等一系列的服务保护机制
在分布式架构中,当某个服务单元发生故障之后,通过断路器的故障监控,向调用方返回一个错误响应,而不是长时间的等待。这样就不会使得线程因调用故障服务被长时间占用不释放,避免了故障在分布式系统中的蔓延
Hystrix 具备服务降级、服务熔断、线程和信号隔离、请求缓存、请求合并以及服务监控等强大功能
Hystrix 使用舱壁模式实现线程池的隔离,它会为每一个依赖服务创建一个独立的线程池,这样就算某个依赖服务出现延迟过高的情况,也只是对该依赖服务的调用产生影响,而不会拖慢其他的依赖服务
基于动态代理机制,根据注解和选择的机器,拼接请求 url 地址,发起请求。Feign 的关键机制是使用了动态代理
Feign 是和 Ribbon 以及 Eureka 紧密协作的
配置管理工具包,让你可以把配置放到远程服务器,集中化管理集群配置,目前支持本地存储、Git 以及 Subversion。
微服务网关更多是在前后端分离,或者说涉及到独立的类似手机 APP 等前端应用的时候使用的最多,即把内部各个微服务组件模块的 API 接口能力统一注册和接入到网关,对于 APP 也只需要访问网关暴露的接口即可,同时通过网关还可以进一步的实现安全隔离。
也就是说在这种场景下,网关更多的是实现了接口服务的代理和路由转发能力,更多的是向外的一种能力发布。
服务发现是一个古老的话题,当应用开始脱离单机运行和访问时,服务发现就诞生了。目前的网络架构是每个主机都有一个独立的 IP 地址,那么服务发现基本上都是通过某种方式获取到服务所部署的 IP 地址。DNS 协议是最早将一个网络名称翻译为网络 IP 的协议,在最初的架构选型中,DNS+LVS+Nginx 基本可以满足所有的 RESTful 服务的发现,此时服务的 IP 列表通常配置在 Nginx 或者 LVS。后来出现了 RPC 服务,服务的上下线更加频繁,人们开始寻求一种能够支持动态上下线并且推送 IP 列表变化的注册中心产品。
这是一款经典的服务注册中心产品(虽然它最初的定位并不在于此),在很长一段时间里,它是国人在提起 RPC 服务注册中心时心里想到的唯一选择,这很大程度上与 Dubbo 在中国的普及程度有关。
Nacos 是阿里巴巴旗下的开源项目,在 2018 年开源,携带着阿里巴巴大规模服务生产经验,试图在服务注册和配置管理这个市场上,提供给用户一个新的选择。
值得一提的是,Nacos 作为配置中心的持久化机制可以依赖于 Mysql 来完成(默认依赖于内置数据库)。只需要将 Nacos 目录下的 sql 脚本放到 mysql 中执行(会生成 11 个表),然后在 nacos 配置文件里面配一下 mysql 的账号密码即可。这样使用 mysql 作为数据源的方式相比于 nacos 内置数据库来说更容易管理
Consul 是 HashiCorp 公司推出的一个开源工具。
对比 SpringCloud,Kubernetes 也提供完整的分布式微服务管理框架,几乎所有组件都有对应的产品,其中 Etcd 也可以提供类似 Eureka 的注册中心。
在 Go 生态中,还可以选择基于 Etcd 作为注册中心,Etcd 是由 CoreOS 团队维护的、高可用分布式键值存储数据库,可用于为集群提供配置和服务发现功能,Google 开源的容器管理工具 Kuberbetes 就是基于 Etcd 的。
和 Consul 一样,Etcd 也是基于 Raft 协议作为分布式一致性算法来解决领导者选举和日志复制问题,同样也是基于 Go 语言编写。
Etcd 也支持代理模式(proxy),只不过在 Etcd 中,代理模式和 Consul 的客户端代理模式类似,安装在部署服务的节点上,用来转发请求到 Etcd 集群,本身不存储任何数据,Etcd 集群相当于 Consul 中以服务端模式运行的 Consul 集群,通常要求配置三个及以上节点(不要太多,3~5 就够了,以便可用性和性能上达到平衡),负责真正的请求处理 —— 服务注册与发现。
在目前最新版本的 Etcd v3 中,通过网关模式(gateway)取代了 V2 版本中的代理模式(proxy)。
从服务发现的实现原理上来说,Consul 和 Etcd 的基本设计思路是一致的,Etcd 更简单,Consul 则更像一个全栈的解决方案,功能比 Etcd 要更丰富,比如支持可视化的 Web UI 管理界面、支持多数据库中心、安全层面除了 HTTPS 外还支持 ACL、更加全面的健康检查功能、内置 DNS Server 等,这些都是 Etcd 所不具备的,但是更全面的功能往往意味着更高的复杂性,针对微服务的服务注册和发现场景,Etcd 完全够用了。
本书适合具有一定 Java 基础和 Spring MVC 基础的人群以及希望往架构师方向发展的开发者阅读。
本书共分四部分,从基础到实战,讲解了基于 Spring Cloud 的常用组件。
第一部分(基础篇):第 1~4 章
第二部分(实战篇):第 5~10 章
第三部分(高级篇):第 11~13 章
第四部分(部署篇):第 14~15 章
第 1 章微服务概述
我们要学习微服务架构,就要了解它,本章将带领大家初步了解微服务,为后面系统学习微服务架构奠定良好的基础。
第 2 章 Spring Boot 基础
本书以实战为导向,讲解了如何使用 Spring Cloud 开发微服务项目,而 Spring Cloud 基于 SpringBoot,所以本章先来初步了解如何使用 Spring Boot 搭建框架。
第 3 章 Spring Boot 核心原理
通过第 2 章的学习,读者应该对 Spring Boot 有了一个大致的认识,利用 Spring Boot 可以极大地简化应用程序的开发,这都归功于 Spring Boot 的四大核心原理:起步依赖、自动配置、Actuator 和 Spring Boot 命令行。本章中,我们将深入探讨 Spring Boot 的核心原理,以便读者能更好地学习和使用 Spring Boot。
第 4 章 Spring Cloud 概述
从本章开始,我们将正式踏上探索 Spring Cloud 秘密的旅程。学完本书后,读者将学会搭建一个完整的分布式架构,从而向架构师的目标靠近。
第 5 章 项目准备阶段
本章中,我 将开始 个大型实战项目一一博客网站。通过“以战代练”的方式来学习如何构建 Spring loud 微服务架构,让读者走出理论的丛林,在实践中玩转微服务架构。
第 6 章 公共模块封装
从本章开始,我们将学习框架的搭建。由于代码量巨大,本书不可能全部贴出,所以只展示一些核心代码。全部源码可以从本书配套源码中查看。
第 7 章 注册中心: Spring Cloud Netflix Eureka
通过前面的学习,我们可以总结出来,注册中心是整套微服务架构的核心,即系统的心脏,它能够帮助我们管理所有的微服务,精确定位到具体的服务就是通过注册中心来实现的。构建注册中心的好处也是不言而喻的,通过注册中心,我们可以实现服务的负载均衡。配置的统-管理。服务间的通信等。目前。我们可以采用多种技术实现注册中心,如 Eureka. ZooKeeper. Consul 等,本书采用 SpringCloud 默认集成的 Eureka 框架来构建注册中心。
第 8 章 配置中心: Spring Cloud Config
我们知道,一个微服务系统可能由成千上万的服务组成,每个服务都会有自己的配置,不同服务之间的有些配置是相同的,比如数据库。如果对于每个服务,我们都复制相同的配置,一旦该配置发生了变化,那么每个服务都需要修改,代价可想而知。Spring Cloud 已经考虑到了这一点, 它为我们提供了一整套解决方案, 那就是强大的 Spring CloudConfig。
第 9 章 服务网关: Spring Cloud Gateway
本将介绍的微服务的又一大组件一一服务网关。我们需要服务网关,还有一些很重要的因素,比如服务网关会对接口进行统一拦截并做合法性校验,一个服务可以启动多个端口,利用服务网关进行负载均衡处理等。目前市面上有很多产品可以实现服务网关这一功能, 如 Nginx. Apache. Zuul 以及 Spring CloudGateway 等。Spring Cloud 集成了 Zuul 和 Gateway,我们可以很方便地实现服务网关这一功能。
第 10 章 功能开发
通过前几章的学习,我们已经搭建好了博客网站的基本框架。本章我们将正式开始网站的功能开发。
第 11 章 服务间通信: Spring Cloud Netflix Ribbon 和 Spring Cloud OpenFeign
一个大型的 系统由多个微服务模块组成,我们一-般 可以通过内部接口调用的形式(服务 A 提供一个接口,服务 B 通过 HTTP 请求调用服务 A 的接口)实现各模块之间的通信。为了简化开发,SpringCloud 集成了 Spring Cloud Netlix Ribbon 和 Spring Cloud OpenFeign,两个组件都支持通过 HTTP 请求不同的服务。本书将简要介绍 Spring Cloud Netflix Ribbon,借此引出 Sping Cloud OpenFeign,并详细介绍其用法。
第 12 章 服务链路追踪: Spring Cloud Sleuth
我们知道,微服务之间通过网络进行通信,但在我们提供服务的同时,不能保证网络一定是畅通的。相反地,网络是很脆弱的,网络资源也有限,因此我们有必要追踪每个网络请求,了解它们经过了哪些微服务,延迟多少,每个请求所耗费的时间等。只有这样才能更好地分析系统瓶颈,解决系统问题。在 Spring Cloud 中,我们可以使用 Spring Cloud Sleuth 组件来实现微服务追踪。
第 13 章 服务治理: Spring Cloud Consul 和 Spring Cloud ZooKeeper
在前面的章节中,读者已经接触到了 Spring Cloud 默认集成的服务治理框架 Spring Cloud NettlixEureka。在本章,我们将接触到新的服务治理框架,以便读者在实际应用中有多种选择。
第 14 章系统发布上线
通过前几章的学习,我们顺利完成了应用的开发,仅仅完成框架搭建和功能开发是不够的,我们还需要将应用发布到服务器上供客户端访问。本章中,我们将开始详解应用的发布。
第 15 章使用 Kubernetes 部署分布式集群
容器技术的出现带给了我们新的思路。我们可以将服务打包成镜像,放到容器中,通过容器来运行服务,这样可以很方便地进行分布式管理,同样的服务也可以很方便地进行水平扩展。Docker 是容器技术方面的佼佼者,它是一-个开源容器,而 Kubernetes (以下简称 K8S)是一个分布式集群方案的平台,它和 Docker 就是天生的一对。 通过 K8S 和 Docker 的配合,我们很容易搭建分布式集群环境。下面,我们就来看一下 Docker 和 K8S 的诱人之处。