03知识点

05服务幂等设计

幂等定义

请求层面幂等

保证请求重复执行和执行一次的结果一致

业务层面幂等
  • 同一用户不重复下单
  • 商品不超卖
  • MQ消费端去重

幂等目的

交易、转账等操作在重试的时候不会出错。如果每个请求失败之后直接返回给用户,则不用考虑幂等。

数据访问层幂等

  • Create操作禁止使用auto increment id,使用业务相关的唯一ID可以保证操作幂等
  • Read操作本身幂等
  • Update操作分为两种,绝对值更新是幂等的,相对值更新不是幂等的
  • Delete操作分为两种,绝对值删除是幂等的,相对值删除不实幂等的

幂等案例

QQ离线消息的已读状态(请求层面幂等)

天然幂等操作

计数增加操作

增加Where操作,先查出当前值,再更新。但这种做法在高并发情况下性能不好。

电商平台购买商品

整个购买流程(整个请求)的幂等性由分布式事务来保证。即转换成分布式事务问题。

业务层面幂等

冗余部署多个进程,当MQ上游重复添加消息时,保证下游不重复消费。本质上是分布式锁问题。

06分布式锁设计

定义

分布式环境下锁定全局唯一资源(解决业务层面的幂等问题,解决消息的重复消费)

  • 请求处理串行化
  • 实际表现为互斥锁

****为什么不能解决消息的重复发送?
当没有收到ACK的时候,无法确定消息是否发送成功,只能重新发送

基于Redis分布式锁

实现方式

Set nx (SET if Not eXists)

存在的问题

  • 锁的时间不可控:
    1. 难以确定过期时间
    2. 无法续租
  • 单点问题:
    1. 单例情况下,进程一旦死掉,会彻底阻塞业务流程
    2. 主从方式,主从同步异步,当主从切换时会导致两个线程获取锁。

能不能用Redis实现分布式锁区别与业务场景:

  1. 交易场景要求绝对一致,不能使用
  2. 如果是社交或其他不极端要求严格的场景,可以使用

Redis主从复制半同步,本质上是AP模型,分布式锁是CP模型
Redis官方简历使用RedLock,类似自己实现Raft算法。实现上复杂性高。

高可用分布式锁设计目标

  • 强一致性
  • 服务高可用
  • 锁自动续约及其自动释放
  • 代码高度抽象,业务接入极间
  • 可视化管理后台,监控和管理

存储层产品对比

image.png

Tair也可用来做分布式锁的存储
Tair是淘宝开源的一个分布式key/value结构数据库。参考:深入理解Tair

美团点评内部开发的分布式锁Cerberus,使用了多种引擎实现(Tair、ZK),支持使用方自主选择一种或多种引擎。这样可以结合引擎的特点,选择符合实际业务需求和系统架构的方式。

选型(ETCD)

etcd:从应用场景到实现原理的全方位解读

07分布式事务设计

数据不一致的原因

单独的数据库,可以依赖于数据的事务操作保证数据的一致性。在分布式系统中,数据的不一致性原因包括:

  • 多个DB
  • DB和缓存

举例

在一个业务流程中,比如:下单->减库存->支付
三个操作分布在不同的服务和不同的数据库上。此时无法使用本地事务保证数据的一致性。只能采用分布式事务来解决。

实际问题

在实际系统中,当系统中使用MQ的话,会进一步增加事务的复杂性。比如当消息发送者需要执行事务的回滚操作。

相关概念

刚性分布式事务

  • 强一致性
  • XA模型(实现了事务的ACID特性)。XA规范由AP(Application Program,应用程序)、RM(Resource Manager,资源管理器)、TM(Transaction Manager,事务管理器)组成。2PC
  • CAP模型中实现CP

柔性分布式事务

  • 最终一致性
  • CAP、BASE理论,实现CAP中的AP。典型实现:TCC模型,Saga模型

BASE (Basically Availabe, Soft state, Eventual consistency)

