跳转到内容

Redis - 经典业务场景

草稿难度:中级#Redis

原文:CSDN(历史文章导入,当前状态为草稿)

大Key问题是指在Redis等内存数据库中,某个Key对应的value数据结构过大,通常是指单个Key的大小超过10KB甚至达到MB级别。这些大Key在读写操作时会消耗过多的内存和网络带宽,导致Redis性能下降,甚至引发系统稳定性问题。
从本质上看,大Key问题是内存数据结构不合理使用的结果。Redis作为内存数据库,其主要优势在于高速的内存读写和原子操作,但这些优势建立在数据结构合理使用的基础上。当单个Key存储了过多数据时,会导致内存分配不均衡、网络传输效率降低,违背了Redis的设计初衷。
典型的大Key场景包括:用户购物车数据(一个Hash可能包含数百个商品)、商品的全量SKU信息(一个Hash包含所有规格组合)、用户收藏列表(一个Set或List包含大量商品ID)等。这些大Key在高并发场景下会成为系统的性能瓶颈.

大Key问题主要带来四方面危害:

  • 一是读写性能下降,影响响应时间;
  • 二是内存分片不均衡,导致某些节点内存使用率过高;
  • 三是在集群扩容或故障转移时,大Key迁移会带来网络阻塞和服务卡顿;
  • 四是删除大Key时可能导致Redis阻塞,影响其他操作。

识别大Key主要有三种方法:

  • 一是使用Redis自带的SCAN命令配合DEBUG OBJECT获取Key的大小;
  • 二是使用redis-cli的–bigkeys选项进行扫描;
  • 三是通过第三方工具如redis-rdb-tools分析RDB文件。
    在生产环境中,我们通常结合多种方法进行定期检查。
    一套完整的大Key监控机制大概有下面几个步骤:
  • 定期扫描:每天凌晨低峰期,我们使用redis-cli –bigkeys对生产环境进行扫描,识别潜在的大Key。为了减少对线上服务的影响,我们设置了较低的扫描频率。
  • 采样分析:我们开发了一个自定义工具,通过SCAN命令随机采样约5%的Key,并使用DEBUG OBJECT命令获取这些Key的内存使用情况,生成大Key分布报告。
  • RDB分析:每周我们会对备份的RDB文件进行离线分析,使用redis-rdb-tools生成完整的Key大小分布报告,识别潜在的大Key。
  • 监控告警:当发现单个Key大小超过预设阈值(如1MB)时,系统会自动发出告警,并记录相关信息供后续分析。

解决大Key最直接的方法是优化数据结构,将大Key拆分成多个小Key。常见的拆分策略包括:哈希拆分、范围拆分和时间拆分等。通过合理的拆分策略,可以显著降低单个Key的大小,提高操作效率.
比如在电商系统中,可以对几类典型的大key进行拆分优化:

  • 用户购物车:原本使用一个Hash存储所有商品,改为按照商品类别拆分成多个Hash,如cart:user:10001:electronics、cart:user:10001:clothing等,既减小了单个Key的大小,又提高了类别相关操作的效率。
  • 商品SKU信息:将原本一个包含所有SKU的大Hash拆分为多个小Hash,按照SKU ID的范围进行拆分,如product:10001:sku:1-100、product:10001:sku:101-200等。
  • 用户浏览历史:从单个List改为按时间范围拆分的多个List,如history:user:10001:202301、history:user:10001:202302等,每个List只存储一个月的浏览记录。

