1.2 Spring Cloud与中间件
1.2.1 中间件概述
中间件与操作系统、数据库并列为传统基础软件的三驾马车。其中,中间件也是难度极高的软件工程。传统中间件的概念,诞生于上一个“分布式”计算的年代,也就是小规模局域网中的服务器/客户端计算模式,在操作系统之上、应用软件之下的“中间层”软件。
随着互联网的快速发展,以及云计算的出现,企业的IT架构正在发生深刻的变革。在这个过程中,软件向大规模互联网云服务演化,无论是操作系统还是数据库都发生了深刻的变化,中间件也在这个过程不断演进和扩大自己的边界。中间件向下屏蔽异构的硬件、软件、网络等计算资源,向上提供应用开发、运行、维护等全生命周期的统一计算环境与管理,属于承上启下的中间连接层,对企业来说有着极其重要的价值。中间件本质上可以归属为技术架构,常见的中间件分别是服务治理中间件(例如:Dubbo等RPC框架)、配置中心、全链路监控、分布式事务、分布式定时任务、消息中间件、API网关、分布式缓存、数据库中间件等。
1.2.2 什么是Spring Cloud
在前面的小节介绍了中间件,Spring Cloud也是一个中间件。它目前由Spring官方开发维护,基于Spring Boot开发,提供一套完整的微服务解决方案。包括服务注册与发现、配置中心、全链路监控、API网关、熔断器等选型中立的开源组件,可以随需扩展和替换组装。
Spring Cloud项目自从推出以来,到目前为止一直在高速迭代。Spring Cloud技术团队于2018年6月19日发布了Spring Cloud的重大里程碑Finchley版本。本书也是基于此版本编写,目前Spring Cloud在国内外得到广泛使用。Spring Cloud中国社区发起了Spring Cloud在中国的使用情况收集,具体可以参考如下统计链接:http://github.com/SpringCloud/spring-cloud-document/issues/1。
1.2.3 Spring Cloud项目模块
Spring Cloud是一个开源项目集合,包括很多子项目。具体的项目地址可以参考GitHub组织:http://github.com/spring-cloud。Spring Cloud的主要组件汇总如表1-3所示,因为Spring Cloud的子项目居多,每个子项目有自己的版本号,为了对Spring Cloud整体进行版本编号,确定一个可用于生产上的版本标识。这些版本采用伦敦地铁站的名字,按名称首字母排序,比如Dalston版,Edgware版,Finchley。但是我们一般都会简称为D版、E版、F版等。
表1-3 Spring Cloud组件列表
1.2.4 Spring Cloud与服务治理中间件
服务治理中间件包含服务注册与发现、服务路由、负载均衡、自我保护、丰富的治理管理机制等功能。其中服务路由包含服务上下线、在线测试、机房就近选择、A/B测试、灰度发布等。负载均衡支持根据目标状态和目标权重进行负载均衡。自我保护包括服务降级、优雅降级和流量控制。
Spring Cloud作为一个服务治理中间件,它的服务治理体系做了高度的抽象,目前支持使用Eureka、Zookeeper、Consul作为注册中心,并且预留了扩展接口,而且由于选型是中立的,所以支持无缝替换。在Spring Cloud中可以通过Hystrix进行熔断自我保护Fallback,通过Ribbon进行负载均衡。本书围绕着Spring Cloud的服务治理体系介绍Eureka、Consul、Ribbon、Hystrix等实战用法。关于Spring Cloud注册中心的对比选型参考,如图1-4所示。
图1-4 注册中心选型对比
1.2.5 Spring Cloud与配置中心中间件
在单体应用中,我们一般的做法是把属性配置和代码硬编码放在一起,这没有什么问题。但是在分布式系统中,由于存在多个服务实例,需要分别管理每个具体服务工程中的配置,上线需要准备Check List并逐个检查每个上线的服务是否正确。在系统上线之后一旦修改某个配置,就需要重启服务。这样开发管理相当麻烦。因此我们需要把分布式系统中的配置信息抽取出来统一管理,这个管理的中间件称为配置中心。配置中心应该具备的功能,分别是支持各种复杂的配置场景,与公司的运维体系和权限管理体系集成,各种配置兼容支持,如图1-5所示。
图1-5 配置中心的功能
Spring Cloud Config是Spring Cloud生态圈中的配置中心中间件,它把应用原本放在本地文件中的配置抽取出来放在中心服务器,从而能够提供更好的管理、发布能力。Spring Cloud Config基于应用、环境、版本三个维度管理,配置存储支持Git和其他扩展存储,且无缝支持Spring里Environment和PropertySource的接口。但是Spring Cloud Config的缺点是没有可视化的管控平台,因此会用其他的配置中心中间件取代它管理配置。在本书的第11章和第12章介绍了Spring Cloud Config和携程开源配置中心Apollo的实战用法。
1.2.6 Spring Cloud与网关中间件
1.网关中间件概述
API Gateway(APIGW/API网关),顾名思义,是出现在系统边界上一个面向API的、串行集中式的强管控服务,这里的边界是企业IT系统的边界,可以理解为企业级应用防火墙,主要起到隔离外部访问与内部系统的作用。在微服务概念流行之前,API网关就已经诞生了,例如银行、证券等领域常见的前置系统,它的设计与出现主要是为了解决访问认证、报文转换、访问统计等问题。网关在微服务架构中所处的位置,如图1-6所示。
图1-6 网关在微服务架构中所处的位置
随着微服务架构概念的提出,API网关成为微服务架构的一个标配组件。作为一个网关中间件,至少具备如下四大功能。
(1)统一接入功能
为各种无线应用提供统一的接入服务,提供一个高性能、高并发、高可靠的网关服务。不仅如此,还要支持负载均衡、容灾切换和异地多活。
(2)协议适配功能
网关对外的请求协议一般是HTTP或HTTP2协议,而后端提供访问的服务协议要么是REST协议要么是RPC协议。网关需要根据请求进来的协议进行协议适配,然后协议转发调用不同协议提供的服务。比如网关对外暴露是HTTP协议的请求,而网关后端服务可能是Dubbo提供的RPC服务,可能是Spring Cloud提供的REST服务,也可能是其他PHP编写的服务。当一个HTTP请求经过网关时,通过一系列不同功能的Filter处理完毕之后,此时就需要进行协议适配,判断应该协议转发调用RPC服务,调用REST服务,还是调用PHP提供的服务。
(3)流量管控功能
网关作为所有请求流量的入口,当请求流量瞬间剧增,比如天猫双11、双12或者其他大促活动,流量会迅速剧增,此时需要进行流量管控、流量调拨。当后端服务出现异常,服务不可用时,需要网关进行熔断和服务降级。在异地多活场景中需要根据请求流量进行分片,路由到不同的机房。
(4)安全防护功能
网关需要对所有请求进行安全防护过滤,保护后端服务。通过与安全风控部门合作,对IP黑名单和URL黑名单封禁控制,做风控防刷,防恶意攻击等。
2. Spring Cloud第一代网关Zuul
Spring Cloud生态圈的第一代网关是在Netflix公司开源的网关组件Zuul之上,它基于Spring Boot注解,采用Starter的方式进行二次封装,可以做到开箱即用。目前Zuul融合了Spring Cloud提供的服务治理体系,根据配置的路由规则或者默认的路由规则进行路由转发和负载均衡。它可以与Spring Cloud生态系统内其他组件集成使用,例如:集成Hystrix可以在网关层面实现降级的功能;集成Ribbon可以使得整个架构具备弹性伸缩能力;集成Archaius可以进行配置管理等。但是Spring Cloud Zuul如果需要做一些灰度、降级、标签路由、限流、WAF封禁,则需要自定义Filter做一些定制化实现。
3. Spring Cloud第二代网关Gateway
Spring Cloud Zuul处理每个请求的方式是分别对每个请求分配一个线程来处理。根据参考数据统计,目前Zuul最多能达到1000至2000 QPS。在高并发的场景下,不推荐使用Zuul作为网关。因此出现了Spring Cloud的第二代网关,即Spring Cloud Gateway。
Spring Cloud Gateway是Spring官方基于Spring 5.0、Spring Boot 2.0和Project Reactor等技术开发的网关,旨在为微服务架构提供一种简单、有效、统一的API路由管理方式。Spring Cloud Gateway底层基于Netty实现(Netty的线程模型是多线程reactor模型,使用boss线程和worker线程接收并异步处理请求,具有很强大的高并发处理能力),因此Spring Cloud Gateway出现的目的就是替代Netflix Zuul。其不仅提供统一的路由方式,并且基于Filter链的方式提供了网关基本的功能,例如,安全、监控/埋点、限流等。在本书的第17章和18章,详细地介绍了Spring Cloud Gateway的使用方法和实战技巧。
1.2.7 Spring Cloud与全链路监控中间件
众所周知,中大型互联网公司的后台业务系统由众多的分布式应用组成。一个通过浏览器或移动客户端的前端请求到后端服务应用,会经过很多应用系统,并且留下足迹和相关日志信息。但这些分散在每个业务应用主机下的日志信息不利于问题排查和定位问题发生的根本原因。此时就需要利用全链路监控中间件收集、汇总并分析日志信息,进行可视化展示和监控告警。全链路监控中间件应该提供的主要功能包括:
❑ 定位慢调用:包括慢Web服务(包括Restful Web服务)、慢REST或RPC服务、慢SQL。
❑ 定位各种错误:包括4× ×、5× ×、Service Error。
❑ 定位各种异常:包括Error Exception、Fatal Exception。
❑ 展现依赖和拓扑:域拓扑、服务拓扑、trace拓扑。
❑ Trace调用链:将端到端的调用,以及附加在这次调用的上下文信息,异常日志信息,每一个调用点的耗时都呈现给用户进行展示。
❑ 应用告警:根据运维设定的告警规则,扫描指标数据,如违反告警规则,则将告警信息上报到中央告警平台。
全链路监控中间件相关产品发展至今百花齐放,如京东Hydra,阿里Eagleye,这两个中间件都吸收了Dapper/Zipkin的设计思路,但是目前都未开源。近年,社区又发展出很多调用链监控产品,如国内开源爱好者吴晟(原OneAPM工程师,目前在华为)开源并提交到Apache孵化器的产品Skywalking,它同时吸收了Zipkin/Pinpoint/CAT的设计思路,支持非侵入式埋点。如果使用Java技术栈,希望采用非侵入式的监控,推荐使用Pinpoint或者Skywalking。
本书的相关章节介绍了Spring Cloud Sleuth的实战用法,以及如何借助Pinpoint或者Skywalking实现Spring Cloud体系下的全链路监控。