Spring Cloud

微服务框架 Spring Cloud 介绍

Posted by leone on 2019-01-18

Spring Cloud

微服务入门核心概念

什么是微服务

微服务 (Microservices) 是一种软件架构风格,它是以专注于单一责任与功能的小型功能区块 (Small Building Blocks) 为基础,利用模组化的方式组合出复杂的大型应用程序,各功能区块使用与语言无关 (Language-Independent/Language agnostic) 的 API 集相互通讯。微服务的起源是由 Peter Rodgers 博士于 2005 年度云端运算博览会提出的微 Web 服务 (Micro-Web-Service) 开始,Juval Löwy 则是与他有类似的前导想法,将类别变成细粒服务 (granular services),以作为 Microsoft 下一阶段的软件架构,其核心想法是让服务是由类似 Unix 管道的存取方式使用,而且复杂的服务背后是使用简单 URI 来开放界面,任何服务,任何细粒都能被开放 (exposed)。这个设计在 HP 的实验室被实现,具有改变复杂软件系统的强大力量。2014年,Martin Fowler 与 James Lewis 共同提出了微服务的概念,定义了微服务是由以单一应用程序构成的小服务,自己拥有自己的行程与轻量化处理,服务依业务功能设计,以全自动的方式部署,与其他服务使用 HTTP API 通讯。同时服务会使用最小的规模的集中管理 (例如 Docker) 能力,服务可以用不同的编程语言与数据库等元件实作。

微服务核心概念

微服务是一种以业务功能为主的服务设计概念,每一个服务都具有自主运行的业务功能,对外开放不受语言限制的 API (最常用的是 HTTP),应用程序则是由一个或多个微服务组成。

微服务的另一个对比是单体式应用程序。单体式应用表示一个应用程序内包含了所有需要的业务功能,并且使用像主从式架构 (Client/Server) 或是多层次架构 (N-tier) 实作,虽然它也是能以分散式应用程序来实作,但是在单体式应用内,每一个业务功能是不可分割的。若要对单体式应用进行扩展则必须将整个应用程序都放到新的运算资源(如:虚拟机器) 内,但事实上应用程序中最吃资源、需要运算资源的仅有某个业务部分(例如跑分析报表或是数学算法分析),但因为单体式应用无法分割该部分,因此无形中会有大量的资源浪费的现象。

微服务运用了以业务功能的设计概念,应用程序在设计时就能先以业务功能或流程设计先行分割,将各个业务功能都独立实作成一个能自主执行的个体服务,然后再利用相同的协定将所有应用程序需要的服务都组合起来,形成一个应用程序。若需要针对特定业务功能进行扩充时,只要对该业务功能的服务进行扩展就好,不需要整个应用程序都扩展,同时,由于微服务是以业务功能导向的实作,因此不会受到应用程序的干扰,微服务的管理员可以视运算资源的需要来配置微服务到不同的运算资源内,或是布建新的运算资源并将它配置进去。

虽然使用一般的服务器虚拟化技术就能应用于微服务的管理,但容器技术 (Container Technology) 如 Docker 会更加地适合发展微服务的运算资源管理技术。

Spring Cloud 前言

Spring Cloud是基于Spring Boot的一整套实现微服务的框架。他提供了微服务开发所需的配置管理、服务发现、断路器、智能路由、微代理、控制总线、全局锁、决策竞选、分布式会话和集群状态管理等组件。最重要的是, 跟spring boot框架一起使用的话,会让你开发微服务架构的云服务非常好的方便。SpringBoot旨在简化创建产品级的 Spring 应用和服务,简化了配置文件,使用嵌入式web服务器,含有诸多开箱即用微服务功能

微服务架构是互联网很热门的话题,是互联网技术发展的必然结果。它提倡将单一应用程序划分成一组小的服务,服务之间互相协调、互相配合,为用户提供最终价值。虽然微服务架构没有公认的技术标准和规范或者草案,但业界已经有一些很有影响力的开源微服务架构框架提供了微服务的关键思路,例如 dubbo 和 Spring Cloud,各大互联网公司也有自研的微服务框架,但其模式都于这二者相差不大。