对于必须保持完整的大Key,可以通过压缩算法减小数据体积。常用的方法包括使用高效的序列化格式如Protocol Buffers或MessagePack替代JSON,以及对大文本使用gzip或snappy等压缩算法。这些方法可以在不改变数据结构的情况下,显著减小Key的存储大小。
比如电商系统中有商品详情缓存这类不适合拆分的大key,可以采用以下优化方案:

  • 高效序列化:将原本使用的JSON格式替换为Protocol Buffers,减小了约30%的数据体积。特别是对于包含大量重复字段名的结构化数据,这种优化效果显著。
  • 选择性压缩:对于商品描述、规格参数等文本内容较多的字段,我们使用gzip算法进行压缩,压缩率达到70%以上。
  • 压缩阈值:我们设置了智能压缩策略,只有当数据大小超过5KB时才进行压缩,避免对小数据进行压缩反而增加CPU开销。
  • 缓存压缩结果:为了避免重复压缩,我们在应用层缓存了压缩结果,只有数据变更时才重新压缩。

预防大Key问题的关键是建立有效的监控和预警机制,以及在开发阶段就形成良好的数据设计习惯。我们实施了包括大Key自动发现、定期报告、代码审查和开发规范在内的全方位预防策略.
一套完整的大key监控机制大概有下面几个步骤:

  • 设计阶段控制:在数据模型设计阶段,开发人员评估每个Key的潜在大小和增长趋势,对可能成为大Key的数据结构进行提前拆分设计。
  • 代码审查:我们在代码审查中特别关注Redis操作,确保没有不合理的数据结构使用,如无限增长的集合或不设上限的列表。
  • 自动化测试:我们开发了专门的测试工具,在测试环境中模拟数据增长,提前发现可能的大Key问题。
  • 实时监控:生产环境中,我们的监控系统会实时跟踪每个Redis命令的执行时间,当发现异常耗时的操作时,自动记录相关Key信息并告警。
  • 容量规划:基于历史数据增长趋势,我们定期进行容量规划,预测未来可能出现的大Key,并提前进行优化。

热Key问题是指在分布式缓存或数据库系统中,某些特定的Key在短时间内接收到大量的访问请求,导致这些Key所在的节点负载过高,形成系统瓶颈,甚至引发雪崩效应。这类似于现实世界中的’热点’现象,少数资源承受了大部分的访问压力.
从本质上看,热Key问题是资源分配不均衡的表现。在理想情况下,请求应该均匀分布在所有节点上,但实际业务中,数据访问通常遵循二八定律,即20%的数据承担了80%的访问量。当这种不均衡达到极端时,就形成了热Key.
例如:秒杀活动中的商品库存Key、双十一期间的热门商品信息Key、实时排行榜数据Key等,这些Key在特定时间段内会接收到远超系统平均水平的访问请求。

热Key问题会导致多方面的系统风险:

  • 首先,热Key所在节点可能因负载过高而响应变慢或崩溃;
  • 其次,当热Key节点不可用时,大量请求可能会穿透到后端数据库,引发连锁反应;
  • 最后,即使系统没有崩溃,热Key也会导致资源利用不均衡,降低整体系统效率

要解决这种极热 key 的问题,首先要找出这些 Hot key 来。
识别热Key主要有三种方法:

  • 一是通过Redis自带的监控命令如MONITOR或INFO进行实时监控;
  • 二是使用第三方工具如Redis-faina或Redis-stat进行数据分析;
  • 三是在应用层进行采样统计,记录高频访问的Key。

在项目中,一般用多层次的热key识别策略:

  • 预防性识别:基于业务特性,提前预判可能的热Key。例如,新品发布、促销活动、热点新闻等场景下的相关Key。
  • 实时监控:我们开发了一个专门的热Key监控服务,通过在Redis代理层采样请求,并结合滑动窗口计数算法,实时识别访问频率突增的Key。
  • 日志分析:对Redis的慢查询日志和访问日志进行离线分析,识别历史上的热Key模式,用于优化未来的策略。
  • 自适应采样:在高峰期增加采样率,低峰期降低采样率,平衡监控精度和系统开销

