用于排队叫号系统的redis工具类

  1. 分析

排队叫号系统的队列数据变化很频繁,因此可以考虑使用redis的list结构存储某一队列的数据,与前端采用websocekt连接,后端主动推送数据给前端,避免频繁轮询造成资源浪费。
为了满足排队系统的需求,需要设计以下几个api:

  • 入队
  • 出队
  • 获取队列数据和队长
  • 允许某人中途离队(已知其信息,从队列中剔除)
  • 允许某人插队(在目标anchor前插队还是后插队)
  • 得到某人在队列中的位置

2 redis配置和Vo类代码

yml配置

  redis:
    database: 0
    host: 127.0.0.1
    port: 6379
    timeout: 3000
    jedis:
      pool:
        max-active: 8
        max-wait: -1
        max-idle: 8
        min-idle: 0

redis配置类

@EnableCaching
@Configuration
public class RedisConfig {

    @Value("${spring.redis.host}")
    private String host;
    @Value("${spring.redis.database}")
    private Integer database;
    @Value("${spring.redis.port}")
    private Integer port;
//  @Value("${spring.redis.password}")
//  private String pwd;

    @Primary
    @Bean(name = "jedisPoolConfig")
    @ConfigurationProperties(prefix = "spring.redis.pool")
    public JedisPoolConfig jedisPoolConfig() {
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxWaitMillis(100000);
        return jedisPoolConfig;
    }

    @Bean
    public RedisConnectionFactory redisConnectionFactory(JedisPoolConfig jedisPoolConfig) {
        RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
        redisStandaloneConfiguration.setHostName(host);
        redisStandaloneConfiguration.setDatabase(database);
        // redisStandaloneConfiguration.setPassword(pwd);
        redisStandaloneConfiguration.setPort(port);
        JedisClientConfiguration.JedisPoolingClientConfigurationBuilder jpcb = (JedisClientConfiguration.JedisPoolingClientConfigurationBuilder) JedisClientConfiguration.builder();
        jpcb.poolConfig(jedisPoolConfig);
        JedisClientConfiguration jedisClientConfiguration = jpcb.build();
        return new JedisConnectionFactory(redisStandaloneConfiguration, jedisClientConfiguration);
    }

    /**
     * 配置redisTemplate针对不同key和value场景下不同序列化的方式
     *
     * @param factory Redis连接工厂
     * @return
     */
    @Primary
    @Bean(name = "redisTemplate")
    public RedisTemplate redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate template = new RedisTemplate<>();
        template.setConnectionFactory(factory);
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        template.setKeySerializer(stringRedisSerializer);
        template.setHashKeySerializer(stringRedisSerializer);
        Jackson2JsonRedisSerializer redisSerializer = new Jackson2JsonRedisSerializer(PatientVo.class);
        template.setValueSerializer(redisSerializer);
        template.setHashValueSerializer(redisSerializer);
        template.afterPropertiesSet();
        return template;
    }

    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnSingleCandidate(RedisConnectionFactory.class)
    public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
        StringRedisTemplate template = new StringRedisTemplate();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }
}

vo类代码:

@Data
@NoArgsConstructor
@AllArgsConstructor
public class PatientVo {
    private Long patientId;
    private Integer queueNum;
    private String patientName;
    private String patientGender;
}
  1. redis排队工具类

这里写的不好的地方在于没有判断捕获异常。

@Component
public class QueueUtil {

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 入队
     * @param roomCode 诊室编码
     * @param vo 病人vo对象
     */
    public  void addPatient2Queue(String roomCode, PatientVo vo) {
        redisTemplate.opsForList().rightPush(roomCode, vo);
    }

    /**
     * 队长
     * @param roomCode 诊室编码
     * @return Long长度
     */
    public  Long getQueueLength(String roomCode) {
        return redisTemplate.opsForList().size(roomCode);
    }

