SOA和微服务架构
1.SOA(Service Oriented Architecture)“面向服务的架构”:他是一种设计方法,其中包含多个服务, 服务之间通过相互依赖最终提供一系列的功能。一个服务 通常以独立的形式存在与操作系统进程中。各个服务之间 通过网络调用。

2.微服务架构:其实和 SOA 架构类似,微服务是在 SOA 上做的升华,微服务架构强调的一个重点是“业务需要彻底的组件化和服务化”,原有的单个业务系统会拆分为多个可以独立开发、设计、运行的小应用。这些小应用之间通过服务完成交互和集成。

微服务架构 = 80%的SOA服务架构思想 + 100%的组件化架构思想 + 80%的领域建模思想

API网关:API网关是一个服务器,是系统的唯一入口。从面向对象设计的角度看,它与外观模式类似。API网关封装了系统内部架构,为每个客户端提供一个定制的API。它可能还具有其它职责,如身份验证、监控、负载均衡、缓存、请求分片与管理、静态响应处理。API网关方式的核心要点是,所有的客户端和消费端都通过统一的网关接入微服务,在网关层处理所有的非业务功能。通常,网关也是提供REST/HTTP的访问API。服务端通过API-GW注册和管理服务。

SOA架构特点:系统集成、系统的服务化(把原先固有的业务功能转变为通用 的业务服务,实现业务逻辑的快速复用,解决 的核心问题是【复用】)、业务的服务化(以业务驱动把一个业务单元封装成一项服务,解决的核心问题是【高效】)

微服务架构特点:通过服务实现组件化、按业务能力来划分服务和开发团队、去中心化、基础设施自动化

SOA MSA 分布式系统架构_服务器

二、分布式事务
分布式事务指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上。
就是一次大的操作由不同的小操作组成,这些小的操作分布在不同的服务器上,且属于不同的应用,分布式事务需要保证这些小操作要么全部成功,要么全部失败。分布式事务就是为了保证不同数据库的数据一致性。

CAP 定理一致性、可用性、分区容错性。分布式系统理论上不可能选择 CA 架构,只能选择 CP 或者 AP 架构。
BASE 是 Basically Available(基本可用)、Soft state(软状态)和 Eventually consistent (最终一致性)三个短语的缩写,是对 CAP 中 AP 的一个扩展。
BASE 解决了 CAP 中理论没有网络延迟,在 BASE 中用软状态和最终一致,保证了延迟后的一致性。

分布式事务可以看看下面几种常见的方案:2PC、TCC、MQ 事务、Saga 事务

SOA MSA 分布式系统架构_数据_02


在 XA 协议中分为两阶段:

事务管理器要求每个涉及到事务的数据库预提交(precommit)此操作,并反映是否可以提交。

事务协调器要求每个数据库提交数据,或者回滚数据。

优点:尽量保证了数据的强一致,实现成本较低

缺点:单点问题:事务管理器在整个流程中扮演的角色很关键,如果其宕机,比如在第一阶段已经完成,在第二阶段正准备提交的时候事务管理器宕机,资源管理器就会一直阻塞,导致数据库无法使用。同步阻塞:在准备就绪之后,资源管理器中的资源一直处于阻塞,直到提交完成,释放资源。数据不一致:两阶段提交协议虽然为分布式数据强一致性所设计,但仍然存在数据不一致性的可能。

XA 协议比较简单,成本较低,但是其单点问题,以及不能支持高并发(由于同步阻塞)依然是其最大的弱点。

TCC 事务机制相比于上面介绍的 XA,解决了如下几个缺点:解决了协调者单点,由主业务方发起并完成这个业务活动。业务活动管理器也变成多点,引入集群。
同步阻塞:引入超时,超时后进行补偿,并且不会锁定整个资源,将资源转换为业务逻辑形式,粒度变小。
数据一致性,有了补偿机制之后,由业务活动管理器控制一致性。

Try 阶段:尝试执行,完成所有业务检查(一致性),预留必需业务资源(准隔离性)。Confirm 阶段:确认真正执行业务,不作任何业务检查,只使用 Try 阶段预留的业务资源,Confirm 操作满足幂等性。要求具备幂等设计,Confirm 失败后需要进行重试。Cancel 阶段:取消执行,释放 Try 阶段预留的业务资源,Cancel 操作满足幂等性。Cancel 阶段的异常和 Confirm 阶段异常处理方案基本上一致。

SOA MSA 分布式系统架构_服务器_03


TCC在保证强一致性的同时,最大限度提高系统的可伸缩性与可用性。

TCC拥有以下特点:位于业务服务层而非资源层 ,由业务层保证原子性

  没有单独的准备(Prepare)阶段,降低了提交协议的成本

  Try操作 兼备资源操作与准备能力

  Try操作可以灵活选择业务资源的锁定粒度,而不是锁住整个资源,提高了并发度

TCC需要较高的开发成本,每个子业务都需要有响应的comfirm、Cancel操作,即实现相应的补偿逻辑。