在应用服务器上引入本地缓存,可以有效减轻Redis集群的热Key压力。常用的本地缓存方案包括Caffeine、Guava Cache等,通过合理设置过期时间和更新策略,可以在保证数据相对新鲜的同时,大幅降低对分布式缓存的访问频率。
对于商品详情这类读多写少的数据,可以在应用服务器上部署了两级缓存:

  • JVM本地缓存:使用Caffeine实现,针对超热Key设置较短的过期时间(如10秒)和较大的容量。
  • 分布式缓存:使用Redis集群,作为本地缓存未命中时的第二层防护
    同时,我们通过消息队列实现了缓存更新的准实时通知,当商品信息变更时,主动失效相关的本地缓存,保证数据的一致性。

热Key分片是指将一个热Key的数据分散到多个子Key中,每个子Key负责一部分数据,从而将访问压力分散到多个节点。这种方法特别适用于可以进行数据分割的场景,如列表数据、计数器等.
比如,对于一个商品评论列表这类的热key,我们采用分片策略:

  • 数据分片:将评论数据按照时间或ID范围分成多个子列表,存储在不同的Key中,如product:10001:comments:1、product:10001:comments:2等。
  • 请求路由:客户端请求时,根据页码或时间范围计算出应访问的子Key,或者使用随机策略选择一个子Key。
  • 结果聚合:对于需要聚合结果的场景,如获取评论总数,我们预先计算并存储在单独的Key中,或者使用Redis的脚本功能在服务端进行聚合。
    这种分片策略使我们能够将单个热Key的访问压力分散到多个Redis节点,有效避免了单点瓶颈。

利用Redis的主从复制机制,可以实现读写分离,将读请求分流到多个从节点,减轻主节点压力。对于特别热的Key,还可以实现’副本漂移’,即为热Key创建更多的副本,提供更大的读取带宽。
项目中实现动态读写分离策略思路:

  • 基础读写分离:使用Redis Sentinel或Redis Cluster,将读请求默认路由到从节点,写请求路由到主节点。
  • 动态副本调整:监控系统实时检测热Key,当发现热Key时,自动为其创建额外的副本,并更新路由策略,将该Key的读请求优先路由到这些副本。
  • 一致性保证:对于强一致性要求的场景,我们实现了’读-写-读’模式,即先尝试从节点读取,如果数据过期或不存在,则回源到主节点,并更新从节点数据。
    这种动态调整的策略,使我们能够针对不同的Key提供不同级别的服务质量,既保证了热Key的访问性能,又避免了资源浪费。

秒杀场景的本质是在极短时间内承受大量并发请求,同时保证有限商品的正确售卖。它具有三个核心特征:高并发(短时间内大量用户涌入)、资源有限(商品数量有限)和时效性强(活动在特定时间开始和结束)。这种场景对系统的性能、一致性和可用性提出了极高的挑战。
从技术角度看,秒杀是一个典型的’多进程争抢有限资源’问题。以我们电商平台的一次手机秒杀为例,活动开始后的前30秒内,系统承受了超过50万QPS的峰值请求,而商品库存仅有1000台。这意味着系统需要在极短时间内从50万请求中准确筛选出1000个成功请求,同时保证不超卖、不重复售卖,并给其余用户提供良好的失败体验。这种极端的请求比和资源比,使秒杀成为检验系统架构和技术能力的重要场景

秒杀系统最大的挑战是处理瞬时的高并发请求。普通系统的QPS可能是几百或几千,而秒杀系统需要应对可能达到几十万甚至上百万的QPS。这种量级的请求会对系统的每一层(从网络到应用再到数据库)都造成巨大压力。
面临的具体挑战包括:

  • 流量洪峰:活动开始的瞬间,QPS从平时的2000左右暴增至超过10+万,这种突发流量会导致系统各层面的资源争抢和排队。
  • 连接数暴增:大量用户同时连接,导致网络连接数迅速达到系统上限,新的连接请求被拒绝。
  • 数据库压力:如果没有合理设计,所有请求都会直接冲击数据库,导致数据库CPU使用率飙升,响应时间从毫秒级增加到秒级,甚至宕机。
  • 缓存失效:大量相同请求可能导致缓存失效或缓存雪崩,进一步加剧后端系统压力。
  • 资源争抢:多个服务实例同时争抢有限的库存资源,导致超卖或库存不一致问题

