# 《Seckill秒杀系统》第109章:实现基于条件限流机制防刷

作者:冰河
星球:http://m6z.cn/6aeFbs (opens new window)
博客:https://binghe.gitcode.host (opens new window)
文章汇总:https://binghe.gitcode.host/md/all/all.html (opens new window)
源码获取地址:https://t.zsxq.com/0dhvFs5oR (opens new window)

沉淀,成长,突破,帮助他人,成就自我。

  • 本章难度:★★☆☆☆
  • 本章重点:实现秒杀系统基于Nginx条件限流的防刷方案,掌握秒杀系统基于条件限流防刷的原理,并能够将基于条件限流防刷的落地方案和实现方式灵活应用到自身实际项目中。

大家好,我是冰河~~

秒杀系统的流程之所以非常高,是因为参与秒杀活动的商品一般都是非常稀缺的商品,这些商品本身的价值又比较高,这无形当中就会吸引很多黄牛党和刷单用户来参与秒杀活动。

# 一、前言

刷单用户和黄牛党会利用非正常手段来向秒杀系统发起大量的请求,这些请求对正常用户来说是非常不公平的,不仅会挤占正常用户抢购秒杀商品的通道,还会大量占用服务器的带宽,消耗大量服务器的资源,如果对这类请求不做限制,可能会引起秒杀系统崩溃宕机,进而引发一系列严重的事故。

# 二、本章诉求

实现接口防刷有多种方案,本章,我们就一起实现接口防刷的第一种方案:基于条件限流防刷。主要基于条件来实现接口的访问频率,以此来达到接口防刷的目的,重点掌握基于条件防刷的实现原理与落地实现方案,并能够将其灵活应用到自身实际项目中。

# 三、实现基于条件限流

这里,我们主要是基于流量网关实现条件限流,尽量将限流方案前置化,将大部分刷单流量挡在整个秒杀系统的入口之外,提升秒杀系统的稳定性和可靠性。

注意:这里我们以获取秒杀活动详情为例,来实现基于用户条件限流的防刷功能。小伙伴们如果想实现基于其他接口的条件限流防刷功能,另外,在之前的演示的基于用户实现限流时,我们是在Lua脚本中写死了用户的标识,这里,我们通过Lua脚本从请求的Header中获取用户Token作为用户的标识,这样就可以在真实环境中实现基于用户的限流。

秒杀系统基于条件限流防刷的具体步骤如下所示。

(1)set_common_var.lua文件

set_common_var.lua文件是一个Lua脚本文件,表示设置一些通用的变量。

源码详见:seckill-nginx工程下的lua/set_common_var.lua。

--获取请求头里的参数
local headers = ngx.req.get_headers()
--获取access_token
local user_access_token = headers["access-token"]
if not user_access_token then
    user_access_token = ""
end
return user_access_token
1
2
3
4
5
6
7
8

可以看到,set_common_var.lua脚本中的主要逻辑就是获取请求头信息,从请求头信息中获取到用户的access-token并返回。

(2)修改domain.com文件

在domain.com文件中引入set_common_var.lua脚本文件,并将返回的user_access_token赋值给$user_access_token变量,如下所示。

#用户token,可作为标识用户的唯一id
set_by_lua_file $user_access_token D:/Workspaces/myself/seckill/myself/seckill/seckill/seckill-nginx/lua/set_common_var.lua;

1
2
3

(3)修改common.conf文件

# 查看完整文章

加入冰河技术 (opens new window)知识星球,解锁完整技术文章与完整代码