Spring Cloud 全家桶

  • Spring Cloud Config:配置管理开发工具包,可以让你把配置放到远程服务器,目前支持本地存储、Git以及Subversion。

  • Spring Cloud Bus:事件、消息总线,用于在集群(例如,配置变化事件)中传播状态变化,可与Spring Cloud Config联合实现热部署。

  • Spring Cloud Netflix:针对多种Netflix组件提供的开发工具包,其中包括Eureka、Hystrix、Zuul、Archaius等。

  • Netflix Eureka:云端负载均衡,一个基于 REST 的服务,用于定位服务,以实现云端的负载均衡和中间层服务器的故障转移。

  • Netflix Hystrix:容错管理工具,旨在通过控制服务和第三方库的节点,从而对延迟和故障提供更强大的容错能力。

  • Netflix Zuul:边缘服务工具,是提供动态路由,监控,弹性,安全等的边缘服务。

  • Netflix Archaius:配置管理API,包含一系列配置管理API,提供动态类型化属性、线程安全配置操作、轮询框架、回调机制等功能。

  • Spring Cloud for Cloud Foundry:通过Oauth2协议绑定服务到CloudFoundry,CloudFoundry是VMware推出的开源PaaS云平台。

  • Spring Cloud Sleuth:日志收集工具包,封装了Dapper,Zipkin和HTrace操作。

  • Spring Cloud Data Flow:大数据操作工具,通过命令行方式操作数据流。

  • Spring Cloud Security:安全工具包,为你的应用程序添加安全控制,主要是指OAuth2。

  • Spring Cloud Consul:封装了Consul操作,consul是一个服务发现与配置工具,与Docker容器可以无缝集成。

  • Spring Cloud Zookeeper:操作Zookeeper的工具包,用于使用zookeeper方式的服务注册和发现。

  • Spring Cloud Stream:数据流操作开发包,封装了与Redis,Rabbit、Kafka等发送接收消息。

  • Spring Cloud CLI:基于 Spring Boot CLI,可以让你以命令行方式快速建立云组件。

微服务主要的优势如下:

1.降低复杂度

将原来偶合在一起的复杂业务拆分为单个服务,规避了原本复杂度无止境的积累。每一个微服务专注于单一功能,并通过定义良好的接口清晰表述服务边界。每个服务开发者只专注服务本身,通过使用缓存、DAL 等各种技术手段来提升系统的性能,而对于消费方来说完全透明。

2.可独立部署

由于微服务具备独立的运行进程,所以每个微服务可以独立部署。当业务迭代时只需要发布相关服务的迭代即可,降低了测试的工作量同时也降低了服务发布的风险。

3.容错

在微服务架构下,当某一组件发生故障时,故障会被隔离在单个服务中。 通过限流、熔断等方式降低错误导致的危害,保障核心业务正常运行。

4.扩展

单块架构应用也可以实现横向扩展,就是将整个应用完整的复制到不同的节点。当应用的不同组件在扩展需求上存在差异时,微服务架构便体现出其灵活性,因为每个服务可以根据实际需求独立进行扩展。

微服务架构优势

复杂度可控:在将应用分解的同时,规避了原本复杂度无止境的积累。每一个微服务专注于单一功能,并通过定义良好的接口清晰表述服务边界。由于体积小、复杂度低,每个微服务可由一个小规模开发团队完全掌控,易于保持高可维护性和开发效率。

独立部署:由于微服务具备独立的运行进程,所以每个微服务也可以独立部署。当某个微服务发生变更时无需编译、部署整个应用。由微服务组成的应用相当于具备一系列可并行的发布流程,使得发布更加高效,同时降低对生产环境所造成的风险,最终缩短应用交付周期。