秒杀系统的另一大挑战是保证数据一致性,特别是库存数据。在高并发环境下,如何确保商品不超卖、不重复售卖,同时又不影响系统性能,是一个复杂的平衡问题.
数据一致性主要体现在以下几个方面:

  • 库存精确控制:确保系统最终售出的商品数量与设定的库存数量完全一致,不多不少。
  • 重复购买控制:防止同一用户通过多次点击或使用多个设备重复购买,确保购买机会公平分配。
  • 订单与库存一致:确保每个成功创建的订单都有对应的库存记录,避免出现’有订单无库存’或’有库存无订单’的不一致状态。
  • 支付与订单一致:确保用户支付的金额与订单金额一致,且每笔支付都对应到正确的订单。

秒杀系统还面临严峻的安全挑战,包括恶意抢购、接口刷单、数据篡改等风险。由于秒杀商品通常具有较高价值,会吸引大量黑产利用技术手段进行不正当获利.
有几种常见的安全威胁:

  • 机器人抢购:黑产使用自动化脚本模拟用户行为,以远超正常人类的速度和频率发起请求,抢占正常用户的购买机会。
  • 接口攻击:绕过前端页面直接调用后端接口,跳过各种前端验证和限制。
  • 数据篡改:尝试修改请求参数,如商品价格、数量或优惠信息,获取不正当利益。
  • 分布式拒绝服务攻击:通过大量无效请求占用系统资源,影响正常用户访问。
  • 账号共享与代抢:一个账号多人使用或专业代抢服务,违背活动公平原则。

秒杀系统的前端策略主要包括:静态化、限流、排队和体验优化。通过将活动页面静态化减轻服务器压力;客户端限流控制请求频率;实现排队机制提供更好的用户体验;以及采用各种前端优化技术提升页面性能.
在秒杀系统中,前端可以采用了以下策略:

  • 页面静态化:将秒杀页面大部分内容转为静态资源,部署在CDN上,减少对应用服务器的请求。我们的实践表明,这种方法可以将动态请求减少约80%,显著降低后端压力。
  • 前端限流:在JavaScript中实现点击按钮后的冷却期(如5秒内禁止再次点击),减少用户重复提交。同时,使用本地存储记录用户操作状态,防止刷新页面绕过限制。
  • 排队体验优化:实现前端排队进度展示,当检测到系统繁忙时,自动将用户请求转入排队模式,显示当前排队位置和预估等待时间,提升用户体验。
  • 资源预加载:活动开始前预加载相关资源,减少活动开始后的资源加载时间。
  • WebSocket实时通知:使用WebSocket建立长连接,服务端可以主动推送抢购结果,避免客户端频繁轮询。
  • 降级展示:准备多级降级方案,当系统负载过高时,可以逐步简化页面功能,保证核心抢购功能可用。
    这些前端策略不仅提升了用户体验,还有效减轻了后端系统压力,是秒杀系统成功的重要因素。

服务层是秒杀系统的核心,主要采用以下设计策略:服务隔离(将秒杀服务与常规服务分离);限流熔断(控制请求流量);异步处理(将非核心流程异步化);以及多级缓存(减轻数据库压力)。这些策略共同保证了服务层的高性能和稳定性。
服务层采用了以下架构设计:

  • 服务隔离:我们将秒杀服务完全独立部署,使用专门的服务集群处理秒杀请求,避免秒杀流量影响其他业务。这种物理隔离比逻辑隔离更可靠,确保了主站业务的稳定性。
  • 限流熔断:在网关层实现了基于令牌桶算法的限流机制,控制进入系统的请求速率。同时,使用Sentinel实现熔断保护,当下游服务出现异常时,快速失败并返回降级响应。
  • 请求预处理:在请求进入核心秒杀逻辑前,先进行一系列验证和过滤,包括用户资格验证、活动状态检查、风控规则等,过滤掉无效请求,减轻后续环节压力。
  • 多级缓存:实现了本地缓存(Caffeine)+ 分布式缓存(Redis)的多级缓存架构,将商品信息、活动规则、库存数据等热点数据缓存起来,减少数据库访问。
  • 异步处理:将订单创建、支付通知、物流信息等非核心流程异步化,用户抢购成功后立即返回结果,后续流程通过消息队列异步处理。
  • 幂等设计:所有关键操作都实现了幂等性处理,确保重复请求不会导致数据不一致,提高系统的容错能力。

