基于Redisson的RAtomicLong实现全局唯一工单号生成器

最近几年,我一直从事的是运营平台业务开发。每天,我们都需要处理大量的工单配置工作。为了生成工单号,我们建立了一张专用的数据库表,用于记录和生成工单号。每次创建工单时,我们会查询这张表,根据年份字段、月份字段和模块编码找到最大的自增序列号。随后,我们将自增序列号加一,与模块编码、年月序列号拼接以生成工单号,并将相关信息写入表中。这种方法一直使用得很顺利,因为工单配置的量并不是特别大,一直都没有出现问题。然而,最近我们为第三方提供了一个工单推送的接口,他们一次性推送了大量的工单,这导致不仅生成了许多重复工单号,而且还引起了接口性能方面的问题。因此,我们决定对工单号生成方式进行改进,本文我们将介绍下我们新的生成方法。

redisson.jpg

实现思路

这次我们采用了 Redisson 的 RAtomicLong 来生成一个以固定字符加上年月为键的自增数。随后,将自增数转换为36进制字符串,以年月和36进制字符串拼接形成全局唯一的工单号。

代码实现

SerialIdService.java

ini 复制代码
@Service
@Slf4j
public class SerialIdService {

    private static final String ID_KEY = "xiuji:";
    private static final int BASE_36 = 36;

    private static final Integer SEQUENCE_LENGTH = 5;
    @Resource
    private RedissonClient redissonClient;

    public String workSerialId() {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyMM");
        String dateStr = LocalDate.now().format(formatter);
        //使用了Redisson的AtomicLong对象生成唯一序列号
        RAtomicLong atomicLong = redissonClient.getAtomicLong(ID_KEY+dateStr);
        //设置过期时间为35天
        if(atomicLong.get() == 0){
            atomicLong.expire(Duration.ofDays(35));
        }
        //将唯一序列号转换为36进制的字符串,长度为4位,用于减少ID的长度
        String sequenceStr = Long.toString(atomicLong.incrementAndGet(), BASE_36).toUpperCase();
        //36进制的序列号若小于4位,则用0补齐高位
        if (sequenceStr.length() < SEQUENCE_LENGTH) {
            sequenceStr = String.format("%4s", sequenceStr).replace(' ', '0');;
        }
        String serialId = dateStr+sequenceStr;

        log.info("生成的工单号:{}",dateStr+sequenceStr);
        return dateStr+sequenceStr;
    }

}

生成的工单号示例:

复制代码
240121AXT6
240121AXT7
240121AXT8
240121AXT9
240121AXTA
240121AXTB
240121AXTC
240121AXTD
240121AXTE
240121AXTF
240121AXTG
240121AXTH
240121AXTI
240121AXTJ

总结

通过Redisson的RAtomicLong,我们成功实现了一个简单而强大的全局唯一工单号生成器。该生成器保证了唯一性,且在分布式环境中表现出色。在实际应用中,可以根据业务需求进行调整和扩展,以满足更复杂的场景。

相关推荐
他们叫我秃子28 分钟前
前端开发转 Go 全栈(五):终于遇到熟人了,Go 的闭包和高阶函数原来这么像 JavaScript
前端·后端·go
SomeB1oody30 分钟前
【RustyML入门】2.6. 线性判别分析
开发语言·后端·机器学习·rust·教程
妙码生花31 分钟前
从 PHP 到 AI + Golang,程序员自救转型手记(五十七):AI时代对组件封装的新理解、agInput 统一入口,动态表单预备
前端·后端·go
Yao80632 分钟前
SpringAI + Ollama + DeepSeek + RAG 搭建 AI 航线规划系统
后端
大勇前进33 分钟前
SQL Server 分页查询多种写法对比:哪种性能最高?
后端
妙码生花36 分钟前
从 PHP 到 AI + Golang,程序员自救转型手记(五十六):附件管理、增加根据文件后缀生成 SVG 文件图标的接口
前端·后端·go
前端Hardy41 分钟前
Vue 终于杀进终端界!这个开源项目让 CLI 开发像写网页一样简单
前端·javascript·后端
老孙讲技术1 小时前
周界枪响了、电梯脸却进了物业群:一个 callback,怎么把 alarm 和 faceAnalysis 拆成两条值班线?
后端·物联网
大勇前进1 小时前
千万级大表 SQL Server 查询慢?一套可落地的性能调优实战路径
后端
前端开发张小七1 小时前
Java 学习笔记 · 第三课:多线程与并发编程(线程、同步、死锁、Lock、乐观锁与悲观锁)
java·后端·程序员