高并发场景分析之redis+lua防重校验

 更新时间:2023年07月10日 10:13:34   作者:想养一只萨摩耶~  
这篇文章主要介绍了高并发场景分析之redis+lua防重校验,本文通过示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

高并发场景:redis+lua防重校验

大家平时在做有并发量下单的项目时,代码层面基本上就分为这么几个步骤:参数校验--->防重校验--->库存校验扣减--->下单成功--->支付

最近公司有个商城项目说要30分钟达到1亿的并发量。当时听到突然猛了一下。真是牛逼克拉斯呀。

不过该说不说还是得开搞,所谓的并发无非就是要想办法减少io的操作,尽量少查表,其余配置方面的问题就看公司舍不舍得花钱了。

其中防重校验这一部分选用了redis集合lua来做,来防止多次提交。

注意:真实下单操作是分为了订单前置操作 (前置校验和生成防重令牌)和提交订单两个接口来写的,这里为了测试简单合并了

@RestController
@RequestMapping("/lua")
public class TestLuaController {
    @Autowired
    private StringRedisTemplate redisTemplate;
    private static final String ORDER_CHECK_TOKEN = "order_check_token";
    private static final String ORDER_TOKEN_DEFAULT_VALUE = "value";
    /**
     * 场景:最近公司有高并发场景,涉及到用令牌防重(防止有人多次提交订单)
     *     可以使用redis执行lua脚本 比较key值令牌是否存在,如果存在即删除
     */
    @RequestMapping("/checkTempToken")
    public Long luaExecute(String checkToken){
        //模拟提交订单生成的防重令牌
        redisTemplate.opsForValue().set(ORDER_CHECK_TOKEN + checkToken,ORDER_TOKEN_DEFAULT_VALUE,60, TimeUnit.SECONDS);
        String script = "if redis.call(\"get\",KEYS[1]) == ARGV[1]\n" +
                "then\n" +
                "    return redis.call(\"del\",KEYS[1])\n" +
                "else\n" +
                "    return 0\n" +
                "end";
//执行redis脚本操作的函数
        Long execute = redisTemplate.execute(new DefaultRedisScript<>(script, Long.class), Arrays.asList(ORDER_CHECK_TOKEN + checkToken), ORDER_TOKEN_DEFAULT_VALUE);
        System.out.println(execute);
        return execute;
    }
}

结果:

redis+lua语言去重

1)redis

redis是一种键值对的单线程架构模型,所以它是线程安全的,也是分布式缓存常用的解决方案。

2)lua

lua是基于c语言的一种脚本语言,它可以很轻便地被使用在嵌入式方面。我们不会去重写redis,但是我们可以去使用lua来扩展redis的功能。而redis也内置了对lua支持的模块。

3)redis+lua是我司基于分布式告警去重的一种解决方案,要达到的目的:堵住10是s内的重复告警,主要应用的场景是同一个告警,在不通的客户端同时推送了一条告警数据,此时要堵住

一条数据。

直接上代码吧

@Component
public class RedisLua {
    @Autowired
    private RedisTemplate<String,Object> redisTemplate;
    private DefaultRedisScript<Boolean> script;
    private static final String KEY_PREX = "alertInfo_";
    @PostConstruct
    private void init(){
        script = new DefaultRedisScript<Boolean>();
        script.setResultType(Boolean.class);
        script.setScriptSource(new ResourceScriptSource(new
                ClassPathResource("lua/alert.lua")));//lua脚本文件
    }public Boolean blockRepetition(String ruleId,String status,String ip,Object...args){
        List<String> keys = new ArrayList<>();
        keys.add(KEY_PREX + ip+ruleId+status);//key包括前缀+客户端ip+告警规则id+状态
        return redisTemplate.execute(script, keys, args);
    }
}

下面是lua脚本

--[[ ARGV1表示redis生效时间,key表示存储redis的key值]]
local alert = redis.call('exists',KEYS[1]);
if alert
 then
    return false
 else
    redis.call('set',KEYS[1],ngx.time())
    redis.call('expire',KEYS[1],ARGV[1])
    return true
end

该方案主要用于微服务集群中,采用分布式锁防和redis集群确保数据唯一。

使用脚本的好处如下:

1.减少网络开销:本来5次网络请求的操作,可以用一个请求完成,原先5次请求的逻辑放在redis服务器上完成。使用脚本,减少了网络往返时延。

2.原子操作:Redis会将整个脚本作为一个整体执行,中间不会被其他命令插入。

3.复用:客户端发送的脚本会永久存储在Redis中,意味着其他客户端可以复用这一脚本而不需要使用代码完成同样的逻辑。

到此这篇关于高并发场景分析之redis+lua防重校验的文章就介绍到这了,更多相关redis+lua防重内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Redis6 主从复制及哨兵机制的实现

    Redis6 主从复制及哨兵机制的实现

    本文主要介绍了Redis6 主从复制及哨兵机制的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-07-07
  • 详解三分钟快速搭建分布式高可用的Redis集群

    详解三分钟快速搭建分布式高可用的Redis集群

    这篇文章主要介绍了详解三分钟快速搭建分布式高可用的Redis集群,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-02-02
  • Redis实现延迟任务的常见方案详解

    Redis实现延迟任务的常见方案详解

    延迟任务(Delayed Task)是指在未来的某个时间点,执行相应的任务,本文为大家整理了Redis实现延迟任务的几个常见方案,希望对大家有所帮助
    2024-04-04
  • Redis操作相关命令之查看、停止、启动命令

    Redis操作相关命令之查看、停止、启动命令

    这篇文章主要介绍了Redis操作相关命令之查看、停止、启动命令,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-09-09
  • 利用redis实现排行榜的小秘诀

    利用redis实现排行榜的小秘诀

    这篇文章主要给大家介绍了关于如何利用redis实现排行榜的小秘诀,文中通过示例代码介绍的非常详细,对大家学习或者使用redis具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-03-03
  • Redis锁的过期时间小于业务的执行时间如何续期

    Redis锁的过期时间小于业务的执行时间如何续期

    本文主要介绍了Redis锁的过期时间小于业务的执行时间如何续期,Redisson它能给Redis分布式锁实现过期时间自动续期,具有一定的参考价值,感兴趣的可以了解一下
    2024-05-05
  • redislive监控redis服务的图文教程_动力节点Java 学院整理

    redislive监控redis服务的图文教程_动力节点Java 学院整理

    这篇文章主要介绍了redislive监控redis服务的图文教程_动力节点Java 学院整理,需要的朋友可以参考下
    2017-08-08
  • windows下通过批处理脚本启动redis的操作

    windows下通过批处理脚本启动redis的操作

    本文主要给大家介绍了windows下通过批处理脚本启动redis的操作,windows下redis启动,需要进入redis安装目录,然后shift+右键,选择“在此处打开命令窗口”,然后输入redis-server.exe redis.conf,就可以启动redis了,文中有详细的图文参考,感兴趣的朋友可以参考下
    2023-12-12
  • Redis 有序集合的使用场景

    Redis 有序集合的使用场景

    在Redis的学习中,有序集合是一种非常实用的数据结构,本文就来介绍一下Redis 有序集合的使用场景,具有一定的参考价值,感兴趣的可以了解一下
    2024-03-03
  • Redis和Lua使用过程中遇到的小问题

    Redis和Lua使用过程中遇到的小问题

    这篇文章主要给大家介绍了关于Redis和Lua使用过程中遇到的小问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-11-11

最新评论