库存控制是秒杀系统的核心挑战,主要采用以下策略:

  • 缓存预热(提前将库存加载到缓存);
  • 分布式锁(防止并发修改);
  • 库存预扣减(先扣减再处理订单);
  • 异步确认(异步验证和回滚机制)。
    这些策略共同保证了库存数据的准确性和一致性。
    库存控制采用了多层次的策略:
    库存预热与分段:活动开始前,将商品库存数据预先加载到Redis中。对于大库存商品,我们采用库存分段策略,将库存分为多个段,减少单个库存Key的争抢。
    Redis原子操作:使用Redis的DECR或Lua脚本实现原子化的库存扣减,避免并发问题。例如,我们使用以下Lua脚本进行库存校验和扣减:
if (redis.call('exists', KEYS[1]) == 1) then
local stock = tonumber(redis.call('get', KEYS[1]));
if (stock > 0) then
redis.call('decr', KEYS[1]);
return stock;
end;
return 0;
end;
return -1;
  • 分布式锁控制:对于一些复杂的库存操作,如多商品组合或有附加条件的扣减,我们使用Redisson实现的分布式锁进行控制,确保操作的原子性。
  • 库存预扣减与确认:采用“预扣减-确认”的两阶段模式,先在Redis中预扣减库存并设置过期时间,然后异步创建订单,订单创建成功后再确认库存扣减,超时未确认则自动回滚。
  • 数据库最终一致性:定期将Redis中的库存数据与数据库同步,并设计了库存对账机制,定时检查并修复不一致的数据。
  • 限购与资格控制:使用Redis的Set结构记录已购买用户,确保每个用户只能购买限定数量,防止重复购买。

秒杀系统的订单处理采用异步化、分段处理的策略,主要包括:资格验证、库存检查、订单创建和异步通知等环节。通过消息队列解耦各个环节,提高系统的吞吐能力和可靠性。
秒杀系统中,订单处理流程设计如下:

  • 请求预检:用户请求首先经过一系列预检,包括用户身份验证、活动状态检查、购买资格验证等,过滤掉无效请求。
  • 库存检查与预扣减:通过Redis原子操作检查并预扣减库存,如果库存充足,则生成一个带有过期时间的预订单标记。
  • 消息队列解耦:库存预扣减成功后,不直接创建订单,而是将订单创建请求发送到消息队列(如RocketMQ),由专门的订单处理服务异步处理。
  • 订单创建与确认:订单处理服务从消息队列获取请求,创建正式订单,并在数据库中扣减库存,然后确认Redis中的预扣减,移除过期时间。
  • 结果通知:订单创建结果通过消息队列发送到结果处理服务,再通过WebSocket或消息推送通知用户。
  • 异常处理:在整个流程中,我们设计了完善的异常处理机制,包括消息重试、超时回滚、死信队列等,确保系统的可靠性。
  • 限流控制:在订单处理服务中实现了基于消息消费速率的限流控制,确保订单创建的速度在系统承受范围内。
    这种异步化、分段处理的订单流程设计,使我们的系统能够平滑处理秒杀峰值,订单处理成功率达到99.9%以上,同时保证了数据的一致性和可靠性

