第1章 基础知识
什么是微服务架构:
“微服务”一词源于Martin Fowler名为Mircroservices的博文,可以在他的官方博客找到:https://martinfowler.com/articles/microservices.html
微服务是系统架构上的一种设计风格,它的主旨是将一个原本独立的系统拆分成多个小型服务,这些小型服务都在各自独立的进程中运行,服务
之间通过基于HTTP的RESTful API进行通信协作。被拆分成的每一个小型服务都为绕这系统中的某一项或某一些耦合度较高的业务功能进行构建,
并且每个服务都维护着自身的数据库存储、业务开发、自动化测试案列以及独立部署机制。由于有了轻量级的通信协作基础,所以微服务可以使
用不同的语言来编写。
与单体系统的区别:
传统农的企业系统项目架构中,针对每一个复杂的业务需求通常使用对象或业务类型来构建一个单体项目。项目中通常将需求分为三个主要部分:
数据库、服务端处理、前端展现。在业务初期,由于所有业务逻辑都在一个应用中,开发、测试、部署较容易且方便。随着企业的发展,系统为应对
不同的业务需求会不断为该单体项目增加不同的业务模块;同时间随着移动端设备的进步,前端展现模块已经不仅仅局限于web形式,对于系统后藕断
向前端的支持需要更多的接口模块。单体应用由于面对的业务需求更为宽泛,不断扩大的需求会使得单体应用变得越来越臃肿。单体应用的问题就
凸显出来,由于单体系统部署在一个进程内,往往我们修改了一个很小的功能,为了部署上线会影响其他功能的运行。并且,单体应用中的这些模块
使用场景、并发量、消耗的资源类型都各不同,对于资源的利用又相互影响,这样使得我们对各个业务模块的系统容量很难给出较为准确的评估。所以,
单体系统在初期可以非常方便地进行开发和使用,但是随着系统的发展,维护成本会变得越来越大,难以控制。
为了解决单体系统变得臃肿之后产生的难维护问题,微服务架构诞生了并被大家所关注。将系统中的不同功能模块拆分成不同的服务,这些服务都能够
独立部署和扩展。由于每个服务都运行在自己的进程内,在部署上有稳固的边界,这样每个㐏的更新都不会影响其他服务的运行。同时,由于是独立部署的,
可以更准确地为每个服务评估性能容量,通过配合服务间的协作流程也可以更容易地方发现系统的瓶颈位置,以及给出较为准确的系统级性能容量评估。
如何实施微服务:
在实施微服务之前,必须知道,微服务岁虽然有非常多吸引人的优点,但是也因为服务的拆分引发了诸多原本在单体应用中没有的问题。
运维的新挑战:在微服务架构中,运维人员需要维护的进程数量会大大增加。有条不紊地将这些进程编排和组织起来不是一件容易的事,传统的运
维人员往往很难适应这样的变化。运维过程需要更多的自动化,这就要求运维人员有更多的技能来应对这样的挑战,这就要求运维人员具备一定的开发能力
来编排运维过程并让它们能自动运行起来。
接口的一致性:虽然拆分了服务,但是业务逻辑上的依赖并不会消除,只是从单体应用中的代码依赖变为了服务间通信依赖。而当原有接口进行了一些
修改,那么交互方也需要协调这样的改变来进行发布,以保证接口的正确调用。需要更完善的接口和版本管理,或是严格地遵循开闭原则。
分布式的复杂性:拆分后的各个微服务都是独立部署并运行在各自的进程内,它们只能通过通信来进行协作,所以分布式环境的问题都将是微服务架构
系统设计时需要考虑的重要因素,比如 网络延迟、分布式事务、异步消息等。
尽管微服务架构有很多缺点和问题,但是其是休闲的敏捷开发和自动化部署等优点依然被广大优秀架构师和开发者所青睐,解决这些问题是这几年
诸多架构师努力的目标。
在架构师对于一个大型系统架构的设计与实施的过程中,面对环境、资源、团队等各种因素的影响,几乎不会出现完全相同的架构设计。对于微服务架构
并没有一个标准或正式的定义,每位架构师都根据自身理解与实际情况来进行设计,并在发展的过程中不断演化与完善。经过多年的发展,Martin Fowler在
Microsevices一文中,提炼出微服务架构的九大特性,用于指导大家设计架构。
服务组件化
按业务组织团队
做“产品”的态度
智能端的与哑管道
在单体应用中,组件间直接通过函数调用的方式进行交互协作。在微服务架构中,由于服务不在一个进程中,组件间的通信模式发生了改变,若仅仅将原本在
进程内的方法调用改成rpc方式调用,会导致微服务之间产生繁琐的通信,使得系统表现更为糟糕,所以需要更粗粒度的通信协议。
在微服务架构中,通常会使用一下两种调用方式:
第一种,使用HTTP的RESTful API或轻量级的消息发送协议,实现信息传递与服务调用的触发。
第二种,通过在轻量级的消息总线上传递消息,类似RabbitMQ等一些提供可靠异步交换的中间件。
去中心化治理
当采用集中化的架构之类方案时,通常在技术平台上都会制定统一的标准,但是每一种技术平台都有短板,这会导致在碰到短板时,不得不花大力气解决,
并且可能给因为其底层原因解决得不很好,最终成为系统的瓶颈。
在实施微服务架构时,通过采用轻量级的契约定义接口,使得我们对于服务本身的具体技术平台不在那么敏感,这样整个架构系统中的各个组件就能
针对不同的业务特点选择不同的技术平台,终于不会再出现杀鸡用牛刀或是杀牛用指甲钳的尴尬处境。不是每一个问题都是钉子,不是每一个解决方案都是锤子。
去中心化管理数据
在实施微服务架构时,都希望让每一个服务来管理其自有的数据库,这就是数据管理的去中心化。在去中心化的过程中,除了将原数据库的存储内容才拆分
到新平台的其他数据库实例中之外(如把原来存储在MySQL中的表拆分后,存储到多个不同的MySQL实例中),也可以将一些具有特殊结构或业务特性性
的数据存储到一些其他的数据库实例中(如把日志信息存储到MongoDB中或把用户登录信息存储到Redis)。虽然数据管理的去中心化可以让数据管理更加细致化,
通过采用更合适的技术可以让数据存储的性能达到最优。但是,数据存储由于不同于数据库实例中后,数据一致性也成了微服务架构中待解决的问题之一。
分布式事务本身的实现难度就非常大,所以在微服务架构中,我们更强调在各服务之间进行“无事务”的调用,而对于数据一致性,只要求数据在最后的
处理状态是一致的即可;若在过程中发现错误,通过补偿机制进行处理,使得错误数据能够达到最终一致性。
基础设施自动化
随着云计算服务和容器技术的不断成熟,运维基础设施工作变得越来越容易。实施微服务架构时,数据库、应用程序的个头虽然都变小了。但是因为拆分的原因,
数量成倍增长。这使得运维人员需要关注的内容也成倍增长,并且操作性任务也会成倍增长。这些问题若没有得到妥善解决,必将是运维人员的噩梦。
所以,在微服务架构中,务必一开始就构建起“持续交付”平台支持整个实施过程,该平台需要两大内容,缺一不可。
自动化测试:每次部署前的强心剂,尽可能地获得对正在运行软件的信心。
自动化部署:解放烦琐枯燥的重复操作以及对多环境的配置管理。
容错设计
在单体应用中,一般不存在单个组件故障而其他部件还能运行的情况,通常是一挂全挂。而在微服务架构中,由于服务都运行在独立的进程中,所以存在部分
服务出现故障,而其他服务正常运行。比如,当正常运作的服务B调用到故障服务A时,因故障服务A没有返回,线程挂起开始等待,直到超时才能释放,
而此时若触发服务B调用服务A的请求来自服务C,而服务C频繁调用服务B时,由于其依赖服务A,线程大量被挂起等待,最后导致服务A也不能正常服务,
这时就会出现故障蔓延。所以,在微服务架构中,快速检测出故障源并尽可能地自动恢复服务是必须被设计和考虑的。通常,我们都希望在每个服务中实现监控和
日志记录的组件,比如服务状态、断路器状态、吞吐量、网络延迟等关键数据的仪表盘。
演进式设计
通过上面的几点特征,我们已经能够体会到,要实施一个完美的微服务架构,需要考虑的设计与成本并不小,对于没有足够经验的团队来说,甚至要比
单体应用付出更多的代价。所以,很多情况下,架构师都会以演进的方式进行系统构建。在初期,以单体系统的方式来设计和实施,一方面系统体量
初期不会很大,构建和维护成本都不高。另一方面,初期的核心业务在后期通常也不会发生巨大的改变。随着系统的发展或者业务的需要,架构师会将
一些经常变动或是有一定时间效应的内容进行微服务处理,并逐渐将原来在单体系统中多变的模块逐步拆分出来,而稳定不太变化的模块就形成了一个核心微服务存在
整个架构之中。
为什么选择Spring Cloud
近几年很多人对于微服务架构的热情非常高,但是回头看“微服务”被提及也有很多年了。无数的架构师和开发者在实际项目中实践该设计理念并为此付出了诸多努力,
同时也分享了他们在微服务架构中针对不同应用更场景出现的各种问题的各种解决方案和开源框架:
服务治理:Dubbo 、 DubboX 、Netflix的Eureka、Apache的Consul等。
分布式配置管理:百度的Disconf、Netflix的Archaius、360的QConf、Spring Cloud的Config、淘宝的Diamond等。
批量任务:当当的Elasitc-Job、LinkedIn的Azkaban、Spring Cloud的Task等。
服务跟踪:京东的Hydra、Spring Cloud的Sleuth、Twitter的Zipkin等。
。。。
Spring Cloud 简介
Spring Cloud是一个基于Spring Boot实现的微服务架构开发工具。它为微服务架构中设计的配置管理、服务治理、断路器、智能路由、微代理、控制总线、
全局锁、决策精选、分布式会话和集群状态管理等操作提供了一种简单的开发方式。
Spring Cloud 包含了多个子项目:
Spring Cloud Config:配置管理工具,支持使用Git存储配置内容,可以使用它实现应用配置的外部化存储,并且支持客户端配置信息刷新、加密/解密配置内容等。
Spring Cloud Netflix:核心组件,对多个Netflix OSS开源套件进行整合。
Eurka:服务治理组件,包含服务注册中心、服务注册与发现机制的实现。
Hystrix:容错管理组件,实现断路器模式,帮助服务依赖中出现的延迟和故障提供强大的容错能力。
Ribbon:客户端负载均衡的服务调用组件。
Feign:基于Ribbon和Hystrix声明式调用组件。
Zuul:网关组件,提供智能路由、访问过滤等功能。
Archaius:外部化配置组件。
Spring Cloud Bus:事件、消息总线,用于传播集群中的状态变化或事件,以触发后续的处理,比如动态刷新配置等。
Spring Cloud Cluster:针对ZooKeeper、Redis、Hazelcast、Consul的选举算法和童永刚的状态模式的实现。
Spring Cloud Cloudfoundry:与Pivotal Cloudfoundry的整合支持。
Spring Cloud Consul:服务发现与配置管理工具。
Spring Cloud Stream:通过Redis、Rabbit或者Kafka实现消费微服务,可以通过简单的声明式模型来发送和接收消息。
Spring Cloud AWS:用于简化整合Amazon Web Service的组件。
Spring Cloud Security:安全工具包,提供在Zuul代理中对OAuth2客户端请求的中继器。
Spring Cloud Sleuth:Spring Cloud 应用的分布式跟踪实现,可以完美整合Zipkin。
Spring Cloud Zookeeper:基于Zookeeper的服务发现与配置管理组件。
Spring Cloud Starters:Spring Cloud 的基础组件,它是基于Spring Boot 风格项目的基础依赖模块。
Spring Cloud CLI:用于在Groovy中快速创建Spring Cloud应用的Spring Boot CLI插件。
。。。
Spring Cloud 的版本及版本号,自行百度:https://www.baidu.com