技术选型灵活:微服务架构下,技术选型是去中心化的。每个团队可以根据自身服务的需求和行业发展的现状,自由选择最适合的技术栈。由于每个微服务相对简单,故需要对技术栈进行升级时所面临的风险就较低,甚至完全重构一个微服务也是可行的。

容错:当某一组建发生故障时,在单一进程的传统架构下,故障很有可能在进程内扩散,形成应用全局性的不可用。在微服务架构下,故障会被隔离在单个服务中。若设计良好,其他服务可通过重试、平稳退化等机制实现应用层面的容错。

扩展:单块架构应用也可以实现横向扩展,就是将整个应用完整的复制到不同的节点。当应用的不同组件在扩展需求上存在差异时,微服务架构便体现出其灵活性,因为每个服务可以根据实际需求独立进行扩展。

什么是 Spring Boot

Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。用我的话来理解,就是Spring Boot其实不是什么新的框架,它默认配置了很多框架的使用方式,就像maven整合了所有的jar包,Spring Boot整合了所有的框架(不知道这样比喻是否合适)。

Spring Boot简化了基于Spring的应用开发,通过少量的代码就能创建一个独立的、产品级别的Spring应用。 Spring Boot为Spring平台及第三方库提供开箱即用的设置,这样你就可以有条不紊地开始。Spring Boot的核心思想就是约定大于配置,多数Spring Boot应用只需要很少的Spring配置。采用Spring Boot可以大大的简化你的开发模式,所有你想集成的常用框架,它都有对应的组件支持。

Spring Cloud 都做了哪些事

Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署。Spring并没有重复制造轮子,它只是将目前各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,通过Spring Boot风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包

微服务中必备的核心组件

  • 配置管理

  • 控制总线

  • 集群管理

  • 安全机制

  • Session管理

  • Failback

  • 智能路由

  • 网关管理

  • 服务发现

三者之间的关系

微服务是一种架构的理念,提出了微服务的设计原则,从理论为具体的技术落地提供了指导思想。Spring Boot是一套快速配置脚手架,可以基于Spring Boot快速开发单个微服务;Spring Cloud是一个基于Spring Boot实现的服务治理工具包;Spring Boot专注于快速、方便集成的单个微服务个体,Spring Cloud关注全局的服务治理框架。
Spring Boot/Cloud是微服务实践的最佳落地方案。

Spring Cloud 和 Dubbo 对比

1)从两个公司的背景来谈:Dubbo,是阿里巴巴服务化治理的核心框架,并被广泛应用于中国各互联网公司;Spring Cloud是大名鼎鼎的Spring家族的产品。阿里巴巴是一个商业公司,虽然也开源了很多的顶级的项目,但从整体战略上来讲,仍然是服务于自身的业务为主。Spring专注于企业级开源框架的研发,不论是在中国还是在世界上使用都非常广泛,开发出通用、开源、稳健的开源框架就是他们的主业。

2)从社区活跃度这个角度来对比,Dubbo虽然也是一个非常优秀的服务治理框架,并且在服务治理、灰度发布、流量分发这方面做的比Spring Cloud还好,除过当当网在基础上增加了rest支持外,已有两年多的时间几乎都没有任何更新了。在使用过程中出现问题,提交到github的Issue也少有回复。

相反Spring Cloud自从发展到现在,仍然在不断的高速发展,从github上提交代码的频度和发布版本的时间间隔就可以看出,现在Spring Cloud即将发布2.0版本,到了后期会更加完善和稳定。

  1. 从整个大的平台架构来讲,dubbo框架只是专注于服务之间的治理,如果我们需要使用配置中心、分布式跟踪这些内容都需要自己去集成,这样无形中使用dubbo的难度就会增加。Spring Cloud几乎考虑了服务治理的方方面面,更有Spring Boot这个大将的支持,开发起来非常的便利和简单。