基于消息的分布式事务
这类事务机制将分布式事务分成多个本地事务,这里称之为主事务与从事务。首先主事务本地先行提交,然后通过消息通知从事务,从事务从消息中获取信息进行本地提交。可以看出这是一种异步事务机制、只能保证最终一致性;但可用性非常高,不会因为故障而发生阻塞。另外,主事务已经先行提交,如果因为从事务无法提交,要回滚主事务还是比较麻烦,所以这种模式只适用于理论上大概率等成功的业务情况,即从事务的提交失败可能是由于故障,而不大可能是逻辑错误。
  基于异步消息的事务机制主要有两种方式:本地消息表与事务消息。二者的区别在于:怎么保证主事务的提交与消息发送这两个操作的原子性。
  如果用异步消息实现转账的例子,那么操作分为四部:用户A扣钱,发消息,用户B收消息,用户B扣钱。前两步必须保证原子性,如果A扣钱成功但是没有发出消息,那么用户A损失了;如果发消息成功,但是没有扣钱,那么用户B就多得了一笔钱,银行肯定不干。

基本流程如下:第一阶段 Prepared 消息,会拿到消息的地址。第二阶段执行本地事务。第三阶段通过第一阶段拿到的地址去访问消息,并修改状态。消息接受者就能使用这个消息。如果确认消息失败,在 RocketMQ Broker 中提供了定时扫描没有更新状态的消息。如果有消息没有得到确认,会向消息发送者发送消息,来判断是否提交,在 RocketMQ 中是以 Listener 的形式给发送者,用来处理。

如果消费超时,则需要一直重试,消息接收端需要保证幂等。如果消息消费失败,这时就需要人工进行处理,因为这个概率较低,如果为了这种小概率时间而设计这个复杂的流程反而得不偿失。

SOA MSA 分布式系统架构_微服务_04

Saga 事务
Saga 的组成:每个 Saga 由一系列 sub-transaction Ti 组成,每个 Ti 都有对应的补偿动作 Ci,补偿动作用于撤销 Ti 造成的结果。这里的每个 T,都是一个本地事务。
Saga 定义了两种恢复策略:向后恢复,即上面提到的第二种执行顺序,其中 j 是发生错误的 sub-transaction,这种做法的效果是撤销掉之前所有成功的 sub-transation,使得整个 Saga 的执行结果撤销。向前恢复,适用于必须要成功的场景,执行顺序是类似于这样的:T1,T2,…,Tj(失败),Tj(重试),…,Tn,其中 j 是发生错误的 sub-transaction。该情况下不需要 Ci。这里要注意的是,在 Saga 模式中不能保证隔离性,因为没有锁住资源,其他事务依然可以覆盖或者影响当前事务。

三、分布式算法(一致性Hash算法)
在做服务器负载均衡时候可供选择的负载均衡的算法有很多,包括: 轮循算法(Round Robin)、哈希算法(HASH)、最少连接算法(Least Connection)、响应速度算法(Response Time)、加权法(Weighted )等。其中哈希算法是最为常用的算法.

典型的应用场景是: 有N台服务器提供缓存服务,需要对服务器进行负载均衡,将请求平均分发到每台服务器上,每台机器负责1/N的服务。

常用的算法是对hash结果取余数 (hash() mod N ):对机器编号从0到N-1,按照自定义的 hash()算法,对每个请求的hash()值按N取模,得到余数i,然后将请求分发到编号为i的机器。但这样的算法方法存在致命问题,如果某一台机器宕机,那么应该落在该机器的请求就无法得到正确的处理,这时需要将当掉的服务器从算法从去除,此时候会有(N-1)/N的服务器的缓存数据需要重新进行计算;如果新增一台机器,会有N /(N+1)的服务器的缓存数据需要进行重新计算。对于系统而言,这通常是不可接受的颠簸(因为这意味着大量缓存的失效或者数据需要转移)。那么,如何设计一个负载均衡策略,使得受到影响的请求尽可能的少呢?

在Memcached、Key-Value Store 、Bittorrent DHT、LVS中都采用了Consistent Hashing算法,可以说Consistent Hashing 是分布式系统负载均衡的首选算法。

一致性哈希算法(Consistent Hashing Algorithm)是一种分布式算法,常用于负载均衡。一致性哈希将整个哈希值空间组织成一个虚拟的圆环,如假设某哈希函数H的值空间为0 - (232)-1(即哈希值是一个32位无符号整形),整个空间按顺时针方向组织。0和(232)-1在零点中方向重合。
接下来使用如下算法定位数据访问到相应服务器:将数据key使用相同的函数H计算出哈希值h,通根据h确定此数据在环上的位置,从此位置沿环顺时针“行走”,第一台遇到的服务器就是其应该定位到的服务器。
例如我们有A、B、C、D四个数据对象,经过哈希计算后,在环空间上的位置如下:数据A会被定为到Server 1上,D被定为到Server 3上,而B、C分别被定为到Server 2上。

一致性hash算法原理:先构造一个长度为232的整数环(这个环被称为一致性Hash环),根据节点名称的Hash值(其分布为[0, 232-1])将服务器节点放置在这个Hash环上,然后根据数据的Key值计算得到其Hash值(其分布也为[0, 232-1]),接着在Hash环上顺时针查找距离这个Key值的Hash值最近的服务器节点,完成Key到服务器的映射查找。

使用一致性Hash算法,尽管增强了系统的伸缩性,但是也有可能导致负载分布不均匀,解决办法就是使用虚拟节点代替真实节点。