秒杀系统的缓存设计采用多级缓存架构,包括本地缓存、分布式缓存和持久化存储。通过合理的缓存策略、失效机制和一致性保证,提高系统的响应速度和承载能力.
在我们的秒杀系统中,缓存设计包括以下几个方面:
多级缓存架构:

  • 一级缓存:应用服务器本地缓存(Caffeine),用于存储热点数据,如商品基本信息、活动规则等。
  • 二级缓存:Redis集群,用于存储共享数据,如库存信息、用户购买记录等。
  • 三级存储:MySQL数据库,作为最终的数据持久化层。
    热点数据预加载:
  • 活动开始前30分钟,系统自动将秒杀商品信息、库存数据等预加载到Redis和本地缓存。
  • 对于超热商品,我们会在所有应用服务器上都预加载其数据,避免缓存未命中。
    缓存更新策略:
  • 采用“先更新数据库,再删除缓存”的策略,配合消息队列实现缓存的最终一致性。
  • 对于库存等关键数据,使用Redis的原子操作直接更新,而不是删除后重建。
    缓存穿透防护:
  • 使用布隆过滤器过滤不存在的商品ID请求,防止缓存穿透。
  • 对于查询结果为空的请求,也缓存空结果(设置较短的过期时间),防止大量无效请求打到数据库。
    缓存雪崩防护:
  • 为不同数据设置随机过期时间,避免同时失效。
  • 实现了缓存失效的平滑策略,当检测到大量缓存同时失效时,自动延长部分缓存的过期时间。
    热点缓存保护:
  • 对于秒杀活动中的热点商品,我们实现了“热点数据多副本”策略,在Redis集群的多个节点上都保存副本,分散访问压力。
  • 使用Redis Cluster的Hash Tags功能,确保相关的热点数据分布在同一个节点上,减少跨节点操作。

在秒杀系统中,分布式锁是保证数据一致性的关键技术。可以使用基于Redis或ZooKeeper的分布式锁实现,配合乐观锁、事务和最终一致性检查,确保系统数据的准确性和一致性.
机制如下:
分布式锁实现:

  • 主要使用Redisson实现的分布式锁,它基于Redis的NX命令和Lua脚本,提供了可重入、自动续期等高级特性。
  • 对于特别关键的操作,如大额支付确认,我们使用ZooKeeper实现的分布式锁作为补充,虽然性能略低但一致性更强。
    锁粒度优化:
  • 我们根据业务特点优化了锁的粒度,对于库存操作使用商品级别的锁,而不是全局锁,提高并发度。
    在某些场景下,我们使用分段锁策略,如将一个商品的库存分为多个段,每个段一个锁,进一步提高并发度。
    乐观锁与版本控制:
  • 在数据库层面,我们使用乐观锁机制(版本号或条件更新),避免并发更新冲突。
    例如,库存扣减SQL使用条件更新:
UPDATE stock SET quantity = quantity - 1, version = version + 1 WHERE id = ? AND quantity >= 1 AND version = ?

分布式事务处理:

  • 对于跨多个资源的操作,如订单创建同时涉及订单表和库存表,我们使用本地消息表模式实现分布式事务。
  • 在某些关键场景,我们也使用TCC(Try-Confirm-Cancel)模式,确保操作的原子性。
    最终一致性保证:
  • 实现了一套完整的对账和修复机制,定期比对Redis中的库存数据和数据库中的实际库存,发现并修复不一致。
  • 设计了“库存-订单”一致性检查任务,确保每个成功的订单都有对应的库存扣减记录。
    故障恢复机制:
  • 当检测到分布式锁服务异常时,系统会自动切换到备用锁实现或降级为本地锁+补偿机制。
  • 所有关键操作都有完整的日志记录,支持故障后的数据恢复和重建。

