0
点赞
收藏
分享

微信扫一扫

如何安全进行速卖通自养号测评操作?

开源分享 2024-04-29 阅读 9

1. 幂等性的概念

        接口幂等性是指在软件工程和Web服务领域中,一个接口(通常是HTTP API)无论被调用一次还是多次,其对系统产生的副作用应该是相同的,即结果保持一致,不会因为多次请求而有所不同。换句话说,多次执行同一操作应当产生与执行一次相同的效果,不会额外改变系统的状态。

2. 幂等性的核心价值

确保数据一致性:在存在网络延迟或不稳定的情况下,请求可能被重复发送。幂等性确保即使请求多次到达服务器,也不会导致多次创建资源、多次扣除账户余额等错误,从而维护了数据的一致性和完整性。

简化错误处理:客户端可以更简单地处理请求失败的情况,只需重试即可,无需复杂的逻辑来判断是否需要重试或如何处理潜在的副作用。

提升用户体验:用户操作(如点击支付按钮)因网络问题或误操作导致的重复提交,不会引起多次扣款等不良后果,增强了用户对系统的信任感。

3. 幂等性与HTTP方法

请求类型安全性与幂等性描述
GET安全且幂等用于获取资源,多次请求应返回相同的结果
PUT不安全但幂等用于替换整个资源。无论PUT操作执行多少次,资源最终状态都是一样的,即被最后的请求体内容所替换
POST不安全且不幂等用于创建新的资源,多次调用可能会创建多个资源
DELETE不安全但幂等重复提交,删除一个已经不存在的资源,不会改变系统状态

        其中POST是非幂等的,因为它用于创建新的资源,多次调用可能会创建多个不同的资源。但在某些设计中,如果POST请求设计为总是创建相同的结果(基于请求数据和当前系统状态),也可以实现幂等性。

4. 幂等性的应用场景

        幂等性对于保证系统的一致性和可靠性至关重要,尤其是在分布式系统和网络不稳定环境下,它有助于处理如下几种常见场景:

  • 网络重传:在网络不稳定的情况下,请求可能会被重传,幂等性确保重传不会导致多次执行操作,如多次扣款。
  • 用户误操作:用户可能因页面刷新、误点击等原因重复提交请求,幂等性保护用户免受因此导致的数据不一致影响。
  • 用户恶意刷单:比如在抢兑换码、投票这种互动中,可能会有用户会进行恶意的重复发送请求,恶意刷单,使结果不实。
  • 异步消息重复处理:在使用消息队列或事件驱动架构时,消息可能因故障恢复机制被重新投递,幂等性处理可以避免业务逻辑被重复执行

5. 解决方案

保证接口幂等性有多种方法,当前提供数据库方案,如下:

5.1. 数据库唯一索引

这可以算是最简单的方法了,直接在数据库表中的某个关键字段设置唯一索引,下面以订单(order)数据库表为例写一段SQL:

alter table `order` add UNIQUE KEY `t_xxx` (`某个字段`); 

加了唯一索引之后,第一次请求数据可以插入成功。但后面的相同请求,插入数据时会报异常,表示唯一索引有冲突:

Duplicate entry '002' for key 'order.t_code

具体流程图如下:

5.2. 建立防重表

        有同学可能就问了,上面的方案不太合理,因为有时候我们的表中需要一些重复数据,只有一些特殊场景才不需要重复数据,唯一索引方案可能就不合适了。

        这个时候可以试试防重表,简单来说就是我们再单独建立一张表,只需要含有id和想要唯一的索引字段。

具体流程图如下:

5.3. 悲观锁机制

        悲观锁机制可以作为一种手段来帮助解决接口幂等性问题,尤其是在处理高并发场景下对数据的并发修改需求。悲观锁的基本假设是数据在并发访问期间很可能发生冲突,因此在事务开始时就立即锁定所需的数据资源,防止其他事务对其进行修改,直到当前事务结束。

        以下是利用MySQL悲观锁机制解决接口幂等性的基本方案:

1. 使用SELECT ... FOR UPDATE

        在执行更新操作之前,先使用SELECT ... FOR UPDATE语句锁定要修改的行。这会在读取数据的同时加上排他锁(X锁),确保其他事务无法修改这些数据,直到当前事务结束(提交或回滚)。

START TRANSACTION;

SELECT * FROM your_table WHERE id = ? FOR UPDATE;

-- 根据查询结果判断是否需要更新
IF (需要更新) THEN
    UPDATE your_table SET column=value WHERE id = ?;
END IF;

COMMIT;

2. 结合接口幂等性设计

结合上述SQL操作,可以设计一个幂等性接口处理流程:

        大缺点:悲观锁需要在同一个事务操作过程中锁住一行数据,如果事务耗时比较长,会造成大量的请求等待,影响接口性能。

5.4. 乐观锁机制

        悲观锁会增加锁争用的可能性,可能导致事务等待和阻塞,影响系统性能,特别是在高并发场景下。因此,应谨慎使用,乐观锁某些情况下就是个很好的替代方案。

        MySQL乐观锁机制是一种非阻塞的并发控制策略,它假定多线程同时修改数据的概率较低,因此不会在事务一开始就对数据加锁,而是在更新数据时检查数据是否被其他事务修改过。这对于高并发场景下解决接口幂等性问题特别有效,因为它减少了锁的竞争,提高了系统的吞吐量。以下是利用MySQL乐观锁机制解决接口幂等性的方案:

1. 版本字段实现乐观锁

在数据库表中添加一个额外的字段作为版本控制,比如version字段,初始值为1。

CREATE TABLE your_table (
    id INT PRIMARY KEY,
    data VARCHAR(100),
    version INT DEFAULT 1
);

2. 接口调用流程

客户端请求:客户端发出修改数据的请求,请求中包含数据的原始版本号(如果有的话)。

读取数据并附带版本信息:服务端首先查询需要更新的数据,并获取其当前的版本号。

SELECT * FROM your_table WHERE id = ?;

 幂等性检查与更新:在更新数据时,同时在UPDATE语句中加入版本号的条件检查,确保只有当版本号与查询时一致时才执行更新。

   UPDATE your_table 
   SET data = ?, version = version + 1 
   WHERE id = ? AND version = ?;

---(data = ? 是要更新的新数据值。
---version = version + 1 表示更新成功后,版本号递增。
---WHERE id = ? AND version = ? 确保只有当记录的版本号与预期一致时才执行更新。)

④ 结果判断:根据UPDATE语句影响的行数判断是否更新成功。

如果影响行数为1,说明更新成功,且数据没有被其他事务修改过。
如果影响行数为0,说明数据在执行更新前已经被其他事务修改,此时可以根据业务逻辑选择重试或返回错误信息。

具体流程图如下:

今天写到这里,明天再来写token方案哈。

举报

相关推荐

0 条评论