实现思路
这次我们采用了 Redisson 的 RAtomicLong 来生成一个以固定字符加上年月为键的自增数。随后,将自增数转换为36进制字符串,以年月和36进制字符串拼接形成全局唯一的工单号。
代码实现
SerialIdService.java
@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,我们成功实现了一个简单而强大的全局唯一工单号生成器。该生成器保证了唯一性,且在分布式环境中表现出色。在实际应用中,可以根据业务需求进行调整和扩展,以满足更复杂的场景。