前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java基础面试题【分布式】二

Java基础面试题【分布式】二

作者头像
@派大星
发布2023-10-19 16:33:06
2070
发布2023-10-19 16:33:06
举报
文章被收录于专栏:码上遇见你

分布式锁解决方案

思考的点:

需要这个锁独立于每一个服务之外,而不是在服务里面。数据库:利用主键冲突控制一次只有一个线程能获取锁,非阻塞、不可重入、单点、失效时间

Zookeeper分布式锁

zk通过临时节点,解决了死锁的问题,一旦客户端获取到锁之后突然挂掉(Session连接断开),那么这个临 时节点就会自动删除掉,其他客户端自动获取锁。临时顺序节点解决羊群效应

Redis分布式锁

setNX,单线程处理网络请求,不需要考虑并发安全性 所有服务节点设置相同的key,返回为0、则锁获取失败

setnx 问题:

  1. 早期版本没有超时参数,需要单独设置,存在死锁问题(中途宕机) ,可通过过期时间保证。
  2. 后期版本提供加锁与设置时间原子操作,但是存在任务超时,锁自动释放,导致并发问题,加锁与释放锁不是同一线程问题 ,可重入性及锁续期没有实现,通过redisson解决(类似AQS的实现,看门狗监听机制)

可参考文章:面试官:你真的了解Redis分布式锁吗?

redlock:意思的机制都只操作单节点、即使Redis通过sentinel保证高可用,如果这个master节点由于 某些原因发生了主从切换,那么就会出现锁丢失的情况(redis同步设置可能数据丢失)。redlock从多 个节点申请锁,当一半以上节点获取成功、锁才算获取成功,redission有相应的实现

分布式事务解决方案

  • XA规范:分布式事务规范,定义了分布式事务模型
    • 四个角色:事务管理器(协调者TM)、资源管理器(参与者RM),应用程序AP,通信资源管理器CRM
    • 全局事务:一个横跨多个数据库的事务,要么全部提交、要么全部回滚
    • JTA事务时java对XA规范的实现,对应JDBC的单库事务
两阶段协议:

image.png

**说明:** 第一阶段( prepare ) :每个参与者执行本地事务但不提交,进入 ready 状态,并通知协调者已经准备就绪。 第二阶段( commit ) 当协调者确认每个参与者都 ready 后,通知参与者进行 commit 操作;如果有 参与者 fail ,则发送 rollback 命令,各参与者做回滚。问题:

  • 单点故障:一旦事务管理器出现故障,整个系统不可用(参与者都会阻塞住)
  • 数据不一致:在阶段二,如果事务管理器只发送了部分 commit 消息,此时网络发生异常,那么 只有部分参与者接收到 commit 消息,也就是说只有部分参与者提交了事务,使得系统数据不一 致。
  • 响应时间较长:参与者和协调者资源都被锁住,提交或者回滚之后才能释放
  • 不确定性:当协事务管理器发送 commit 之后,并且此时只有一个参与者收到了 commit,那么当 该参与者与事务管理器同时宕机之后,重新选举的事务管理器无法确定该条消息是否提交成功。
三阶段协议

主要是针对两阶段的优化,解决了2PC单点故障的问题,但是性能问题和不一致问题仍然 没有根本解决

引入了超时机制解决参与者阻塞的问题,超时后本地提交,2pc只有协调者有超时机制

  • 第一阶段:CanCommit阶段,协调者询问事务参与者,是否有能力完成此次事务。
    • 如果都返回yes,则进入第二阶段
    • 有一个返回no或等待响应超时,则中断事务,并向所有参与者发送abort请求
  • 第二阶段:PreCommit阶段,此时协调者会向所有的参与者发送PreCommit请求,参与者收到后 开始执行事务操作。参与者执行完事务操作后(此时属于未提交事务的状态),就会向协调者反馈 “Ack”表示我已经准备好提交了,并等待协调者的下一步指令。
  • 第三阶段:DoCommit阶段, 在阶段二中如果所有的参与者节点都返回了Ack,那么协调者就会从 “预提交状态”转变为“提交状态”。然后向所有的参与者节点发送"doCommit"请求,参与者节点在 收到提交请求后就会各自执行事务提交操作,并向协调者节点反馈“Ack”消息,协调者收到所有参 与者的Ack消息后完成事务。相反,如果有一个参与者节点未完成PreCommit的反馈或者反馈超 时,那么协调者都会向所有的参与者节点发送abort请求,从而中断事务。
TCC(补偿事务):

Try、Confirm、Cancel 针对每个操作,都要注册一个与其对应的确认和补偿(撤销)。

  • 操作 Try操作做业务检查及资源预留,
  • Confirm做业务确认操作,
  • Cancel实现一个与Try相反的操作既回滚操 作。

TM首先发起所有的分支事务的try操作,任何一个分支事务的try操作执行失败,TM将会发起所有 分支事务的Cancel操作,若try操作全部成功,TM将会发起所有分支事务的Confirm操作,其中 Confirm/Cancel操作若执行失败,TM会进行重试。TCC模型对业务的侵入性较强,改造的难度较大,每个操作都需要有 try 、 confirm 、 cancel 三个接 口实现 confirm 和 cancel 接口还必须实现幂等性。 消息队列的事务消息:

  • 发送prepare消息到消息中间件
  • 发送成功后,执行本地事务
    • 如果事务执行成功,则commit,消息中间件将消息下发至消费端(commit前,消息不会被 消费)
    • 如果事务执行失败,则回滚,消息中间件将这条prepare消息删除
  • 消费端接收到消息进行消费,如果消费失败,则不断重试

如何实现接口的幂等性

  • 唯一id。每次操作,都根据操作和内容生成唯一的id,在执行之前先判断id是否存在,如果不存在 则执行后续操作,并且保存到数据库或者redis等。
  • 服务端提供发送token的接口,业务调用接口前先获取token,然后调用业务接口请求时,把token 携带过去,务器判断token是否存在redis中,存在表示第一次请求,可以继续执行业务,执行业务 完成后,最后需要把redis中的token删除
  • 建去重表。将业务中有唯一标识的字段保存到去重表,如果表中存在,则表示已经处理过了
  • 版本控制。增加版本号,当版本号符合时,才能更新数据
  • 状态控制。例如订单有状态已支付 未支付 支付中 支付失败,当处于未支付的时候才允许修改为支 付中等
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-10-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码上遇见你 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 分布式锁解决方案
    • Zookeeper分布式锁
      • Redis分布式锁
      • 分布式事务解决方案
        • 两阶段协议:
          • 三阶段协议
            • TCC(补偿事务):
            • 如何实现接口的幂等性
            相关产品与服务
            云数据库 Redis®
            腾讯云数据库 Redis®(TencentDB for Redis®)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档