暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

无状态和幂等

老码农空杯修行记 2020-08-23
1592

无状态设计如何诞生

后台开发可能都经历过下面这种架构,尤其在初创公司或小规模公司内经常这样设计,产品往往做前后端分离,服务MVC架构

其缺点:单点问题,服务宕机整个服务不能用;用户体验,一个服务提供,大量请求无法快速响应

随着公司的成长,用户增加,这种架构的缺点暴露无遗,此时单个服务承载能力受限制,用户无法得到好的体验,此时怎么办?往往做法是Nginx后面再挂一台机器,部署同样的服务,也就是做了冗余

冗余之后什么单点,用户体验全部解决了。但是随便加一台机器,启动一个服务就可以了吗,中间服务不需要做任何改动?其实是有前提的,能够冗余,服务设计必须要无状态
无状态解决问题
  • 降低响应延时,提升用户体验

  • 服务自由冗余,依据业务规模快速扩容和缩容
无状态

同一服务冗余部署N个,比如3个,那么客户端访问服务时,若参数相同请求api相同(同一个服务)时,无论是否是同一个客户端,还是不同时间点都应该返回一致的结果,此时我们就说服务满足无状态设计。

无状态手段

把有状态的数据从服务分离出来,单独存储,比如存到公共缓存、比如放到客户端

案例-1 
以下session存储设计哪些是无状态化设计?

     

                    A:DB 存储                                              B:APP 存储

 

                    C:服务存储                                       D:cache 存储

案例-2

下面每个服务都把地域数据存储到了服务的内存,那么服务是无状态的吗?

幂等
业务幂等
业务的预期,比如每人只能抢购一部手机,若有用户拿着手机和pad同时抢购,得到两部手机,那么未达到预期,就说业务没有做到幂等。业务幂等是在并发场景下,多个请求产生的影响是否符合业务场景预期。本质来讲是分布式锁的问题,但凡锁其本质都是将多个操作串行化。比如抢购,先拿到锁,然后在共享资源中写一条 uid=1 这么条记录,然后其它请求发现请求中的uid已经有记录,直接返回成功即可。
请求幂等

同一个请求重复执行和执行一次的所产生的影响一致,比如,银行转账,用户A向用户B赚100元,网络抖动或故障或服务故障,导致某个环节重试,但无论怎样,都要保证最终用户A只向用户B转账100元,而不是其它金额。

请求幂等解决的问题

幂等是要保证数据和用户或业务的预期一致,数据在哪儿?在数据库。谁会改变数据库?CRUD操作会改变数据,因此幂等本质变成了CRUD要幂等。因此判定那块需要幂等,就看谁在操作CRUD,在微服务中就是DAS(数据访问服务)了

Create 操作幂等吗
  • 自增主键:app发起请求存储用户数据,第一次走①的流程,由于app请求超时,app重试,发起第二次请求,第二次按照②的路径,最终导致数据库张三的用户重复插入两条,所以自增主键的 Create 操作不幂等

  • 自增主键+唯一索引:假设上图中,设置name为唯一索引,那么②的路径就会执行失败,所以幂等

  • 业务主键:数据库不采用自增主键,然后客户端在操作时首先获取一个主键,然后带上主键去请求,这样能保证幂等。主键一定是客户端获取,其它地方都会造成重试,重新生成主键可能还是不幂等

Select操作幂等吗

读操作不改变数据,天然幂等

Update操作幂等吗

app企图修改张三年龄,第一次修改为19,然后数据库修改变为了19,接着app修改为20,沿着②的路径修改为20;但是网关发现①的请求失败或超时,所以重试再次发起请求,按照③的路径将年龄修改为19,但是app希望的是20,这就发生了不幂等,这是ABA问题,就是说Update在ABA的问题中不幂等

如何解决?乐观锁,修改时先读取上次的状态再比较,条件满足则更新。比如上面update操作,首先读取上一次数据状态,比如18,然后进行update name=19 where name=张三 and age=18,此时若超时,再发起请求时,由于age已经变成了20,重试操作会失败,从而保证了数据的正确;还有可以维护一个状态(维护一个状态机)或版本字段,更新时比较状态或版本,然后执行更新操作。

Delete操作幂等吗

delete操作,一般的删除幂等,删一次和删除两次都一样,但是类似带上limit这样的删除不幂等,会多删除数据,但是这种业务中很少用。


文章转载自老码农空杯修行记,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论