Java服务使用Redis实现分布式全局唯一标识
此处以SpringBoot
为例, 示范如何使用Redis
构造全局唯一标识.
1. RedisTemplate 配置
spring.redis.database = 0
spring.redis.host = **
spring.redis.port = 6379
spring.redis.password = **
spring.redis.lettuce.pool.max-wait = 1000ms
以上配置, 参照实际情况进行设置.,
2.Java 服务中 Redis 配置
@Repository
@Slf4j
public class RedisCounterRepository {
<span class="hljs-keyword">private</span> final <span class="hljs-title class_">DateTimeFormatter</span> dateTimeFormatter = <span class="hljs-title class_">DateTimeFormatter</span>.<span class="hljs-title function_">ofPattern</span>(<span class="hljs-string">"yyyyMMdd"</span>);
<span class="hljs-keyword">private</span> <span class="hljs-title class_">RedisTemplate</span><<span class="hljs-title class_">String</span>, <span class="hljs-title class_">Object</span>> redisTemplate;
<span class="hljs-meta">@Autowired</span>
<span class="hljs-keyword">public</span> <span class="hljs-title class_">RedisCounterRepository</span>(<span class="hljs-title class_">RedisTemplate</span><<span class="hljs-title class_">String</span>, <span class="hljs-title class_">Object</span>> redisTemplate) {
<span class="hljs-variable language_">this</span>.<span class="hljs-property">redisTemplate</span> = redisTemplate;
}
<span class="hljs-comment">// 根据获取的自增数据,添加日期标识构造分布式全局唯一标识</span>
<span class="hljs-keyword">private</span> <span class="hljs-title class_">String</span> <span class="hljs-title function_">getNumFromRedis</span>(<span class="hljs-params"><span class="hljs-built_in">String</span> changeNumPrefix</span>) {
<span class="hljs-title class_">String</span> dateStr = <span class="hljs-title class_">LocalDate</span>.<span class="hljs-title function_">now</span>().<span class="hljs-title function_">format</span>(dateTimeFormatter);
<span class="hljs-title class_">Long</span> value = <span class="hljs-title function_">incrementNum</span>(changeNumPrefix + dateStr);
<span class="hljs-keyword">return</span> dateStr + <span class="hljs-title class_">StringUtils</span>.<span class="hljs-title function_">leftPad</span>(<span class="hljs-title class_">String</span>.<span class="hljs-title function_">valueOf</span>(value), <span class="hljs-number">4</span>, <span class="hljs-string">'0'</span>);
}
<span class="hljs-comment">// 从redis中获取自增数据(redis保证自增是原子操作)</span>
<span class="hljs-keyword">private</span> long <span class="hljs-title function_">incrementNum</span>(<span class="hljs-params"><span class="hljs-built_in">String</span> key</span>) {
<span class="hljs-title class_">RedisConnectionFactory</span> factory = redisTemplate.<span class="hljs-title function_">getConnectionFactory</span>();
<span class="hljs-keyword">if</span> (<span class="hljs-literal">null</span> == factory) {
log.<span class="hljs-title function_">error</span>(<span class="hljs-string">"Unable to connect to redis."</span>);
<span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">UserException</span>(<span class="hljs-title class_">AppStatus</span>.<span class="hljs-property">INTERNAL_SERVER_ERROR</span>);
}
<span class="hljs-title class_">RedisAtomicLong</span> redisAtomicLong = <span class="hljs-keyword">new</span> <span class="hljs-title class_">RedisAtomicLong</span>(key, factory);
long increment = redisAtomicLong.<span class="hljs-title function_">incrementAndGet</span>();
<span class="hljs-keyword">if</span> (<span class="hljs-number">1</span> == increment) {
<span class="hljs-comment">// 如果数据是初次设置,需要设置超时时间</span>
redisAtomicLong.<span class="hljs-title function_">expire</span>(<span class="hljs-number">1</span>, <span class="hljs-title class_">TimeUnit</span>.<span class="hljs-property">DAYS</span>);
}
<span class="hljs-keyword">return</span> increment;
}
PS:
如果您觉得我的文章对您有帮助,请关注我的微信公众号,谢谢!