微服务架构-微服务实施

目录

一、概述

二、微服务拆分

2.1 概述

2.2 拆分原则

2.3 拆分方法

2.3.1 以数据为维度进行拆分

2.3.2 按照使用场景拆分

2.3.3 重要和非重要的拆分

2.3.4 变和不变的拆分

三、微服务通信

3.1 概述

3.2 微服务通信方式选择

3.3 微服务编排

3.4 API接口设计

3.5 合理设置超时和重试

3.6 数据一致性设计

四、微服务稳定性保障

4.1 概述

4.2 稳定性保障的目标

4.2.1 概述

4.2.2 故障预防

4.2.3 故障快速定位

4.2.4 故障快速止损

4.3 稳定性保障的6个维度

4.3.1 概述

4.3.2 隔离

4.3.3 冗余

4.3.4 容灾容错

4.3.5 变更管理

4.3.6 时间相关故障管理

4.3.7 运维友好


一、概述

微服务改造过程中会面临很多挑战,接下来从服务拆分、服务通信以及服务稳定性设计这几个维度出发,讨论微服务实施过程中需要着重注意的问题。

二、微服务拆分

2.1 概述

服务拆分是微服务改造的第一步,也是最为关键的一步,拆分是否合理,决定了整个微服务化过程的成败,因此,需要有科学的拆分原则和拆分方法,保证拆分过程有序进行。

2.2 拆分原则

微服务拆分前,需要确定拆分的基本原则,微服务拆分的一个非常重要原则是无状态,无状态服务方便扩展和运维,所以无状态设计需要贯穿到微服务架构设计的全局层面进行思考。

服务拆分粒度并不是越细越好,需要结合当前团队的人员情况而定,比如当前团队只有5个人,如果拆分后的微服务个数超过50,和人员的数量严重不匹配,不仅不会带来效率的提升,反而会导致效率的下降,建议拆分后每个人维护的微服务不要超过3个,并且每个微服务都有相应的备用负责人,规避可能的突发风险;针对多团队异地开发的情况,最好拆分后每个子团队负责的微服务相对独立,尽量减少异地团队的直接沟通成本。

微服务拆分时经常会遇到一些问题,比如是否需要拆分、拆分粒度的问题等,一般原则是遇到痛点问题时才进行拆分,非拆分不可时才启动微服务拆分,不要为了拆分而拆分。对于拆分方案拿捏不准的场景,尽量先不进行拆分,等想清楚了再定,避免拆分不合理,带来大量返工。

拆分后的微服务组织上层次不要过深,一个请求的处理过程中经过的微服务个数不要超过5个,链路太深会导致定位和追查问题特别麻烦,同时也会带来一定的性能损耗。

对于拆分后的子服务来说,尽量避免相互依赖的场景,子服务调用时相互依赖会导致升级和维护时特别麻烦,增加很多不必要的运维成本。

2.3 拆分方法

微服务拆分的总体思想是根据高耦合、低内聚的原则识别出各个微服务的边界。具体拆分思路和业务形态紧密相关,没有绝对的标准,下面介绍微服务架构拆分中使用比较多的两种拆分方式。

2.3.1 以数据为维度进行拆分

按照数据拆分,是微服务拆分中最常见的一种方式,没有特殊考虑时一般根据领域实体数据进行拆分,拆分出来的服务负责处理给定的数据/资源的所有操作。

以电商系统为例,大体可分为订单系统、用户系统、库存系统等。以订单系统为例,订单系统就负责订单核心数据的维护、订单数据的增删查改,确立了主要实体数据后可以根据数据的查询、修改等确定服务的接口,如订单的各种查询接口以及订单状态更新接口。

根据数据维度把系统可以拆分出若干个子服务,但这些数据之间会有不少关联关系。以百度贴吧为例,贴吧中的人、吧、帖是三个最重要的实体数据,这些实体数据可以分别放到不同的服务中。但是一些常见的实体关系,比如人发过的帖子、人收藏的吧,以及吧的会员、吧的帖子列表等,这些实体关系数据的维护,原则上放在哪个实体上维护没有标准的答案,某个人发过的帖子放在人服务和帖服务都可以,反复在这些地方纠结也不会带来太多的收益,可以人为地指定一个约束,如某个人发过的帖子就放在帖服务里面。

2.3.2 按照使用场景拆分