    // 获取队列数据
    public List getQueueData(String roomCode) {
        return redisTemplate.opsForList().range(roomCode, 0, -1);
    }

    // 某人中途离开队伍
    public  void leaveQueue(String roomCode, PatientVo patientVo) {
        redisTemplate.opsForList().remove(roomCode, 0, patientVo);
    }

    // 队首离队
    public  PatientVo headLeaveQueue(String roomCode) {
        PatientVo leftPop = redisTemplate.opsForList().leftPop(roomCode);
        return leftPop;
    }

    // 得到某人队列中的位置
    public  List getOnesPosition(String roomCode, PatientVo patientVo) {
        List queueData = getQueueData(roomCode);
        int myPositionBeforeNum = queueData.indexOf(patientVo);
        int myPosition = myPositionBeforeNum + 1;
        int size = queueData.size();
        // 当前排队res[0]人,您排在第res[1]位,前面还有res[2]位。
        List result = new ArrayList<>();
        result.add(size);
        result.add(myPosition);
        result.add(myPositionBeforeNum);
        return result;
    }

    // 插队操作
    public  void jumpAQueue(String roomCode, PatientVo jumpChecker, PatientVo targetChecker, Integer jumpType) {
        // 在target前面插队
        if (jumpType.equals(1)) {
            redisTemplate.opsForList().leftPush(roomCode, targetChecker, jumpChecker);
        }
        if (jumpType.equals(2)) {
            redisTemplate.opsForList().rightPush(roomCode, targetChecker, jumpChecker);
        }
    }
}
  1. 简单测试

测试代码

@Autowired
    private QueueUtil queueUtil;

    @GetMapping("/test/qu")
    private Result testQueueUtil() {
        long start = System.currentTimeMillis();
        List list = patientInfoService.list();
        for (int i = 0; i < 10; i++) {
            PatientInfo info = list.get(i);
            PatientVo vo = new PatientVo(info.getPatientId(),
                    info.getQueueNum(),
                    info.getPatientName(),
                    info.getPatientSex());
            queueUtil.addPatient2Queue("test", vo);
        }
        List queueData = queueUtil.getQueueData("test");
//      PatientVo jumpVo = new PatientVo(1999L, 2999, "test", "test");
//      PatientVo targetVo = new PatientVo(1058L, 2005, "冯秀娟", "女");
//      queueUtil.jumpAQueue("test", jumpVo, targetVo, 2);
//      List queueData = queueUtil.getQueueData("test");
        long end = System.currentTimeMillis();
        log.info("waste time: {}s", (float)(end - start) / 1000);
        return Result.success(queueData);
    }

测试结果图1:

用于排队叫号系统的redis工具类
测试结果图2:
用于排队叫号系统的redis工具类
然后测试一下插队功能,在冯秀娟后面插入test
查看RedisManager里的结果:
用于排队叫号系统的redis工具类
test成功插队。