柔性分布式事务场景

异步场景:基于MQ消息驱动的分布式事务

这个场景解决的问题是,本地操作和发送消息两个行为的事务问题。
在消息消费端:

  • 消息幂等通过分布式锁来实现
  • 执行失败,一般通过报警、日志、人工干预来解决。
方案一

MQ提供类似XA的分布式事务功能,通过MQ事务消息,等达到分布事务事务的最终一致。(RocketMQ)
缺点:业务方需要给MQ提供回查接口(对业务入侵大),发送消息非幂等(消费端需要处理幂等)

方案二

本地事务表。本质上是将本地操作和发消息转化成本地事务问题。通过本地事务操作表和本地事务消息表,两个表通过本地事务保证。

同步场景:基于异步补偿分布

同步场景描述的是在服务聚合处,串行执行下单、减库存、支付三个操作。
由业务网逻辑层驱动的同步场景。
如果下单执行成功,减库存执行失败,如果回滚下单操作?
可能地方案是在减库存执行失败时,服务聚合节点调用下单服务的回滚接口。理论上可以通过XA、TCC等来结局。但这里没讲。

08服务降级设计

目的

  • 流量高峰期
  • 短时请求量大
    如果没有服务降级,可能导致:服务宕机、系统雪崩等。

手段

拒绝部分老请求

确保“新”请求正常 响应,因为老请求可能在前端以及等待超时了。
实现方式可以通过RPC队列:请求入队、出队时间,对于在队列中停留超过阈值的直接丢弃。

优先级请求

丢弃非核心请求,保证主要业务

随机拒绝

随机处理一定比例的请求,网站一会可用,一会不可用。

Integer.valueOf("1.23")的实现

方案

集中式:仅仅在网关层执行降级不靠谱,因为网关层无法确定应该过滤多少流量。只有底层才知道自己能处理多少个请求。
自治式:各个层都由自己的降级方案。
一般不需要对DB层进行降级,但新浪微博对于明星时间的突发流量,通过将瞬时数据写入缓存,然后在慢慢回放给数据库保证服务的可用性。

Log4j是阻塞的写日志,如果阻塞大量日志需要写的话,也会把主机资源用完。

09服务限流/熔断设计

目的

屏蔽性能下降时的非关键服务,防止导致雪崩。

平台化熔断系统需求分析

  • 大部分熔断返回默认值
  • 进入熔断时打印日志同时返回业务定制的Exception
  • 通过服务治理平台能够对熔断进行查看、管理
  • 可以报警
  • 接口粒度

基于RPC客户端来实现熔断,升级时只需要升级RPC客户端就可以。
通过动态代理实现是否熔断。

业界方案

Hystrix、Resilience4J

10服务灰度发布设计

定义

一种发布规则,让一部分用户用新系统,另一部分仍用旧系统

金丝雀发布,A/B Test

目的

让一小部分用户来进行线上测试,如果发现问题可以快速回滚。

实现方案

通过配置中心对系统进行配置,包括:指定灰度服务器、灰度流量占比、是否允许灰度。

协议设计

数据协议:
确定Header中的灰度发布以来字段,比如:udi,Token,IP,网关中打Tag等。
灰度发布策略:仅根据uid/token/IP的单策略,基于上下文的灰度策略。

案例

  1. 多层服务进行灰度,通过nginx层打tag实现
  2. 涉及到数据的灰度服务分三步:部分灰度(数据全量复制、双写);全部灰度(双写);灰度完成(去除双写)

业界产品

Spring Cloud灰度发布神器:Nepxion Discovery,是服务注册和负载均和的增强中间件,包含了灰度发布功能。

11服务全链路压测设计

基于线上真实环境,模拟海量用户,对整个链路进行压测。
工具:
JMeter、TCPCopy(流量复制)、Apache ab
标准:
CPU、网卡、请求超时量、QPS

你可能感兴趣的:(03知识点)