服务按照使用场景进行服务拆分,这种拆分方式也比较常见,如顺风车的所有后端查询操作之前都在一个单体服务里面,有固定路线/临时路线查询顺路订单,有根据路线查询附近订单,还有查询跨城订单,以及后续的需求乘客查询附近司机,乘客查询顺路司机等。之前这些在线查询接口都在一个单体服务中,多个RD会同时负责和修改这个服务的代码,开发效率低下,测试、上线都会相互影响,维护起来比较困难,后来把这些查询按照功能都拆分为不同的子服务,每个RD单独负责,大大提高了开发、测试以及运维效率。

2.3.3 重要和非重要的拆分

将核心逻辑和非核心逻辑拆分为不同的微服务,然后采用不同的高可用处理方案,比如核心服务尽量做到机房、集群等多维度的冗余和隔离;非核心服务则可以适当降低可用性标准,出现问题时只要能够及时降级和熔断即可。

2.3.4 变和不变的拆分

按照变更频次对服务进行拆分,尽量将变化聚集到少部分微服务上面,系统的绝大多数服务变更很少,可以减少变更对整个系统的冲击和影响。

三、微服务通信

3.1 概述

为了保证拆分之后的微服务能够通力合作,共同对外提供服务能力,需要通过一定的机制将拆分之后的微服务合起来,也就是微服务通信,接下来讨论微服务通信过程中常见的一些问题。

3.2 微服务通信方式选择

微服务通信时,首先需要考虑的是通信方式的选择,对一些不需要返回业务数据的微服务来说,究竟是采用同步方式还是异步方式呢?同步方式架构层面要求比较高,异步方式架构层面比较优雅,但运维成本比较高,出现问题时排查起来不太方便。之前公司中有过一次不成功的架构升级实例,业务形态完全围绕订单状态流转进行,当前的架构初衷是构建一套基于事件驱动的基础设施,所有微服务均以事件驱动的方式进行触发,最后不仅对业务人员的挑战比较大,同时运维、高可用和问题追查的成本比较高。因此微服务化时,核心服务推荐均采用同步通信的方式,一些非核心服务可以采用异步通信的方式。

3.3 微服务编排

微服务编排上,一些可以并行调用的场景推荐采用并行调用的方式,可以减少请求的整体耗时,提高用户体验。

当然对于有些场景来说,直接采用并行调用不一定是最好的方式,需要综合考虑和分析。比如,对于搜索和广告引擎来说,整个系统会有大量的过滤子服务组成,如果完全采用串行的方式,并且有着良好的漏斗模型设计,这时请求的整体耗时可能会上升,但整体的调用量会减少不少,成本上有很大的节省;如果采用完全并行的方式,整体耗时会有很大的改善,但无法充分利用漏斗模型,成本上会有一定的浪费。面对这种场景,需要有一套完善的微服务编排引擎,能够同时兼顾性能和成本上的需求,做到微服务编排的最优化。

3.4 API接口设计

API接口设计上,需要尽可能简单易用,一个接口只实现一个确定的功能,不要设计复杂或者含义不明确的接口,避免滥用;同时接口设计时做好前后向兼容,以及幂等性设计。

3.5 合理设置超时和重试

微服务通信上,需要合理设置超时和重试,超时和重试设置不要只考虑当前链路,而要从请求全链路的角度,对超时和重试进行统一梳理。

除非有特殊原因,建议在调用的入口统一进行重试,请求过程中不再进行重试,避免故障时的多级重试导致的整体雪崩。

3.6 数据一致性设计

同时操作多个微服务的场景,需要保证不同微服务之间的数据一致性,数据一致性设计尽量遵循简单的原则,除非特别场景,不要使用分布式事务。

多个微服务操作时,成功或失败需要以核心数据为准,当同时对多个核心数据进行操作时,可以以其中一个为准,遇到个别数据不一致的场景,可以采用线下对账的方式对不一致的数据进行校对和修正。

四、微服务稳定性保障

4.1 概述

微服务改造中,挑战最大的就是拆分之后的稳定性保障,拆分之后链路复杂、故障点众多,需要一套体系化的稳定性保障机制。

4.2 稳定性保障的目标

4.2.1 概述

微服务稳定性保障需要从事前、事中和事后全方位进行考虑。微服务架构下,应用程序、依赖服务、网络、硬件等都有可能出现故障,稳定性设计和保障的具体目标如下。

4.2.2 故障预防

