网站生成静态慢原因建设银行档案管理网站
网站生成静态慢原因,建设银行档案管理网站,长春专业做网站的公司有哪些,wordpress 插件怎么用1. 什么是幂等性#xff1f;
幂等性是指在分布式系统中#xff0c;一个操作多次执行的结果与其执行一次的结果相同。设计具有幂等性的分布式系统可以有效避免数据不一致和重复处理的问题。
幂等系统的应用场景
在微服务架构下#xff0c;由于分布式天然特性的时序问题, 以…1. 什么是幂等性
幂等性是指在分布式系统中一个操作多次执行的结果与其执行一次的结果相同。设计具有幂等性的分布式系统可以有效避免数据不一致和重复处理的问题。
幂等系统的应用场景
在微服务架构下由于分布式天然特性的时序问题, 以及网络的不可靠性(机器、机架、机房故障, 电缆被挖断等等), 重复请求很常见, 接口幂等性设计就显得尤为重要。 比如浏览器/客户端多次提交、微服务间超时重试、消息重复消费等。 以订单流程为例的幂等性场景
1.一个订单创建接口第一次调用超时了然后调用方重试了一次
2.在订单创建时我们需要去扣减库存这时接口发生了超时调用方重试了一次
3.当这笔订单开始支付在支付请求发出之后在服务端发生了扣钱操作接口响应超时了调用方重试了一次
4.一个订单状态更新接口调用方连续发送了两个消息一个是已创建一个是已付款。但是你先接收到已付款然后又接收到了已创建
5.在支付完成订单之后需要发送一条短信当一台机器接收到短信发送的消息之后处理较慢。消息中间件又把消息投递给另外一台机器处理为了解决以上问题就需要保证接口的幂等性接口的幂等性实际上就是接口可重复调用在调用方多次调用的情况下接口最终得到的结果是一致的。有些接口可以天然的实现幂等性比如查询接口对于查询来说你查询一次和两次对于系统来说没有任何影响查出的结果也是一样。除了查询功能具有天然的幂等性之外增加、更新、删除都要保证幂等性。
2. 分布式幂等性设计方法
2.1 利用数据库实现幂等性
数据库的唯一约束和事务特性可以用来实现幂等性。例如在处理支付请求时我们可以在支付记录表中插入一条带有唯一支付 ID 的记录。如果数据库已存在相同支付 ID 的记录则认为该支付请求已处理过从而实现幂等性。
1、去重表唯一索引
往数据库去重表里插入数据的时候利用数据库的唯一索引特性保证唯一的逻辑。唯一序列号可以是一个字段例如订单的订单号也可以是多字段的唯一性组合。
使用数据库防重表的方式它有个严重的缺点那就是系统容错性不高如果幂等表所在的数据库连接异常或所在的服务器异常则会导致整个系统幂等性校验出问题。
2、多版本号控制之乐观锁
多版本并发控制该策略主要使用update with condition更新带条件来防止来保证多次外部请求调用对系统的影响是一致的。在系统设计的过程中合理的使用乐观锁通过version或者updateTimetimestamp等其他条件来做乐观锁的判断条件这样保证更新操作即使在并发的情况下也不会有太大的问题。借鉴数据库的乐观锁机制。
示例
update t_goods set count count -1 , version version 1 where good_id2 and version 1
根据version版本也就是在操作库存前先获取当前商品的version版本号然后操作的时候带上此version号。我们梳理下我们第一次操作库存时得到version为1调用库存服务version变成了2但返回给订单服务出现了问题订单服务又一次发起调用库存服务当订单服务传如的version还是1再执行上面的sql语句时就不会执行因为version已经变为2了where条件就不成立。这样就保证了不管调用几次只会真正的处理一次。
3、悲观锁
使用悲观锁实现幂等性一般是配合事务一起来实现。
使用select…for update会把数据给锁住不过我们需要注意一些锁的级别MySQL InnoDB默认行级锁。行级锁都是基于索引的如果一条SQL语句用不到索引是不会使用行级锁的会使用表级锁把整张表锁住。for update仅适用于InnoDB且必须在事务块(BEGIN/COMMIT)中才能生效。在进行事务操作时通过“for update”语句MySQL会对查询结果集中每行数据都添加排他锁其他线程对该记录的更新与删除操作都会阻塞。排他锁包含行锁、表锁。
select for update整个执行过程中锁定该订单对应的记录。注意这种在DB读大于写的情况下尽量少用。
举个更新订单的业务场景
假设先查出订单如果查到的是处理中状态就处理完业务再然后更新订单状态为完成。如果查到订单并且是不是处理中的状态则直接返回
4、全局唯一ID
如果使用全局唯一ID就是根据业务的操作和内容生成一个全局ID在执行操作前先根据这个全局唯一ID是否存在来判断这个操作是否已经执行。如果不存在则把全局ID存储到存储系统中比如数据库、Redis等。如果存在则表示该方法已经执行。使用全局唯一ID是一个通用方案可以支持插入、更新、删除业务操作。
结合redis的incr自增实现全局唯一ID是一个常用的方案。
示例代码 2.2 使用分布式事务实现幂等性
在涉及多个服务和数据源的场景下可以使用分布式事务来实现幂等性。例如使用两阶段提交2PC或者三阶段提交3PC协议来保证多个服务间的数据一致性。
示例代码 在这个示例中我们使用 GlobalTransactional 注解来标记需要分布式事务支持的方法。在处理预订请求时系统首先检查预订记录是否已存在然后依次调用酒店服务和支付服务。如果其中任何一个服务出现异常分布式事务将回滚确保数据的一致性和幂等性。
2.3、token机制
token机制的幂等保障的主要流程就是
1.服务端提供了发送token的接口。我们在分析业务的时候哪些业务是存在幂等问题的就必须在执行业务前先去获取token服务器会把token保存2.到redis中。微服务肯定是分布式了如果单机就适用jvm缓存。
3.然后调用业务接口请求时把token携带过去一般放在请求头部。
4.服务器判断token是否存在redis中存在表示第一次请求这时把redis中的token删除继续执行业务。
5.如果判断token不存在redis中就表示是重复操作直接返回重复标记给client这样就保证了业务代码不被重复执行。缺点
业务请求每次请求都会有额外的请求一次获取token请求、判断token是否存在的业务。其实真实的生产环境中1万请求也许只会存在10个左右的请求会发生重试为了这10个请求我们让9990个请求都发生了额外的请求。当然redis性能很好耗时不会太明显
2.4分布式锁
分布式锁可以确保同一时间只有一个线程处理特定的操作。我们可以在处理关键业务逻辑之前获取分布式锁从而保证幂等性。
示例代码 分布式锁实现幂等性的逻辑是在每次执行方法之前判断是否可以获取到分布式锁如果可以则表示为第一次执行方法否则直接舍弃请求即可。需要注意的是分布式锁的key必须为业务的唯一标识通常适用redis或者zookeeper来实现分布式锁
如果是分布是系统构建唯一索引比较困难例如唯一性的字段没法确定这时候可以引入分布式锁通过第三方的系统在业务系统插入数据或者更新数据获取分布式锁然后做操作之后释放锁这样其实是把多线程并发的锁的思路引入多多个系统也就是分布式系统中得解决思路
目前主要有几种方式实现分布式锁
1、redis setNx命令
1获取锁的时候使用setnx加锁并使用expire命令为锁添加一个超时时间超过该时间则自动释放锁锁的value值为一个随机生成的UUID通过此在释放锁的时候进行判断。
2获取锁的时候还设置一个获取的超时时间若超过这个时间则放弃获取锁。
3释放锁的时候通过UUID判断是不是该锁若是该锁则执行delete进行锁释放。
优点
1Redis有很高的性能 2Redis命令对此支持较好实现起来比较方便
2基于ZooKeeper的实现方式
ZooKeeper是一个为分布式应用提供一致性服务的开源组件它内部是一个分层的文件系统目录树结构规定同一个目录下只能有一个唯一文件名。基于ZooKeeper实现分布式锁的步骤如下
1创建一个目录mylock 2线程A想获取锁就在mylock目录下创建临时顺序节点 3获取mylock目录下所有的子节点然后获取比自己小的兄弟节点如果不存在则说明当前线程顺序号最小获得锁 4线程B获取所有节点判断自己不是最小节点设置监听比自己次小的节点 5线程A处理完删除自己的节点线程B监听到变更事件判断自己是不是最小的节点如果是则获得锁。
优点具备高可用、可重入、阻塞锁特性可解决失效死锁问题。
缺点因为需要频繁的创建和删除节点性能上不如Redis方式。
3, 状态机
在设计单据相关的业务或者是任务相关的业务肯定会涉及到状态机就是业务单据上面有个状态状态在不同的情况下会发生变更一般情况下存在有限状态机这时候如果状态机已经处于下一个状态这时候来了一个上一个状态的变更理论上是不能够变更的这样的话保证了有限状态机的幂等。
很多业务表都是有状态的比如转账流水表就会有0-待处理1-处理中、2-成功、3-失败状态。转账流水更新的时候都会涉及流水状态更新即涉及状态机 (即状态变更图)。
状态机是怎么实现幂等的呢
第1次请求来时如流水号是 666该流水的状态是处理中值是 1要更新为2-成功的状态所以该update语句可以正常更新数据sql执行结果的影响行数是1流水状态最后变成了2。 第2请求也过来了如果它的流水号还是 666因为该流水状态已经2-成功的状态了所以不会再处理业务逻辑接口直接返回。 示例 对于不少业务是有一个业务流转状态的每一个状态都有前置状态和后置状态以及最后的结束状态。例如流程的待审批审批中驳回从新发起审批经过审批拒绝。订单的待提交待支付已支付取消。
3.幂等性设计的注意事项
在实现分布式幂等性时需要考虑以下几点 幂等性操作的粒度根据业务场景和性能要求可以选择适当的幂等性设计粒度如方法级、服务级或全局级。 幂等性与性能的权衡实现幂等性可能会增加系统的复杂性和性能开销。在设计时需要考虑这些因素并选择合适的实现策略。 幂等性与可用性的关系某些幂等性实现方法可能会影响系统的可用性如分布式锁。在设计时需要充分了解各种方法的优缺点选择合适的方案。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/89683.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!