4)从技术发展的角度来讲,Dubbo刚出来的那会技术理念还是非常先进,解决了各大互联网公司服务治理的问题,中国的各中小公司也从中受益不少。经过了这么多年的发展,互联网行业也是涌现了更多先进的技术和理念,Dubbo一直停滞不前,自然有些掉队,有时候我个人也会感到有点可惜,如果Dubbo一直沿着当初的那个路线发展,并且延伸到周边,今天可能又是另一番景象了。

Spring 推出Spring Boot/Cloud也是因为自身的很多原因。Spring最初推崇的轻量级框架,随着不断的发展也越来越庞大,随着集成项目越来越多,配置文件也越来越混乱,慢慢的背离最初的理念。随着这么多年的发展,微服务、分布式链路跟踪等更多新的技术理念的出现,Spring急需一款框架来改善以前的开发模式,因此才会出现Spring Boot/Cloud项目,我们现在访问Spring官网,会发现Spring Boot和Spring Cloud已经放到首页最重点突出的三个项目中的前两个,可见Spring对这两个框架的重视程度。

如何实施微服务?

1、服务组件化
组件,是一个可以独立更换和升级的单元。就像PC中的CPU、内存、显卡、硬盘一样,独立且可以更换升级而不影响其他单元。
在“微服务”架构中,需要我们对服务进行组件化分解。服务,是一种进程外的组件,它通过http等通信协议进行协作,而不是传统组件以嵌入的方式协同工作。服务都独立开发、部署,可以有效的避免一个服务的修改引起整个系统的重新部署。

2、按业务组织团队
当我们开始决定如何划分“微服务”时,通常也意味着我们要开始对团队进行重新规划与组织。按以往的方式,我们往往会以技术的层面去划分多个不同的团队,比如:DBA团队、运维团队、后端团队、前端团队、设计师团队等等。若我们继续按这种方式组织团队来实施“微服务”架构开发时,当有一个有问题需要更改,可能是一个非常简单的变动,比如:对人物描述增加一个字段,这就需要从数据存储开始考虑一直到设计和前端,虽然大家的修改都非常小,但这会引起跨团队的时间和预算审批。
在实施“微服务”架构时,需要采用不同的团队分割方法。由于每一个微服务都是针对特定业务的宽栈或是全栈实现,既要负责数据的持久化存储,又要负责用户的接口定义等各种跨专业领域的职能。因此,面对大型项目时候,对于微服务团队拆分更加建议按业务线的方式进行拆分,一方面可以有效减少服务内部修改所产生的内耗;另一方面,团队边界可以变得更为清晰。

3、做“产品”的态度
实施“微服务”架构的团队中,每个小团队都应该以做产品的方式,对其产品的整个生命周期负责。而不是以项目的模式,以完成开发与交付并将成果交接给维护者为最终目标。
开发团队通过了解服务在具体生产环境中的情况,可以增加他们对具体业务的理解,比如:很多时候一些业务中发生的特殊或异常情况,很可能产品经理都并不知晓,但细心的开发者很容易通过生产环境发现这些特殊的潜在问题或需求。
所以,我们需要用做“产品”的态度来对待每一个“微服务”,持续关注服务的运作情况,并不断地分析帮助用户来提升业务功能。

4、轻量化通信机制
在单体应用中,组件间直接通过函数调用的方式进行交互协作。而在“微服务”架构中,服务由于不在一个进程中,组件间的通信模式发生了改变,若仅仅将原本在进程内的方法调用改成RPC方式的调用,会导致微服务之间产生繁琐的通信,使得系统表现更为糟糕,所以,我们需要更粗粒度的通信协议。
在“微服务”架构中,通常会使用这两个服务调用方式:
第一种,使用HTTP协议的RESTful API或轻量级的消息发送协议,来实现信息传递与服务调用的触发。
第二种,通过在轻量级消息总线上传递消息,类似RabbitMQ等一些提供可靠异步交换的结构。
在极度强调性能的情况下,有些团队会使用二进制的消息发送协议,例如:protobuf。

