技术分享 其他 查看内容

使用redis生成全局唯一ID

老高 | 发布于 2018-05-23 09:51| 浏览()| 评论() | 收藏() | 点赞() | 打印

生成唯一客户编码

需求:

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();
}


发表评论(对文章涉及的知识点还有疑问,可以在这里留言,老高看到后会及时回复的。)

表情