Original: https://www.cnblogs.com/ceeSomething8/p/15935420.html
Author: cee_nil
Title: 用于排队叫号系统的redis工具类

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/622727/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • HTTP Cookie/Session

    posted @2022-06-14 23:46 放飞梦想C 阅读(12 ) 评论() 编辑 Original: https://www.cnblogs.com/chengmf/p…

    数据结构和算法 2023年6月8日
    071
  • 算法竞赛进阶指南 0x58 数据结构优化DP

    农民约翰正在指挥他的 N 头牛进行清理工作。他将一天划分为了 T 个班次(1∼ T)。 每头牛都只能在一天中的某一个时间段内进行不间断的工作。 你需要帮助约翰排列出一个合理的奶牛的…

    数据结构和算法 2023年6月12日
    078
  • 任意多边形的面积计算

    任意给出一个三角形ΔABC,设其顶点坐标分别为A(x1, y1),B(x2, y2),C(x3, y3),那么根据线性代数的知识,ΔABC的有向面积可表示为: 其中,ΔABC顶点A…

    数据结构和算法 2023年6月7日
    088
  • uva 1440 & uvalive 4597

    题意: DAG的最小路径覆盖,一条边可以被重复覆盖多次,但是一次只能沿着DAG的方向覆盖一条链,问最少覆盖次数。 思路: 看了半天没有思路,所以去搜索了题解,然后发现是有源汇上下界…

    数据结构和算法 2023年6月12日
    070
  • Redis:HGETALL的排序问题

    HGETALL 介绍 Returns all fields and values of the hash stored at key. In the returned value,…

    数据结构和算法 2023年6月7日
    083
  • 07 sql函数

    函数:切记函数和括号要紧密相连内置函数1.算术函数abs mod roundmax min avg sum count 这几个为聚集函数,特别在分组中常用 select abs(-…

    数据结构和算法 2023年6月8日
    079
  • 《程序员漫画》码农给孩子取名

    「左耳朵梵高」 第16篇原创 程序员给孩子取名,老大叫玲玲,老二叫玲伊,老三叫。。。 我是左耳朵梵高,北理工毕业,现任某金融咨询公司首席架构师,曾在阿里巴巴中间件团队任职。沉浸软件…

    数据结构和算法 2023年6月7日
    057
  • Fhq_Treap 和 Splay:谁才是序列之王?

    平衡树 很久以前,我立志要学习所有的平衡树,然后把每个树的学习笔记都整理到相关博客中。 而如今…… 今年欢笑复明年,不知退役在眼前。 在阅读本文之前建议先学…

    数据结构和算法 2023年6月12日
    091
  • 容斥原理

    链接:https://ac.nowcoder.com/acm/contest/548/F来源:牛客网 立华奏是一个天天打比赛的萌新。 省选将至,萌新立华奏深知自己没有希望进入省队,…

    数据结构和算法 2023年6月7日
    078
  • 随笔4

    一份满意的答卷 终究是意难平。 高三莘莘学子寒窗苦读9年,为的就是高考这重要一刻。发挥超常光宗耀祖,各大名校挤破门槛争着抢夺你;落榜了垂头丧气,回家还要忍受各种七大姑八大姨的亲切问…

    数据结构和算法 2023年6月7日
    083
  • Java中如何创建不可变(immutable)类

    不可变类是指类的实例一经创建完成,这个实例的内容就不会改变。 Java中的String和八个基本类型的包装类(Integer, Short, Byte, Long, Double,…

    数据结构和算法 2023年6月12日
    088
  • 群论学习小记

    对 (S_n) 的一个子群 (G),设 (Z_k) 表示作用在 (1\sim n) 上使 (k) 保持不动的置换类,(E_k) 表示 (k) 在群 (G) 作用下的 “…

    数据结构和算法 2023年6月12日
    070
  • [总结]2022/1/21

    P1心路历程 开题看到T1,又双叒叕回想起来CSP(话说最近这几天总是想起CSP不好的回忆),感觉实在是太像CSP的T4了。于是想用重载运算符和map。但问题是我忘了重载运算符!!…

    数据结构和算法 2023年6月8日
    077
  • Rust单链表

    节点的结构 希望链表存储在堆上,所以使用 Box 包裹节点 Rust 没有空值,所以用 Option 在包裹一层 #[derive(PartialEq, Eq, Clone, De…

    数据结构和算法 2023年6月7日
    0100
  • 简单的打麻将!!!!

    https://nanti.jisuanke.com/t/39612 题面: 在麻将游戏中,有 3434 种牌,分别是 1-91−9 的万,1-91−9 的筒,1-91−9 的条,…

    数据结构和算法 2023年6月7日
    069
  • 单向链表的介绍和实现思路

    链表在内存中的存储 链表是以节点的方式来存储, 是链式存储 每个节点包含 data 域 和 next 域。next域用来指向下一个节点 链表的各个节点不一定是连续存储的 链表分 带…

    数据结构和算法 2023年6月12日
    0106
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球