5、去中心化治理
当我们采用集中化的架构治理方案时,通常在技术平台上都会做统一的标准,但是每一种技术平台都有其短板,这会导致在碰到短板时,不得不花费大力气去解决,并且可能还是因为其底层原因解决的不是很好。
在实施“微服务”架构时,通过采用轻量级的契约定义接口,使得我们对于服务本身的具体技术平台不再那么敏感,这样我们整个“微服务”架构的系统中的组件就能针对其不同的业务特点选择不同的技术平台,终于不会出现杀鸡用牛刀或是杀牛用指甲钳的尴尬处境了。

6、去中心化管理数据
我们在实施“微服务”架构时,都希望可以让每一个服务来管理其自有的数据库,这就是数据管理的去中心化。
在去中心化过程中,我们除了将原数据库中的存储内容拆分到新的同平台的其他数据库实例中之外(如:把原本存储在MySQL中的表拆分后,存储多几个不同的MySQL实例中),也可以针对一些具有特殊结构或业务特性的数据存储到一些其他技术的数据库实例中(如:把日志信息存储到MongoDB中、把用户登录信息存储到Redis中)。
虽然,数据管理的去中心化可以让数据管理更加细致化,通过采用更合适的技术来让数据存储和性能达到最优。但是,由于数据存储于不同的数据库实例中后,数据一致性也成为“微服务”架构中急需解决的问题之一。分布式事务的实现,本身难度就非常大,所以在“微服务”架构中,我们更强调在各服务之间进行“无事务”的调用,而对于数据一致性,只要求数据在最后的处理状态是一致的效果;若在过程中发现错误,通过补偿机制来进行处理,使得错误数据能够达到最终的一致性。

7、基础设施自动化
近年来云计算服务与容器化技术的不断成熟,运维基础设施的工作变得越来越不那么难了。但是,当我们实施“微服务”架构时,数据库、应用程序的个头虽然都变小了,但是因为拆分的原因,数量成倍的增长。这使得运维人员需要关注的内容也成倍的增长,并且操作性任务也会成倍的增长,这些问题若没有得到妥善的解决,必将成为运维人员的噩梦。
所以,在“微服务”架构中,请务必从一开始就构建起“持续交付”平台来支撑整个实施过程,该平台需要两大内容,不可或缺:
自动化测试:每次部署前的强心剂,尽可能的获得对正在运行软件的信心。
自动化部署:解放繁琐枯燥的重复操作以及对多环境的配置管理。

8、容错设计
在单体应用中,一般不存在单个组件故障而其他还在运行的情况,通常是一挂全挂。而在“微服务”架构中,由于服务都运行在独立的进程中,所以是存在部分服务出现故障,而其他服务都正常运行的情况,比如:当正常运作的服务B调用到故障服务A时,因故障服务A没有返回,线程挂起开始等待,直到超时才能释放,而此时若触发服务B调用服务A的请求来自服务C,而服务C频繁调用服务B时,由于其依赖服务A,大量线程被挂起等待,最后导致服务C也不能正常服务,这时就会出现故障的蔓延。
所以,在“微服务”架构中,快速的检测出故障源并尽可能的自动恢复服务是必须要被设计和考虑的。通常,我们都希望在每个服务中实现监控和日志记录的组件,比如:服务状态、断路器状态、吞吐量、网络延迟等关键数据的仪表盘等。

9、演进式设计
通过上面的几点特征,我们已经能够体会到,要实施一个完美的“微服务”架构,需要考虑的设计与成本并不小,对于没有足够经验的团队来说,甚至要比单体应用发付出更多的代价。
所以,很多情况下,架构师们都会以演进的方式进行系统的构建,在初期系统以单体系统的方式来设计和实施,一方面系统体量初期并不会很大,构建和维护成本都不高。另一方面,初期的核心业务在后期通常也不会发生巨大的改变。随着系统的发展或者业务的需要,架构师们会将一些经常变动或是有一定时间效应的内容进行“微服务”处理,并逐渐地将原来在单体系统中多变的模块逐步拆分出来,而稳定不太变化的就形成了一个核心“微服务”存在于整个架构之中。