生成唯一客户编码
需求:1.id生成有一定规则,可识别
2.全局保持唯一,支持分布式
思路:1.年月日+每日自增数
2.每天23:59:59秒把自增数清0
优势:1.通过年月日可以看出用户注册时间
2.通过自增数可以看出每日注册量
使用redis原因:
redis本身单线程,不会出现并发问题
redis自身有过期策略
使用RedisAtomicLong 自增
主要代码如下:
//通过key获取自增并设定过期时间
public Long generateId(String key,Date date) {
RedisAtomicLong counter = new RedisAtomicLong(key, mRedisTemp.getConnectionFactory());
counter.expire(date);
return counter.incrementAndGet();
}
//组装符合自己规则的id并设置过期时间
/**
* @param key redis中的key值
* @param prefix 最后编码的前缀
* @param hasExpire redis是否使用过期时间生成自增id
* @param minLength redis生成的自增id的最小长度,如果小于这个长度前面补0
* @return
*/
private String generateCode(String key,String prefix,boolean hasExpire,Integer minLength){
try {
Date date = null;
Long id = null;
if(hasExpire){
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 23);
calendar.set(Calendar.MINUTE, 59);
calendar.set(Calendar.SECOND, 59);
calendar.set(Calendar.MILLISECOND, 999);
date = calendar.getTime();
}
id = redisService.generateId(key,date);
if(id != null){
return this.format(id,prefix,date,minLength);
}
} catch (Exception e) {
LOGGER.info("error-->redis生成id时出现异常");
LOGGER.error(e.getMessage(),e);
}
return BaseIdGenerator.generateStringKey();
}
//设定格式
private String format(Long id,String prefix,Date date,Integer minLength){
StringBuffer sb = new StringBuffer();
sb.append(prefix);
if(date != null){
DateFormat df = new SimpleDateFormat("yyyyMMdd");
sb.append(df.format(date));
}
String strId = String.valueOf(id);
int length = strId.length();
if(length < minLength){
for(int i = 0 ;i < minLength - length; i++){
sb.append("0");
}
sb.append(strId);
}else{
sb.append(strId);
}
return sb.toString();
}
个人公众号欢迎共同成长交流