当前位置:网站首页>分布式常见面试题

分布式常见面试题

2022-06-23 09:32:00 Linging_24

1.如何防止表单重复提交

  1. 前端。每次点击后都要等X秒才能点击。
  2. 数据库添加唯一索引
  3. 服务器返回表单页面时,会先生成一个subToken保存于session或redis,当表单提交时候携带token,如果token一致,则执行后续,并将服务器中的token删除。如果token不存在,则说明是重复提交。

2.如何设计一个秒杀系统

  1. 前端。
    在秒杀之前,按钮置灰,并且不给前端真正的请求地址。前端定时请求后端接口,如果到了秒杀时间,则返回给前端真正的地址,前端放开按钮,每次点击后都要等XX秒才能点击。

  2. 服务器:服务器用nginx做集群、redis也做集群

  3. 限流:在秒杀之前,将秒杀数量的令牌存入到redis中,可以用list,每次来请求都去redis中取出令牌,如果获取到说明秒杀成功,然后去访问数据库下单,如果没有获取到,则说明商品卖完了。

  4. 消息中间件。如果秒杀数量比较多,例如上万十万,则秒杀成功之后,将成功的请求放入到mq或者kafka中间件中,再从消息队列中获取请求。

  5. 服务降级。为了以防万一,还是要做服务熔断降级。

3.分布式系统的接口幂等性设计

  1. 唯一id。每次操作,都根据操作和内容生成唯一的id,在执行之前先判断id是否存在,如果不存在则执行后续操作,并且保存到数据库或者redis等。
  2. 服务端提供发送token的接口,业务调用接口前先获取token,然后调用业务接口请求时,把token携带过去,服务器判断token是否存在redis中,存在表示第一次请求,可以继续执行业务,执行业务完成后,最后需要把redis中的token删除。
  3. 建去重表。将业务中有唯一标识的字段保存到去重表,如果表中存在,则表示已经处理过了
  4. 版本控制。增加版本号,当版本号符合时,才能更新数据。
  5. 状态控制。例如订单有状态:已支付、未支付、支付中、支付失败,当处于未支付的时候才允许修改为支付中等。

4.管理分布式session的四种方式(单点登录)

  1. session复制
    应用服务器开启Web容器的Session复制功能,在集群中的几台服务器之间同步Session对象。

    方案简单,且从本机读取session也相当快捷,但有非常明显的缺陷:只能使用在集群规模比较小的情况下(企业应用系统,使用人数少,相对比较常见这种模式),当集群规模比较大的时候,集群服务器之间需要大量的通信进行Session的复制,占用服务器和网络的大量资源,系统负担较大。而且由于用户的session信息在每台服务器上都有备份,在大量用户访问下,可能会出现服务器内存都还不够session使用的情况。

  2. session会话保持
    会话保持是利用负载均衡的原地址Hash算法实现,负载均衡服务器总是将来源于同一IP的请求分发到同一台服务器上。

    这种方案虽然保证了每个用户都能准确的拿到自己的session,而且大量用户访问也不怕,但是这种会话保持不符合系统高可用的需求。这种方案有着致命的缺陷:一旦某台服务器发生宕机,则该服务器上的所有session信息就会不存在,用户请求就会切换到其他服务器,而其他服务器因为没有其对应的session信息导致无法完成相关业务。所以这种方法基本上不会被采纳。

  3. cookie记录
    将session或者token记录在客户端,每次请求服务器的时候将session或者token放在请求中发送给服务器,服务器进行校验即可判断是否登录。

    利用cookie记录session是存在很多缺点:比如cookie的大小存在限制能记录的信息不能超过限制;比如每次请求都要传输cookie影响性能;比如cookie可被修改或者存在破解的可能,导致cookie不能存重要信息,安全系数不够。但是由于cookie简单易用,支持服务器的线性伸缩,而且大部分的session信息相对较小,所以其实很多网站或多或少的都会使用cookie来记录部分不重要的session信息。

  4. session共享
    使用redis保存系统的所有session,redis作为一个存储中心,分布式系统的多台机器可以共享使用,当请求时,去redis中查找是否存在session,即可判断用户是否登录。

    此方式对redis的可用性较高,需要搭建redis集群。

5. 如何保障请求执行顺序

一般来说,从业务逻辑上最好设计系统不需要这种顺序的保证,因为一旦引入顺序性保障,会导致系统复杂度的上升,效率会降低,对于热点数据会压力过大等问题。

首先使用一致性hash负载均衡策略,将同一个id的请求都分发到同一个机器上面去处理,比如订单可以根据订单id。如果处理的机器上面是多线程处理的,可以引入内存队列去处理,将相同id的请求通过hash到同一个队列当中,一个队列只对应一个处理线程。
最好能将多个操作合并成一个操作。

————————————————
版权声明:本文为CSDN博主「一只叫狗的猫」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/zgsxhdzxl/article/details/104414475

原网站

版权声明
本文为[Linging_24]所创,转载请带上原文链接,感谢
https://blog.csdn.net/Linging_24/article/details/120751653