您的位置 首页 golang

Golang 分布式面试题与答案(一)

一、目录:

1、分布式服务接口的 幂等性 如何设计?

2、分布式系统中的 接口调用 如何 保证顺序性

3、说说 zookeeper 一般都有哪些使用场景?

4、说说你们的分布式 session 方案是啥?怎么做的?

5、 分布式事务 了解吗?

6、常见的 分布式锁 有哪些解决方案?

7、 ZK Redis 的区别,各自有什么优缺点?

二、详情解读:

1、分布式服务接口的幂等性如何设计?

所谓 幂等性 ,就是 说一个接口,多次发起同一个请求,你这个接口得保证结果是准确的 。比如不能多扣款。不能多插入一条数据,不能将统计值多加了 1 ,这就是幂等性。

其实保证幂等性 主要是三点

  • 对于每个请求必须有一个唯一的标识 ,举个例子:订单支付请求,肯定得包含订单 ID ,一个订单 ID 最多支付一次。

  • 每次处理完请求之后,必须有一个记录标识这个请求处理过了 ,比如说,常见得方案是再 mysql 中记录个状态啥得,比如支付之前记录一条这个订单得支付流水,而且支付流水采用 order id 作为唯一键( unique key )。只有成功插入这个支付流水,才可以执行实际的支付扣款

  • 每次接收请求需要进行判断之前是否处理过的逻辑处理 ,比如说,如果有一个订单已经支付了,就已经有了一条支付流水,那么如果重复发送这个请求,则此时先插入支付流水, order id 已经存在了,唯一键约束生效,报错插入不进去的。然后你就不用再扣款了。

2、分布式系统中的接口调用如何保证顺序性?

可以接入 MQ ,如果是系统 A 使用多线程处理的话,可以使用内存队列,来保证顺序性,如果你要 100% 的顺序性,当然可以使用分布式锁来搞,会影响系统的并发性。

3、说说 zookeeper 一般都有哪些使用场景?

  • 分布式协调 :这个其实就是 zk 很经典的一个用法,简单来说,就好比,你系统 A 发送个请求到 mq ,然后 B 消费了之后处理。那 A 系统如何指导 B 系统的处理结果?用 zk 就可以实现分布式系统之间的协调工作。 A 系统发送请求之后可以在 zk 上对某个节点的值注册个监听器,一旦 B 系统处理完了就修改 zk 那个节点的值, A 立马就可以收到通知,完美解决。

  • 分布式锁 :对某一个数据联系发出两个修改操作,两台机器同时收到请求,但是只能一台机器先执行另外一个机器再执行,那么此时就可以使用 zk 分布式锁,一个机器接收到了请求之后先获取 zk 上的一把分布式锁,就是可以去创建一个 znode ,接着执行操作,然后另外一个机器也尝试去创建那个 znode ,结果发现自己创建不了,因为被别人创建了,那只能等着,等等一个机器执行完了自己再执行。

  • 配置信息管理 zk 可以用作很多系统的配置信息的管理,比如 kafka storm 等等很多分布式系统都会选用 zk 来做一些元数据,配置信息的管理,包括 dubbo 注册中心不也支持 zk 么。

  • HA 高可用性 :这个应该是很常见的,比如 hdfs yarn 等很多大数据系统,都选择基于 zk 来开发 HA 高可用机制,就是一个重要进程一般会主备两个,主进程挂了立马通过 zk 感知到切换到备份进程。

4、说说你们的分布式 session 方案是啥?怎么做的?

  • Tomcat + redis

其实还挺方便的,就是使用 session 的代码跟以前一样,还是基于 tomcat 原生的 session 支持即可,然后就是用一个叫做 tomcat RedisSessionManager 的东西,让我们部署的 tomcat 都将 session 数据存储到 redis 即可.

  • Spring Session + redis

分布式会话的这个东西重耦合在 tomcat ,如果我要将 web 容器迁移成 jetty ,不能重新把 jetty 都配置一遍.

所以现在比较好用的还是基于 java 的一站式解决方案,使用 spring session 是一个很好的选择,给 spring session 配置基于 redis 来存储 session 数据,然后配置一个 spring session 的过滤器,这样的话, session 相关操作都会交给 spring session 来管了。

接着在代码中,就是用原生的 session 操作,就是直接基于 spring session redis 中获取数据了。

5、分布式事务了解吗?

  • XA 方案/两阶段提交方案

第一个阶段(先询问)

第二个阶段(再执行)

  • TCC 方案

TCC 的全程是: Try、Confirm、Cancel

这个其实是用到了补偿的概念,分为了 三个阶段

Try 阶段 :这个阶段说的是对各个服务的资源做检测以及对资源进行锁定或者预留

Confirm 阶段: 这个阶段说的是在各个服务中执行实际的操作

Cancel 阶段 :如果任何一个服务的业务方法执行出错,那么这里就需要进行补偿,就是执行已经成功的业务逻辑的回滚操作

  • 本地消息表
  • 可靠消息最终一致性方案
  • 最大努力通知方案

6、常见的分布式锁有哪些解决方案?

  • Reids 的分布式锁,很多大公司会基于 Reidis 做扩展开发
  • 基于 Zookeeper
  • 基于数据库,比如 Mysql

7、ZK 和 Redis 的区别,各自有什么优缺点?

先说 Redis:

  • Redis 只保证最终一致性,副本间的数据复制是异步进行( Set 是写, Get 是读, Reids 集群一般是读写分离架构,存在主从同步延迟情况),主从切换之后可能有部分数据没有复制过去可能会丢失锁情况,故强一致性要求的业务不推荐使用 Reids ,推荐使用 zk

  • Redis 集群各方法的响应时间均为最低。随着并发量和业务数量的提升其响应时间会有明显上升(公有集群影响因素偏大),但是极限 qps 可以达到最大且基本无异常。

再说 ZK

  • 使用 ZooKeeper 集群,锁原理是使用 ZooKeeper 的临时节点,临时节点的生命周期在 Client 与集群的 Session 结束时结束。因此如果某个 Client 节点存在网络问题,与 ZooKeeper 集群断开连接, Session 超时同样会导致锁被错误的释放(导致被其他线程错误地持有),因此 ZooKeeper 也无法保证完全一致。

  • ZK 具有较好的稳定性;响应时间抖动很小,没有出现异常。但是随着并发量和业务数量的提升其响应时间和 qps 会明显下降。

更多编程干货,请关注我

文章来源:智云一二三科技

文章标题:Golang 分布式面试题与答案(一)

文章地址:https://www.zhihuclub.com/90608.shtml

关于作者: 智云科技

热门文章

网站地图