消息队列在秒杀系统中扮演着关键角色,主要用于流量削峰、系统解耦和异步处理。通过将高并发请求缓冲在消息队列中,然后按照系统处理能力逐步消费,有效避免了瞬时高峰对系统的冲击.
消息队列(主要使用RocketMQ)的应用包括以下几个方面:
1.流量削峰

  • 用户秒杀请求成功后,不直接处理订单创建,而是将请求发送到消息队列。
  • 订单处理服务按照固定的速率从队列中消费消息,如每秒处理500个订单,确保系统稳定运行。
  • 当请求量超过系统处理能力时,多余的请求会暂存在队列中,而不是直接拒绝,提高了用户体验。
    2.系统解耦
  • 将秒杀系统拆分为多个独立服务:请求验证服务、库存服务、订单服务、支付服务等。
  • 各服务之间通过消息队列通信,减少了服务间的直接依赖,提高了系统的可维护性和扩展性。
  • 当某个服务需要升级或扩容时,不会影响其他服务的正常运行。
    3.异步处理
  • 将非核心流程异步化,如订单创建后的短信通知、积分更新、统计数据更新等。
  • 用户只需等待核心流程完成(如库存确认),就能收到成功响应,提升了用户体验。
    4.可靠性保证
  • 使用RocketMQ的事务消息特性,确保消息发送和本地事务的原子性。
  • 实现了消息重试机制,当消息处理失败时,会按照指数退避策略进行重试。
  • 设置了死信队列,对于多次重试仍失败的消息,转入死信队列,由专门的服务处理。
    5.顺序性保证
  • 对于需要保证顺序的操作,如同一商品的库存变更,使用RocketMQ的顺序消息特性,确保消息按照发送顺序被消费。
  • 通过商品ID作为分区键,将同一商品的消息路由到同一个队列,保证处理顺序。
    6.监控与告警
  • 实现了完整的消息队列监控系统,包括队列积压情况、消费延迟、错误率等指标。
  • 当检测到异常情况,如队列积压超过阈值或消费错误率上升,系统会自动发出告警。

秒杀系统的安全防护是多层次的,包括风控策略、验证码机制、接口加密、防重复提交、黑名单机制等。这些措施共同构成了一个完整的安全防护体系,有效防止了恶意抢购和刷单行为.
安全防护措施包括以下几个方面:
用户行为风控:

  • 实现了基于机器学习的用户行为分析系统,识别异常的点击模式和请求频率。
  • 对用户的IP地址、设备指纹、操作时序等多维度数据进行分析,给每个请求分配风险分数。
  • 当风险分数超过阈值时,要求用户进行额外的验证,如短信验证码或滑动验证。
    验证码与人机识别:
  • 在秒杀开始前,要求用户完成验证码或滑动拼图等人机识别任务。
  • 使用动态验证码技术,验证码有效期短(如30秒)且一次性使用,防止批量预生成。
  • 在高风险情况下,启用更复杂的验证机制,如行为验证或生物特征识别。
    接口安全与加密:
  • 所有API请求都需要签名验证,签名包含时间戳、随机数和请求参数的哈希值。
  • 关键参数(如商品ID、价格)使用对称加密传输,防止参数篡改。
  • 实现了API防重放机制,每个请求的时间戳和随机数只能使用一次。
    限流与防刷:
  • 基于用户ID、IP地址和设备ID的多维度限流,如同一用户每分钟最多发起5次请求。
  • 实现了递进式限流策略,随着用户请求频率的增加,限流阈值逐渐降低。
  • 对于检测到的刷单行为,实施渐进式惩罚,从增加验证难度到临时封禁。
    黑名单机制:
  • 维护动态黑名单系统,将检测到的恶意IP、设备ID和用户账号加入黑名单。
  • 黑名单分为多个等级,从增加验证难度到完全拒绝访问。
  • 黑名单信息在集群间实时同步,确保全系统一致的防护策略。
    业务规则防护:
  • 实施严格的购买资格验证,如用户注册时间、历史购买记录、信用评分等。
  • 对于高价值商品,增加额外的验证步骤,如实名认证或绑定银行卡。