Spring Cloud作为Java语言的微服务框架,它依赖于SpringBoot,有快速开发、持续交付和容易部署等特点。SpringCloud的组件非常多,涉及微服务的方方面面,在开源社区Spring和Netflix、Pivotal两大公司的推动下越来越完善。
微服务可拆分为 “微” 和 “服务” 两个。“微” 即小的的意思,那到底多小才算 “微” 呢?可能不同的团队有不同的答案。从参与微服务的人数来讲,单体微服务从架构、代码、开发、测试、运维的人数加起来是8~10人才算“微”。那么何为“服务呢”?按照 “微服务” 概念提出者Martin Fowler给出的建议:“服务”是一个独立运行的单元组件,每个单元组件运行在独立的进程中。组件与组件之间通常使用HTTP这种轻量级的通信机制进行通信。
微服务具有一下特点:
微服务具有以上这些特点,那么微服务需要具备一些什么样的功能呢?微服务的功能主要体现在以下几个方面。
微服务系统由很多个单一职责的服务单元组成,例如Netflix公司的系统是由600多个微服务构成的,而每一个微服务又有众多实例。由于微服务于系统的服务粒度小,服务数量众多,服务之间相互依赖成网状,所以微服务系统服务注册中心来统一管理微服务实例,方便查看每一个微服务实例的健康状态。
服务注册是指向服务注册中心注册一个服务实例,服务提供者将自己的服务信息(如服务名、IP地址等)告知服务注册中心。服务发现是指当服务消费者需要消费另外一个服务时,服务注册中心能够告知服务消费者它所需要消费服务的实例信息(如服务名、IP地址等)。通常情况下,一个服务即是服务提供者,也是服务消费者。服务消费者一般使用HTTP协议或者消息组件这种轻量级的通信机制来进行服务消费。服务的注册与发现如图所示:
服务注册中心会提供服务的健康检查方案,检查被注册的服务是否可用。通常一个服务实例注册后,会定时向服务中心提供 “心跳”,以表明自己处于可用的状态。当一个服务实例通知向服务注册中心提供心跳一段时间后,服务注册中心会认为服务实例不可用,会将该服务实例从服务注册中心列表中剔除。如果这个被剔除掉的服务实例过一段时间后继续向注册中心提供心跳,那么服务注册中心会将该服务实例重新加入服务注册中心的列表中,另外,微服务的服务注册组件都会提供服务的健康状况查看的UI界面,开发人员或者运维人员只需要登录相关的界面就可以服务的健康状态。
在微服务架构中,服务之间的相互调用一般是通过HTTP通信协议来实现的。网络往往具有不可靠性,为了保证服务的高可用 (High Availability),服务单元往往是集群化部署的。例如将服务提供者进行集群化部署,那么服务消费者该调用哪个服务者提供的实例呢?这就涉及了服务的负载均衡。
服务的负载均衡一般最流行的做法如图所示,所有的服务都向服务注册中心注册,服务注册中心持有每个服务的应用名和IP地址信息等,同时每个服务也会获取所有服务注册列表信息。服务消费者集成负载均衡组件,该组件会向服务消费者获取服务注册列表信息,并每隔一段时间重新刷新获取该列表。当服务消费者消费服务时,负载均衡组件获取服务提供者所有实例的注册信息,并通过一定的负载均衡策略(开发者可以配置),选择一个服务提供者的实例,向该实例进行服务消费,这样就实现了负载均衡。
服务注册中心不但需要定时接受每个服务的心跳(用来检查服务是否可用),而且每个服务定期获取服务注册列表的信息,当服务实例数量很多时,服务注册中心承担了非常大的负载。由于服务注册中心在微服务系统中起到了至关重要的作用,所以必须实现高可用。一般的做法是将服务注册中心集群化,每个服务注册中心的数据实时同步,如图所示:
微服务落地到实际项目中,服务数量往往非常多,服务之间的相互依赖性也是错综复杂的,一个网络请求通常要调用多服务才能完成。如果一个服务不可用,例如网络延迟或故障,会影响到依赖于这个不可用的服务的其他服务。如图所示,一个微服务系统有很多个服务,当服务F因某些原因导致了服务的不可用,来至于用户的网络请求需要调用服务F。由于服务F无响应 ,用户的请求都处于阻塞状态,在高并发的场景下,短时间内会导致服务器的线程资源消耗殆尽。另外,依赖于服务F的其他服务,例如图中的服务E、服务G,服务J、也会等待服务F的响应,处于阻塞状态,导致这些服务的线程资源消耗殆尽,进而导致它们的不可用,以及依赖于它们的服务的不可用,最后导致整个系统处于瘫痪的状态也就是雪崩效应。
为了解决分布式系统的雪崩效应,分布式系统引进了熔断器机制。熔断器(Circuit Breaker)一次来源于物理学中的电路知识,它的作用是电路中出现故障时迅速切断电路,从而保护电路,熔断机制如图所示。当一个服务的处理用户请求的失败次数在一定时间内大于设定的阈值时,说明出现了故障,打开熔断器,这时所有的请求会执行快速失败,不执行业务逻辑。当处于打开状态的容器时,一段时间后会处于半打开状态,并执行一定数量的请求,剩余的请求会执行快速失败,若执行的请求失败了,则继续打开熔断器,若成功了,则将熔断器关闭。
这种机制有着非常重要的意义,它不仅能够有效的防止系统的 “雪崩” 效应,还具有一下作用。
Netflix 的 Hystrix熔断器开源组件功能非常强大,不仅有熔断器的功能,还有熔断器的状态监测,并提供友好的UI界面,开发人员或运维人员通过UI界面能够直观的看到熔断器的状态和各种性能指标。
微服务系统通过将资源以API接口的形式暴露给外界来提供服务。在微服务系统中,API接口资源通常是由服务网关(也称 API网关)统一暴露,内部服务不直接对外提供API资源的暴露。这样做的好处是将内部服务隐藏起来,外界还以为是一个服务在提供服务,在一定程度上保护了微服务系统的安全。API网关通常有请求转发的作用,另外它可能需要负责一定在安全验证,例如判断某个请求是否合法,该请求对某一个资源是否具有操作权限等。通常情况下,网关层以集群的形式存在。在服务网关层之前,有可能需要加上负载均衡层,通常为Nginx双机热备,通过一定的路由策略,将请求转发到网关层。到达网关层后,进过一系列的用户身份验证、权限判断,最终转发到具体的服务。具体的服务经过一系列的逻辑运算和数据操作,最终将结果返回给用户,此时的架构如图所示:
网关层具有很重要的意义,具体体现在以下方面。
当然,网关实现这些功能,需要做高可用,否则网关很可能成为架构中的拼劲。最常用的网关组件有Zuul和Nginx等。
在实际开发过程中,每个服务都有大量的配置文件,例如数据库的配置、日志输出级别的配置等,而往往这些配置在不同的环境中也是不一样的。随着服务数量的增加,配置文件的管理也是一件非常复杂的事。
在微服务架构中,需要有统一管理配置文件的组件,例如:Spring Cloud的Spring Cloud Config组件、阿里巴巴的Diamood、百度的Disconf、携程的Apollo等。这些配置组件所实现的功能大体相同,但又有差别,下面以Spring Cloud Config为例来阐述服务配置的统一管理。如图所示:
大致过程如下:
对于集群化的服务,可以通过使用消息总线来刷新多个服务实例。如果服务数量较多,对配置中心需要考虑集群化部署,从而使配置中心高可用,做分布式集群。
微服务系统是一个分布式架构的系统,微服务系统按业务划分服务单元,一个微服务系统往往有很多个服务单元。由于服务单元很多且复杂,服务与服务之间的调用有可能非常复杂,一旦出现了异常和错误,就会很难去定位。所以在微服务架构中,必须实现分布式链路追踪,去跟进一个请求到底有哪些服务参与,参与的顺序又是怎样的,从而使每个请求链路清晰可见,出现了问题很快就能定位。
举个例子,如图所示,在微服务系统中,一个来自用户的请求先到达前端A(如前端界面),然后通过远程调用,到达系统的中间件B、C(如负载均衡、网关等),最后到达后端服务D、E。后端经过一系列的逻辑运算,最后将数据返回给用户。对于这一请求,经历了了这么多服务,怎么样将他的请求过程的数据记录下来呢?这就需要用到服务链路的追踪。
Google开源了链路追踪组件Dapper,并在2010年发表了论文《Dapper,a Large-Scale Distrbuted Systems Tracing Infrastructure》,这篇文章是业内实现链路追踪的标杆和理论基础,具有非常高的参考价值。
目前,常见的链路追踪组件有Google的Dapper、Twitter的Zipkin,以及阿里的Eagleeye(鹰眼)等。都是非常优秀的链路追踪开源组件。
Spring Cloud是基于Spring Boot的。Spring Boot 是由Pivotal团队提供的全新Web框架,它主要的特点就是简化了开发和部署的过程,简化了Spring复杂的配置和依赖管理,通过起步依赖和内置Servlet容器能够使及开发者迅速搭建起一个Web工程。所以Spring Cloud在开发部署上继承了Spring Boot的一些有点,提高了开发和部署上的效率。
Spring Cloud的首要目标就是通过一系列开发组件和框架,帮助开发者迅速搭建一个分布式的微服务系统。Spring Cloud是通过包装其他技术框架来实现的,例如包装开源的Netflix OSS组件,实现了一套通过基于注解、Java配置和基于模板开发的微服务框架.Spring Cloud框架来自于Spring Resource社区,由Pivotal和Netflix两大公司和一些其他的开发者提供技术上的更新迭代。Spring Cloud提供了开发分布式微服务系统的一些常用组件,例如服务注册和发现、配置中心、熔断器、智能路由、为代理、控制总线、全局锁、分布式会话等。
上述的4个组件都来自于Netflix公司,统一称为 Spring Cloud Netflix。
上述列举了一些常用的Spring Cloud组件。一个简单的由Spring Cloud构建的微服务系统,通过常用服务注册中心Eureka、网关Zuul、配置中心Config和授权服务Auth构成,如图所示:
Dubbo是阿里开源的一个分布式服务框架,致力于提高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。Dubbo广泛用于阿里巴巴的各大站点,有很多互联网公司也在使用这个框架。它包含如下核心内容:
Dubbo的架构图如图所示:
Dubbo架构的流程如下:
Dubbo是一个非常优秀的服务治理框架,在国内互联网公司应用广泛,它具有以下特点:
首先从微服务关注点来比较Spring Cloud和Dubbo两大服务框架,如表所示:
微服务关注点 | Spring Cloud | Dubbo |
---|---|---|
配置管理 | Config | —— |
服务发现 | Eureka、Consul、Zookeeper | Zookeeper |
负载均衡 | Ribbon | 自带 |
网关 | Zuul | —— |
分布式追踪 | Spring Cloud Sleuth | —— |
容错 | Hystrix | 不完善 |
通信方式 | HTTP、Message | RPC |
安全模块 | Spring Cloud Security | —— |
Spring Cloud拥有很多的项目模块,包含了微服务系统的方方面面。Dubbo是一个非常优秀的服务治理和服务调用框架,但缺少很多功能模块,例如网关、链路追踪等。在项目模块上,Spring Cloud更具有优势。
Spring Cloud的更新速度非常快,Camden.SR5版本发布于2017年2月,Camden.SR6版本发布于2017年3月,Dalston版本发布于2017年4月,Finchley版本发布于2018年6月,Greenwich版本发布于2019年2月,基本每年发布1~2次版本,每月会发一次版本的迭代。从GitHub的代码仓库来看,Spring Cloud几乎每天都在更新。阿里巴巴于2011年10月开源了Dubbo,开源后的Dubbo发展迅速,大概每23个月有一次版本更新。然而,从在2013年3月开始,Dubbo暂停了版本更新,并只在2014年10月发布了一个小版本,修复了一个Bug,之后长期处于版本停止更新的状态。直到2017年9月,阿里巴巴中间件部门重新组建了Dubbo团队,把Dubbo列为重点开源项目,并在2017年911月之间,一直保持每月一次版本更新的频率。
从学习成本上考虑,Dubbo的版本趋于稳定,文档完善,可以即学即用,没有太大难度。Spring Cloud基于Spring Boot开发,需要开发者先学会Spring Boot。另外,Spring Cloud版本迭代快,需要快速跟进学习。Spring Cloud文档大都是英文的,要求学习者有一定的英文阅读能力。此外,Spring Cloud文档很多,不容易快速找到相应的文档。
从开发风格上来讲,Dubbo更倾向于Spring Xml的配置方式,Dubbo官方也是推荐这种方式。Spring Cloud基于Spring Boot,Spring Boot采用的是基于注解和JavaBean配置方式的敏捷开发。从开发速度上讲,Spring Cloud具有更高的开发和部署速度。
最后。Spring Cloud的通信方式大多数是基于HTTP Restful风格的,服务与服务之间完全无关、无耦合。由于采用的是HTTP Rest,因此服务无关乎语言和平台,只需要提供响应的API接口,就可以相互调用。Dubbo的通信方式基于远程调用,对接口、平台和语言有强依赖性。如果需要实现跨平台调用服务,需要写额外的中间件,这也是Dubbox(支持HTTP协议)存在的原因。
Dubbo和Spring Cloud拥有各自的优缺点,Dubbo更容易上手,并且广泛使用于阿里巴巴的各大站点,经历了 “双11” 期间高并发、大流量的检验,Dubbo框架非常成熟和稳定。Spring Cloud服务框架严格遵守Martin Fowle提出的微服务规范,社区异常活跃,它很可能成为微服务架构的标准。
Kubermetes是一个容器集群管理系统,为容器话的应用程序提供部署运行、维护、扩展、资源调度、服务发现等功能。
Kubermetes是Google运行Borg大规模系统达15年之久的一个经验总结。Kubermetes结合了社区的最佳创意和实践,旨在帮助开发人员将容器打包、动态编排,同时帮助各大公司向微服务方向进行 技术演进。它具有以下特点:
Kubermetes开源免费,是Google在过去15年时间里部署、管理微服务的经验结晶,所以目前Kubermetes在技术社区也是十分火热。下面来看它提供的功能。
从Kubermetes提供的功能来看,Kubermetes完全可以成为构建和部署微服务的一个工具,它是从服务编排上实现的,而不是代码实现的。目前国外有很多知名的公司在使用Kubermetes,如Google、eBay、Pearson等 。由于它的开源免费,Microsoft、VMWare、RedHat、CoreOS等公司纷纷加入并贡献代码。Kubermetes技术吸引了一大批公司和技术爱好者,它已经成为容器管理的领导者。
Spring Cloud是一个构建微服务的框架,而Kubermetes是通过运行的容器的编排来实现构建微服务的。两者从构建微服务的角度和实现方式有很大的不同,但它们提供了构建微服务所需要的全部功能。从提供的微服务所需的功能上看,两者不分上下,如表所示:
微服务关注点 | Spring Cloud | Kubermetes |
---|---|---|
配置管理 | Config | Kubermetes ConfigMap |
服务发现 | Eureka、Consul、Zoopeeper | Kubermetes Services |
负载均衡 | Ribbon | Kubermetes Services |
网关 | Zuul | Kubermetes Services |
分布式追踪 | Spring Cloud Sleuth | Open tracing |
容错 | Hystrix | Kubermetes Health Check |
安全模块 | Spring Cloud Security | —— |
分布式日志 | ELK | EFK |
任务管理 | Spring Boot | Kubermetes Jobs |
Spring Cloud 通过众多的数据库来实现微服务系统所需的各个组件,同时不断集成优秀的组件,所以Spring Cloud组件是非常完善的。Spring Cloud基于Spring Boot框架,有快速开发、快速部署的有点。对于Java开发者来说,学习Spring Cloud的成本不高
Kubermetes在编排上解决微服务的各个功能,例如服务发现、配置管理、负载均衡、容错等。Kubermetes不局限于Java平台,也不局限于语言,开发者可以自由选择开发语言进行项目开发。
与Kubermetes相比,Spring Cloud具有以下有点:
与Kubermetes相比,Spring Cloud具有以下有点:
下面介绍Kubermetes的有点和缺点:
Spring Cloud尝试从Java类库来实现微服务的所有功能,而Kubermetes尝试从容器编排上实现所有的微服务功能,两者的实现角度和方式不一样,个人觉得,两者最终的实现功能和效果上不分胜负,但从实现的方式上来讲,Kubermetes略胜一筹。Kubermetes面向DevOps人员,学习成本高。Spring Cloud有很多的类库。以Spring为基础,继承了Spring Boot快速开发的优点,为Java程序员开发微服务提供了很好的体验,学习成本也较低。所以二者比较,各有优势。没有最好的框架,也没有最好的工具,关键是要适合业务需求和满足业务场景。
首先介绍了微服务应该具备的功能,然后介绍了Spring Cloud和Spring Cloud的基本组件,最后介绍了Spring Cloud与Dubbo、Kubermetes之间的比较,以及它们的优缺点。Spring Cloud作为Java语言的微服务落地框架,有很多的微服务组件。
本高。Spring Cloud有很多的类库。以Spring为基础,继承了Spring Boot快速开发的优点,为Java程序员开发微服务提供了很好的体验,学习成本也较低。所以二者比较,各有优势。没有最好的框架,也没有最好的工具,关键是要适合业务需求和满足业务场景。
首先介绍了微服务应该具备的功能,然后介绍了Spring Cloud和Spring Cloud的基本组件,最后介绍了Spring Cloud与Dubbo、Kubermetes之间的比较,以及它们的优缺点。Spring Cloud作为Java语言的微服务落地框架,有很多的微服务组件。