尽可能减少故障的产生,绝大多数稳定性问题和稳定性故障发生都有一定的诱因,并且一般是在多种拦截手段均失灵的情况下故障才会发生,如果我们在故障发生前制定完备的稳定性保障措施,可以最大限度地减少稳定性故障的发生。

4.2.3 故障快速定位

完全不出故障的业务是不存在的,关键是出故障时能够快速发现故障,只有及时发现,才能在最短时间内采取相应的解决措施。

4.2.4 故障快速止损

发生故障后第一时间要进行业务止损,恢复业务的正常运行,故障深层次的具体原因可以事后再分析和复盘解决。

4.3 稳定性保障的6个维度

4.3.1 概述

系统故障点很多,稳定性保障就是对故障点进行管理的过程。可以从故障点管理的角度将整个稳定性设计和保障分为如下隔离、冗余、容灾容错、变更管理、时间相关故障管理与运维友好6个维度。

4.3.2 隔离

影响系统稳定性的不稳定性因素和故障点很多,从稳定性保障的角度看,很自然的想法就是,如何尽量减少如此多的故障点给系统稳定性带来的隐患,比如某电商业务有200个微服务组成,如果这100个微服务中的任何一个出问题,导致业务不可用,那么系统的可用性就会很低。业务层面如果能够梳理和抽象出保障业务核心运行的最小系统(比如上面提到的电商业务最小系统包含的服务可能会小于50个,其他都是增值和支撑性的服务),同时将最小系统之外的不稳定性因素从最小系统中隔离出来,就可以大大增强系统的稳定性和健壮性。因此,稳定性设计的第一个原则就是“隔离”,通过各种隔离机制,将核心服务之前的故障点隔离出去,保证核心服务的可用性。

4.3.3 冗余

通过隔离,可以减少绝大多数不稳定性因素对系统稳定性的影响,但如果核心服务或核心服务所在的环境出问题,就无法从隔离中受益。我们需要有相应的机制保证核心业务的部分单元出问题时,业务整体运行不受大的影响,这种机制就是冗余。通过服务级别、机器级别、集群级别、机房级别等多种维度的冗余,我们可以保证:即便核心服务出问题,也可以通过相应的流量切换策略,将流量切到冗余节点上,保证业务不受影响。

4.3.4 容灾容错

通过冗余可以保证核心服务及其部署环境变化时的系统稳定性,但如果系统外部输入有变化,比如遇到突然大流量、异常流量或者突发的安全攻击,而系统事先没有相应的应对机制,则业务很可能瞬间被击垮。因此,稳定性设计的第三个原则是“容灾容错”,通过构建多维度的容灾容错体系,保证系统面对异常输入时,仍然能够提高稳定的输出能力。

4.3.5 变更管理

通过隔离、冗余与容灾可以排除和应对业务最小子系统的各种外部稳定性风险,变更管理、时间相关故障管理是为了解决核心系统自身的稳定性问题。绝大部分稳定性故障都是由变更引起,系统如果长时间没有任何变更,很少会有稳定性问题,因此服务稳定性保障的关键一环是严把变更这一关,保证变更质量。

4.3.6 时间相关故障管理

服务没有变更时,有一类故障很少发生并且很难发现,就是随时间变化而产生的ID越界和溢出,这类故障平常测试时很难发现,并且发生时会对整个系统产生很大的影响,需要从设计层面开始把控,比如随时间变化的ID字段尽量使用int64。

4.3.7 运维友好

隔离、冗余和容灾减少了核心服务的外部稳定性风险,变更管理和时间相关故障管理保证了核心服务自身的稳定性。上述5种措施构成了业务稳定性预防的整个闭环,但即使设计得再好,也不能完全杜绝稳定性故障,稳定性风险只能最大限度地减少,因此服务的研发生命周期中,还需要加上运维友好的考虑。设计时需要针对稳定性问题的快速发现进行特别考虑,如日志怎么输出,统计信息如何收集等。通过运维友好设计,比如log、metric和trace等方式的良好设计与运用,建立全方位多维度的故障发现机制,保证出现问题时可以快速发现和快速止损,最大程度上减少稳定性风险的影响。

好了,本次内容就分享到这,欢迎大家关注《微服务架构》专栏,后续会继续输出相关内容文章。如果有帮助到大家,欢迎大家点赞+关注+收藏,有疑问也欢迎大家评论留言!

  • 19
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值