微服务能够拆分为"微"和"服务"二字。"微"即小的意思,那到底多小才算"微"呢?可能不一样的团队有不一样的答案。从参与微服务的人数来说,单个微服务从架构设计、代码开发、测试、运维人数加起来是8~10人才算"微"。那么何为"服务"呢?按照"微服务"概念提出者Martin Fowler给出的定义:"服务"是一个独立运行的单元组建,每一个单元组件运行在独立的进程中,组件与组件之间一般使用HTTP这种轻量级的通讯机制进行通讯。微服务具备如下特色:前端
微服务具备以上这些特色,那么微服务须要具有一些什么样的功能呢?微服务的功能主要体如今如下几个方面:程序员
1.服务的注册与发现
微服务系统由不少个单一职责的服务单元组成,例如Netflix公司的系统是由600多个微服务构成的,而每个微服务又有众多实例。因为该系统的服务粒度较小,服务数量众多,服务之间的相互依赖呈网状,因此该系统须要服务注册中心来统一管理微服务实例,方便查看每个微服务实例的健康状态。
服务注册是指向服务注册中心注册一个服务实例,服务提供者将本身的服务信息(如服务名、IP地址等)告知服务注册中心。服务发现是指当服务消费者须要消费另一个服务时,服务注册中心可以告知服务消费者它所要消费服务的实例信息(如服务名、IP地址等)。一般状况下,一个服务既是服务提供者,也是服务消费者。服务消费者通常使用HTTP协议或者消息组件这种轻量级的通讯机制来进行服务消费。服务的注册与发现以下如所示:
服务注册中心会提供服务的健康检查方案,检查被注册的服务是否可用。一般一个服务实例注册后,会定时向服务注册中心提供"心跳",以代表本身还处于可用的状态。当一个服务实例中止向服务注册中心提供心跳一段时间后,服务注册中心会认为该服务实例不可用,会将该服务实例从服务注册列表中剔除。若是这个被剔除掉的服务实例过一段时间后继续向注册中心提供心跳,那么服务注册中心会将该服务实例从新假如服务注册中心的列表中。另外,微服务的服务注册组件都会提供服务的健康情况查看的UI界面,开发人员或运维人员只须要登录相关的界面就能够知道服务的健康状态。spring
2.服务的负载均衡
在微服务结构中,服务之间的相互调用通常是经过HTTP通讯协议来实现的。网络每每具备不可靠性,为了保证服务的高可用(High Availability),服务单元每每是集群化部署。例如将服务提供者进行集群化不舒服,那么服务消费者该调用哪一个服务提供者的实例呢?这就涉及到了服务的负载均衡。
服务的负载均衡通常最流行的作法以下如所示,全部的服务都向服务注册中心注册,服务注册中心持有每一个服务的
应用名和IP地址等信息,同时每一个服务也会获取全部服务注册列表信息。服务消费者集成负载均衡组件,该组件会向服务消费者获取服务注册列表,并每隔一段时间从新刷新获取该列表。当服务消费者消费服务时,负载均衡组件获取服务提供者全部实例的注册信息,并经过必定的负载均衡策略(开发者能够配置),选择一个服务提供者的实例,向该实例进行服务消费,这样就实现了负载均衡。
服务注册中心不但须要定时接收每一个服务的心跳(用来检查服务是否可用),并且每一个服务会按期获取服务注册列表的信息,当服务实例数量不少时,服务注册中心承担了很是大的负载。因为服务注册中心在微服务系统中起到了相当重要的做用,因此必须实现高可用。通常的作法是将服务注册中心集群化,每一个服务注册中的数据实时同步,以下图所示:
数据库
3.服务的容错
微服务落地到实际项目中,服务的数量每每很是多,服务之间的相互依赖性也是错综复杂的,一个网络请求一般须要调用多个服务才能完成。若是一个服务不可用,例如网络延迟或故障,会影响到依赖于这个不可用的服务的其余服务。以下图所示:
一个微服务系统有不少服务,当服务F因某些缘由致使了服务的不可用,来自于用户的网络请求须要调用服务F。因为服务F无响应,用户的请求都处于阻塞状态,在高并发的场景下,短期内会致使服务器的线程资源消耗殆尽。另外,依赖于服务F的其余服务,例如图中的服务E、服务G、服务J,也会等待服务F的响应,处于阻塞状态,致使这写服务的线程资源消耗殆尽,进而致使它们的不可用,以及依赖于它们的服务的不可用,最后致使整个系统处于瘫痪的状态,也就是"雪崩效应"。
为了解决分布式系统的雪崩效应,分布式系统引进了熔断器机制。熔断器(Circuit Breaker)一词来源于物理学中的电路知识,它的做用是当电路中出现故障时迅速切断电源,起到保护电路的做用,熔断器机制以下图所示:
当一个服务的处理用户请求的失败次数在必定时间内小于设定的阀值时,熔断器处于关闭状态,服务正常;当服务处理用户请求的失败次数大于设定的阀值时,说明服务出现了故障,打开熔断器,这时全部的请求会执行快速失败,不执行业务逻辑。当处于打开状态的熔断器时,一段时间后会处于半打开状态,并执行必定数量的请求,剩余的请求会执行快速失败,若执行的请求失败了,则继续打开熔断器;若成功了,则将熔断器关闭。
这种机制有着很是重要的意义,它不只可以防止系统的"雪崩"效应,还具备如下做用:后端
Netflix的Hystrix熔断器开源组件功能很是强大,不只有熔断器的功能,还有熔断器的状态监测,并提供有好的UI,开发人员或者运维人员经过UI界面可以直观地看到熔断器的状态和各类性能指标。缓存
4.服务网关
微服务系统经过将资源以API接口的形式暴露给外界来提供服务。在微服务系统中,API接口资源一般是由服务网关(也称API网关)统一暴露,内部服务不直接对外提供API资源的暴露。这样作的好处是将内部服务隐藏起来,外界还觉得是一个服务在提供服务,在必定程度上保护了微服务系统的安全。API网关一般有请求转发的做用,另外它可能须要负责必定的安全验证,网关层以集群的形式存在。在服务网关层以前,可能须要加上负载均衡层,一般为Nginx双机热备,经过必定的路由策略,将请求转发到网关层。到达网关层后,通过一系列的用户身份验证、权限判断,最终转发到具体的服务。具体的服务通过一系列的逻辑运算和数据操做,最终将结果返回给用户,此时的架构以下图所示:
网关层具备很重要的意义,具体体如今如下方面:安全
固然,网关实现这些功能,须要作高可用,不然网关极可能成为架构中的瓶颈。最经常使用的网关组件有Zuul、Nginx等。服务器
5.服务配置的统一管理
在实际开发过程当中,每一个服务都有大量的配置文件,例如数据库的配置、日志输出级别的配置等,而每每这些配置在不一样的环境中也是不同的。随着服务数量的增长,配置文件的管理也是一件很是复杂的事。
在微服务架构中,须要有统一管理配置文件的组件,例如Spring Cloud的Spring Cloud Config组件、阿里的Diamond、百度的Disconf、携程的Apollo等。这些配置组件所实现的功能大致相同,可是又有些差异,如下以Spring Cloud Config为例来阐述服务配置的统一管理。大体过程以下如图所示:
网络
对于集群化的服务,能够经过使用消息总线来刷新多个服务实例。若是服务数量较多,对配置中心须要考虑集群化部署,从而使配置中心高可用,作分布式集群。多线程
6.服务链路追踪
微服务系统是一个分布式架构的系统,微服务系统按业务划分服务单元,一个微服务系统每每有不少各服务单元。因为服务单元数量不少且业务复杂,服务与服务之间的调用有可能很复杂,一旦出现了异常和错误,就会很难去定位。因此在微服务架构中,必须实现分布式链路追踪,去跟进一个请求到底有哪些服务参与,参与的顺序又是怎样的,从而使每一个请求链路清晰可见,出了问题很快就能定位。例以下图:
在微服务系统中,一个来自用户的请求先到达前端A(如前端界面),而后经过远程调用,到达系统的中间件B、C(如负载均衡、网关等),最后到达后端服务D、E。后端通过一系列的业务逻辑计算,最后将数据返回给用户。对于这样一个请求,经历了这么多服务,怎么样将其请求过程的参数记录下来呢?这就须要用到服务链路追踪。
Google开源了链路追踪组件Dapper,并在2010年发表了论文《Dapper, a Large-Scale Distributed Systems Tracing In仕astructure》,这篇论文是业内实现链路追踪的标杆和理论基础,具备很是高的参考价值。
目前,常见的链路追踪组件有Google的Dapper、Twitter的Zipkin,以及阿里的Eagleeye(鹰眼)等,都是很是优秀的链路追踪开源组件。
1.Spring Cloud简介
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 Resouces社区,有Pivotal和Netflix两大公司和一些其它的开发者提供技术上的更新迭代。Spring Cloud提供了开发分布式微服务系统的一些经常使用组建,例如服务注册和发现、配置中心、熔断器、智能路由、微代理、控制总线、全局锁、分布式会话等。
2.经常使用组件
(1)服务注册和发现组件 Eureka
利用Eureka组件能够很轻松地实现服务的注册和发现功能。Eureka组件提供了服务的健康监测,以及界面友好的UI。经过Eureka组件提供的UI,Eureka组建可让开发人员随时了解服务单元的运行状况。另外Spring Cloud也支持Consul和Zookeeper,用于注册和服务发现。
(2)熔断组件 Hystrix
Hystrix是一个熔断组件,它除了有一些基本的熔断器功能外,还可以实现服务降级、服务限流的功能。另外Hystrix提供了熔断器的健康监测,以及熔断器健康数据的API接口。Hystrix Dashboard组件提供了单个服务熔断器的健康状态数据的界面展现功能,Hystrix Turbine组件提供了多个服务的熔断器的健康状态数据的界面展现功能。
(3)负载均衡组件 Ribbon
Ribbon是一个负载均衡组件,它一般和Eureka、Zuul、RestTemplate、Feign配合使用。Ribbon和Zuul配合,很容易作到负载均衡,将请求根据负载均衡策略分配到不一样的服务实例中。Ribbon和RestTemplate、Feign配合,在消费服务时可以作到负载均衡。
(4)路由网关 Zuul
路由网关Zuul有只能路由和过滤的功能。内部服务的API接口经过Zuul网关统一对外暴露,内部服务的API接口不直接暴露,防止了内部服务敏感信息对外暴露。在默认状况下,Zuul和Ribbon相结合,可以作到负载均衡、智能路由。Zuul的过滤功能是经过拦截请求来实现的,能够对一些用户的角色和权限进行判断,起到安全验证的做用,同时也能够用于输出实时的请求日志。
上述4各组件都来自于Netflix公司,统一称为Spring Cloud Netflix。
(5)Spring Cloud Config
Spring Cloud Config组件提供了配置文件统一管理的功能。Spring Cloud Config包括Server端和Client端,Server端读取本地仓库或远程仓库的配置文件,全部的Client向Server读取配置信息,从而达到配置文件统一管理的目的。一般状况下,Spring Cloud Config和Spring Cloud Bus相互配置刷新指定Client或全部Client的配置文件。
(6)Spring Cloud Security
Spring Cloud Security是对Spring Security组件的封装,Spring Cloud Security向服务单元提供了用户验证和权限认证。通常来讲,单独再微服务系统中使用Spring Cloud Security是不多见的,通常它会配合Spring Security OAuth2组件一块儿使用,经过搭建受权服务,验证Token或者JWT这种形式对整个微服务系统进行安全验证。
(7)Spring Cloud Sleuth
Spring Cloud Sleuth是一个分布式链路追踪组件,它封装了Dapper、Zipkin和Kibana等组件,经过它能够知道服务之间的相互依赖关系,并实时观察链路的调用状况。
(8)Spring Cloud Stream
Spring Cloud Stream是Spring Cloud框架的数据流操做包,能够封装RabbitMQ、ActiveMQ、Kafka、Redis等消息组件,利用Spring Cloud Stream能够实现消息的接收和发送。
上述列举了一些经常使用的Spring Cloud组件。一个简单的由Spring Cloud构建的微服务系统,一般由服务注册中心Eureka、网关Zuul、配置中心Config和受权服务Auth构成,其架构以下图所示:
Dubbo是阿里巴巴开源的一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。Dubbo普遍用于阿里巴巴的各大站点,有不少互联网公司也在使用这个框架,它包含的核心内容以下:
Dubbo框架图以下所示:
Dubbo框架的流程以下:
Dubbo是一个很是优秀的服务治理框架,在国内互联网公司应用普遍,它具备如下特性:
首先,从微服务关注点来比较Spring Cloud和Dubbo两大服务框架,以下表所示:
Spring Cloud拥有不少的项目模块,包含了微服务系统的方方面面。Dubbo是一个很是优秀的服务治理和服务调用框架,但缺乏不少功能模块,例如网关、链路追踪等。在项目模块上,Spring Cloud占据更大的优点。
Spring Cloud的更新速度很是快,从GitHub的代码仓库来看,Spring Cloud几乎天天都有更新。
从学习成原本看,Dubbo版本趋于稳定,文档完善,能够即学即用,没有太大难度。Spring Cloud基于Spring Boot开发,须要开发者先学会Spring Boot。另外Spring Cloud版本迭代块,须要快速跟进学习。
从开发风格上来说,Dubbo更倾向于Spring Xml的配置方式,Dubbo官方也推荐这种方式。Spring Cloud基于Spring Boot,Spring Boot采用的是基于注解和JavaBean配置方式的敏捷开发。从开发速度上讲,Spring Cloud具备更高的开发和部署速度。
最后,Spring Cloud的通讯方式大多数时基于HTTP Restful风格的,服务与服务之间彻底无关、无耦合。因为采用的是HTTP Restful,所以服务无关乎语言和平台,只须要体统相应API接口,就能够调用。Dubbo的通讯方式基于远程调用,对接口、平台和语言有强依赖性。若是须要实现跨平台调用服务,须要写额外的中间件,这也是Dubbo
存在的缘由。
Kubernetes是一个容器集群管理系统,为容器化的应用程序提供部署运行、维护、扩展、资源调度、服务发现等功能。Kubernetes时Google运行Borg大规模系统达15年之久的一个经验总结。Kubernetes结合了社区的最佳创意和实践,旨在帮助开发人员将容器打包、动态编排,同时帮助各大公司向微服务方向进行技术演进。其具备如下特色:
Kubernetes开源免费,时Google在过去15年时间里部署、管理微服务的经验结晶,因此目前Kubernetes在技术社区也十分火热,下面看看它提供的功能:
从Kubernetes提供的功能来看,Kubernetes彻底能够成为构建和部署微服务的一个工具,它是从服务编排上实现的,而不是从代码实现的。目前国外有不少知名的公司在使用Kubernetes,如Google、eBay、Pearson等。因为它的开源免费,Microsoft、VMWare、Red Hat、CoreOS等公司纷纷加入并贡献代码。Kubernetes技术吸引了一大批公司和技术爱好者,它已经成为容器管理的领导者。
Spring Could是一个构建微服务的框架,儿Kubernetes是经过对运行的容器的编排来实现构建微服务。二者从构建微服务的角度和实现方式有很大的不一样,但它们提供了构建微服务所需的所有功能。从提供的微服务所需的功能上看,二者不分上下,以下表所示:
Spring Cloud经过众多的类库来实现微服务系统所需的各个组件,同时不断集成优秀的组件,因此Spring Cloud组件是很是完善的。Spring Cloud基于Spring Boot框架,有快速开发、快速部署的优势。对于Java开发者来讲,学习Spring Cloud的成本不高。
Kubernetes在编排上解决微服务的各个功能,例如服务发现、配置管理、负载均衡、容错等。Kubernetes不限于Java平台,也不局限于语言,开发者能够自由选择开发语言进行项目开发。
与Kubernetes相比,Spring Cloud具备如下优势:
与Kubernetes比较,Spring Cloud具备如下缺点:
下面介绍Kubernetes的优势和缺点,优势以下:
Kuberbetes的缺点以下:
Spring Cloud 尝试从Java 类库来实现微服务的全部功能,而Kubernetes 尝试从容器编排上实现全部的微服务功能,二者的实现角度和方式不同。我的以为,二者最终的实现功能和效果上不分胜负,但从实现的方式上来说, Kubernetes 略胜一筹。Kubernetes 面向DevOps 人员,学习成本高。Spring Cloud 有不少的类库,以Spring 为基础,继承了Spring Boot 快速开发的优势,为Java 程序员开发微服务提供了很好的体验,学习成本也较低。因此两者比较,各有优点。没有最好的框架,也没有最好的工具,关键是要适合业务需求和知足业务场呆。