将一个单体应用拆分成一组微小的服务组件,每个微小的服务组件运行在自己的进程上,组件之间通过如RESTful API这样的轻量级机制进行交互,这些服务以业务能力为核心,用自动化部署机制独立部署,另外,这些服务可以用不同的语言进行研发,用不同技术来存储数据 。
通过以上的定义描述,我们可以基本确定给出微服务的节特征:
用微服务来进行实践到生产项目中,首先要考虑一些问题。比如下图的微服务业务架构:
在上图图表展示的架构图中,我们假设将业务商户服务A、订单服务B和产品服务C分别拆分为一个微服务应用,单独进行部署。此时,我们面临很多要可能出现的问题要解决,比如:
1、客户端如何访问这些服务?
2、每个服务之间如何进行通信?
3、多个微服务,应如何实现?
4、如果服务出现异常宕机,该如何解决?
以上这些都是问题,需要一个个解决。
在单体应用开发中,所有的服务都是本地的,前端UI界面,移动端APP程序可以直接访问后端服务器程序。
现在按功能拆分成独立的服务,跑在独立的进程中。如下图所示:
此时,后台有N个服务,前台就需要记住管理N个服务,一个服务 下线 、 更新 、 升级 ,前台和移动端APP就要重新部署或者重新发包,这明显不服务我们拆分的理念。尤其是对当下业务需求的飞速发展,业务的变更是非常频繁的。
除了访问管理出现困难以外,N个小服务的调用也是一个不小的网络开销。另外,一般微服务在系统内部,通常是无状态的,而我们的用户在进行业务 *** 作时,往往是跨业务模块进行 *** 作,且需要是有状态的,在此时的这个系统架构中,也无法解决这个问题。传统的用来解决用户登录信息和权限管理通常有一个统一的地方维护管理(OAuth),我们称之为授权管理。
基于以上列出的问题,我们采用一种叫做网关(英文为API Gateway)的技术方案来解决这些问题,网关的作用主要包括:
网关(API Gateway)可以有很多广义的实现办法,可以是一个软硬一体的盒子,也可以是一个简单的MVC框架,甚至是一个Nodejs的服务端。他们最重要的作用是为前台(通常是移动应用)提供后台服务的聚合,提供一个统一的服务出口,解除他们之间的耦合,不过API Gateway也有可能成为 单点故障 点或者性能的瓶颈。
最终,添加了网关(API Gateway)的业务架构图变更为如下所示:
所有的微服务都是独立部署,运行在自己的进程容器中,所以微服务与微服务之间的通信就是IPC(Inter Process Communication),翻译为进程间通信。进程间通信的方案已经比较成熟了,现在最常见的有两大类: 同步调用、异步消息调用 。
同步调用
同步调用比较简单,一致性强,但是容易出调用问题,性能体验上也会差些,特别是调用层次多的时候。同步调用的有两种实现方式:分别是 REST 和 RPC
基于REST和RPC的特点,我们通常采用的原则为: 向系统外部暴露采用REST,向系统内部暴露调用采用RPC方式。
异步消息的方式在分布式系统中有特别广泛的应用,他既能减低调用服务之间的耦合,又能成为调用之间的缓冲,确保消息积压不会冲垮被调用方,同时能保证调用方的服务体验,继续干自己该干的活,不至于被后台性能拖慢。需要付出的代价是一致性的减弱,需要接受数据 最终一致性 ,所谓的最终一致性就是只可能不会立刻同步完成,会有延时,但是最终会完成数据同步;还有就是后台服务一般要实现 幂等性 ,因为消息发送由于性能的考虑一般会有重复(保证消息的被收到且仅收到一次对性能是很大的考验)。最后就是必须引入一个独立的 Broker,作为中间代理池。
常见的异步消息调用的框架有:Kafaka、Notify、MessageQueue。
最终,大部分的服务间的调用架构实现如下所示:
在微服务架构中,一般每一个服务都是有多个拷贝,来做负载均衡。一个服务随时可能下线,也可能应对临时访问压力增加新的服务节点。这就出现了新的问题:
这就是服务的发现、识别与管理问题。解决多服务之间的识别,发现的问题一般是通过注册的方式来进行。
具体来说:当服务上线时,服务提供者将自己的服务注册信息注册到某个专门的框架中,并通过心跳维持长链接,实时更新链接信息。服务调用者通过服务管理框架进行寻址,根据特定的算法,找到对应的服务,或者将服务的注册信息缓存到本地,这样提高性能。当服务下线时,服务管理框架会发送服务下线的通知给其他服务。
常见的服务管理框架有:Zookeeper等框架。
如上的问题解决方案有两种具体的实现,分别是: 基于客户端的服务注册与发现 、 基于服务端的服务注册与发现 。
优点是架构简单,扩展灵活,只对服务注册器依赖。缺点是客户端要维护所有调用服务的地址,有技术难度,一般大公司都有成熟的内部框架支持。
优点是所有服务对于前台调用方透明,一般小公司在云服务上部署的应用采用的比较多。
前面提到,单体应用开发中一个很大的风险是,把所有鸡蛋放在一个篮子里,一荣俱荣,一损俱损。而分布式最大的特性就是网络是不可靠的。通过微服务拆分能降低这个风险,不过如果没有特别的保障,结局肯定是噩梦。
因此,当我们的系统是由一系列的服务调用链组成的时候,我们必须确保任一环节出问题都不至于影响整体链路。相应的手段有很多,比如说:
从上图可以看出单体架构的问题可以通过微服务化拆分来解决。
随着商业模式逐渐得到验证,产品获得了市场的认可,为了加快产品的迭代效率,团队开始引进更多的研发人力,此时业务已经达到了一定的复杂度,单体应用已经无法满足业务增长的需求,研发效率开始下降,这是就是需要考虑服务拆分的时机点。
服务拆分的落地还需要提前准备好配套的基础设施,比如注册中心、配置中心、日志系统、持续交付、监控系统、分布式定时任务、CAP 理论、分布式调用链、API 网关等等;
人才的储备和观念的变化也得同时跟上
服务拆分不仅仅是技术的升级,更是开发方式、组织架构、开发观念的转变
服务拆分粒度太细会增加运维复杂度,粒度过大又起不到效果,如何平衡拆分粒度呢?
产品初期阶段,业务逻辑并没有足够复杂到2~3人没法维护的地步,这时我们没有必要将业务继续拆分的更细,但随着业务的发展,业务逻辑变的越来越复杂,可能同时服务多个平台,这时你会发现服务面临各种问题,这个阶段就需要将服务拆分为更细粒度的服务。虽然业务复杂度已经满足了,但如果没有足够的人力,服务最好也不要拆分,拆分会因为人力的不足导致更多的问题,如研发效率大幅下降。
一个服务需要几个开发维护是比较理性的?
三个火q手原则
三个火q手原则主要应用于微服务设计和开发阶段
拆分策略可以按功能和非功能维度考虑,功能维度主要是划分清楚业务的边界,非功能维度主要考虑六点:扩展性、复用性、高性能、高可用、安全性、异构性。
纵行拆分(基于业务逻辑拆分)
从业务维度进行拆分。标准是按照业务的关联程度来决定,关联比较密切的业务适合拆分为一个微服务,而功能相对比较独立的业务适合单独拆分为一个微服务
横向拆分
从公共且独立功能维度拆分。标准是按照是否有公共的被多个其他服务调用,且依赖的资源独立不与其他业务 耦合。
按领域模型拆分
按领域模型拆分主要是划分清楚业务边界,主要分四步:
1、找出领域实体和值对象等领域对象
2、找出聚合根,根据实体、值对象和聚合根的依赖关系,建立聚合
3、根据业务及语义边界等因素,定义限界上下文
4、每一个限界上下文可以拆分一个对应的服务,但是也要考虑一些非功能因素
扩展性
区分系统中变与不变的部分,不变的部分一般是成熟的、通用的服务功能,变的部分一般是改动比较多、满足业务迭代扩展性需要的功能,我们可以将不变的部分拆分出来,作为公用的服务,将变的部分独立出来满足个性化扩展需要。
二八原则:经常变动的部分大约只占20%,剩下的80%基本不变或极少变化
复用性
不同的业务里或服务里经常会出现重复的功能,比如每个服务都有鉴权、限流、安全以及日志监控等功能,可以将这些通用的功能拆分出来形成独立的服务,也就是微服务里面的API网关。
可靠性
将可靠性要求高的核心服务和可靠性要求相对低的非核心服务拆分开来,然后重点保护核心服务的高可用。
高性能
将性能要求高或者性能压力大的模块拆分出来,避免性能压力大的服务影响其他服务。常见的拆分方式和具体的性能瓶颈有关,例如电商的抢购,性能压力最大的是排队功能,可以将此独立成一个服务;对于读写差异比较大的服务,也可以基于读写分离来拆分;基于数据一致性拆分,将强一致性的业务尽量放在一个服务中,弱一致性通常拆分为不同的服务
安全性
不同的服务可能对信息安全有不同的要求,因此把需要高度安全的服务拆分出来,进行区分部署,可以更有针对性地满足信息安全的要求,也可以降低对防火墙等安全设备吞吐量、并发性等方面的要求,降低成本,提高效率
异构性
对于开发语言种类有要求的业务场景,可以用不同的语言将其功能独立出来实现一个独立服务
以上拆分方式可以根据实际情况自由排列组合使用。拆分不仅仅是架构上的调整,也意味着要在组织结构上做出响应的适应性优化,以确保拆分后的服务由相对独立的团队负责维护
一个系统现在拆分出来的服务粒度也许合适,但随着时间的流失,系统需要不断的适应新的业务发展阶段,我们对系统领域的了解也越来越深,之前拆分的服务粒度可能就不合适了。例如业务的增删导致、过多的进程间通信导致效率低下等因素。
人员和服务数量的不匹配导致的维护成本增加,也是导致服务合并的一个重要原因。
服务数量过多和资源不匹配,则可以考虑合并多个微服务到一个服务包,部署到一台服务器,这样可以节省服务运行时的基础资源消耗,也降低了维护成本。 需要注意的是,虽然服务包是运行在一个进程中,但是服务包内的服务依然要满足微服务定义,以便在未来某一天要重新拆开的时候可以很快就分离
摘要: 最近大家都在谈微服务,随着越来越多的在线业务需要提供更大并发的scale-up 和 scale out能力,微服务确实提供了比较好分布式服务的解决方案。阿里云高级解决方案架构师 杨旭
世界最大混合云的总架构师,4年前,开始作为双11阿里云技术负责人,负责搭建全球最大的混合云结构,把 “双11”的电商业务和技术场景在阿里云上实现,并保障这个混合云在双11当天能够满足全球客户的购物需求。
正文:
最近大家都在谈微服务,随着越来越多的在线业务需要提供更大并发的scale-up 和 scale out能力,微服务确实提供了比较好分布式服务的解决方案。
微服务并不陌生,知道SOA其实也就很容易理解微服务,可以把微服务当做去除了ESB的SOA。ESB是SOA企业服务架构中的总线,而微服务是去中心化的分布式软件架构,个人认为最大的设计区别在于设计初衷:
SOA是为了最大化的实现复杂系统代码的可复用性
而微服务是为了最大限度的解耦,不同业务系统甚至可以是不同语言之间的通信
没有最优的架构,只有最合适的架构,一切系统设计原则都要以解决业务问题为最终目标,脱离实际业务的技术情怀架构往往会给系统带入大坑。所有问题的前提要搞清楚我们今天面临的业务量有多大,增长走势是什么样,而且解决高并发的过程,一定是一个循序渐进逐步的过程。
网上的一张图很经典,总结的非常好:
整个系统进化分为三个阶段:
x轴,水平扩展阶段,通过负载均衡服务器不断的横向扩充应用服务器,水平扩展最重要的问题是需要注意不用服务器之间的如何保持session和会话同步,不能让用户在不通服务器之间切换时有感知应用扩展后自然遇到的问题就是DB的瓶颈:连接数,iops等。
z轴,就是对数据库的拆分,难度上了一个台阶,Sharding的基本思想就要把一个数据库如何进行切分,可以分为水平切分和垂直切分,水平切分相对简单,一主多从,多主都可以,根据业务的需要,多主切分设计时需要注意主键的关系,解决多写在进行数据同步时候的冲突问题,垂直拆分更加复杂,一般都会涉及到架构逻辑的改造,需要引入中间件,来进行数据源的管理,垂直拆分时把关系紧密(比如同一模块)的表切分出来放在一个库上,或者通过hash进行拆分,从而将原有数据库切分成类似矩阵一样可以无限扩充的队列。
y轴扩展,最后就是功能分解了,也就是我们讲的微服务切分。微服务拆分将巨型应用按照功能模块分解为一组组不同的服务,淘宝的系统当年也经历了这样的过程,通过五彩石项目从单一的war包拆分成了今天的大家看到买家,卖家中心,交易等系统。
引入微服务前你要知道的两三事:
1、成本升高,引入微服务架构,需要对原来单一系统进行拆分,1到100以后多服务的部署会带来成本的升高
2、解决分布式事务一致性问题
以前单一的系统好处很多,一条sql解决完成所有业务逻辑,微服务做完一件事情需要涉及多系统调用,系统间网络的不确定性给结果带来很多不确定性,如今天淘宝的系统,完成一次交易下单需要在上百个系统之间调用,如何保证系统的可靠性,以及核心数据如钱的最终一致性是设计之初就要想明白的,这里大多都要借助中间件来实现。
3、微服务的逻辑设计原则
随着不断拆分微服务,以及业务的迭代发展,系统之间极有可能出现混乱调用,所以微服务的顶层设计显得尤为重要,架构师需要搞清楚微服务的架构模型。那核心的设计思想就在于如何进行服务的分层,以及服务的重用,通过分层将服务进行分配,上层服务包装下层服务,下层服务负责原子性的 *** 作,上层服务对下层服务进行业务性的组合编排,一定要理解业务,微服务拆分不是简单的系统组合,再说一遍一定要理解业务,否则上层服务一定会出现大量的交叉调用,系统复杂度会指数级上升,好的微服务架构师一定是业务架构师,基于业务的建瓴,微服务设计三部曲,遵循自下而上的设计原则:
原子服务
首先确认最基本业务最维度的原子服务,原子服务定义就是大家都会最大化重用的功能,需要在应用内的闭环 *** 作,没有任何跨其他服务的分支逻辑,杜绝对其他服务的调用,有自己独立的数据存储,作为最底层服务抽象存在,以淘宝为例,卖家数据,卖家数据,订单数据就属于最基本的原子服务。
服务组合
在业务场景下,一个功能都需要跨越多个原子服务来完成一个动作。组合服务就是将业务逻辑抽象拆成独立自主的域,域之间需要保持隔离,服务组合会使用到多个原子服务来完成业务逻辑,如淘宝的交易平台会调用用户,商品,库存等系统。
业务编排
最外层就是面向用户的业务流程,一个产品化的商业流程需要对组合服务进行逻辑编排来完成最终的业务结果,这个编排服务可以完全是自动化的,通过工作流引擎进行组合自动化来完成特定SOP定义,这对企业应用的自动化流程改进也很有意义。如淘宝类目的双十一活动,通过对不通服务组合进行重用实现不通的营销活动逻辑。
4、运维管理的复杂度提升
微服务让应用数量增加很多,链路的集成、测试、部署都成为新的挑战,以前一个war包解决的问题,需要通过多应用发布来完成,发布时服务之间的依赖影响,会导致功能不可用,测试阶段的依赖性可能会让用例跑不下去,这些都会是需要新考虑的问题,需要有平台化的工具来支撑,目前阿里通过aone产品来保证从日常到预发到线上的持续集成交付。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)