网站后台验证码无法显示,徽省建设干部学校网站,wordpress代码块,锦州网站seo为了生成一个符合要求的分布式全局ID#xff0c;我们可以使用 StringRedisTemplate 来实现。这个ID由三部分组成#xff1a;
符号位#xff08;1 bit#xff09;#xff1a;始终为0#xff0c;表示正数。时间戳#xff08;31 bit#xff09;#xff1a;表示从某个起始…为了生成一个符合要求的分布式全局ID我们可以使用 StringRedisTemplate 来实现。这个ID由三部分组成
符号位1 bit始终为0表示正数。时间戳31 bit表示从某个起始时间点例如2023-01-01 00:00:00到现在的秒数。序列号32 bit用于在同一秒内生成不同的ID。
实现步骤
计算时间戳从某个起始时间点到现在的秒数。生成序列号使用Redis的原子递增操作来生成序列号。组合ID将时间戳和序列号组合成一个64位的长整型数字。
代码实现
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.concurrent.TimeUnit;Service
public class DistributedIdGenerator {Autowiredprivate StringRedisTemplate stringRedisTemplate;// 起始时间点例如2023-01-01 00:00:00private static final long EPOCH ZonedDateTime.of(2023, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault()).toInstant().toEpochMilli() / 1000;// 序列号的Redis键前缀private static final String SEQUENCE_KEY_PREFIX sequence:;/*** 生成分布式全局ID** return 分布式全局ID*/public long generateId() {// 获取当前时间戳从起始时间点到现在的秒数long currentTimeSec Instant.now().getEpochSecond() - EPOCH;// 生成序列号String sequenceKey SEQUENCE_KEY_PREFIX currentTimeSec;long sequence stringRedisTemplate.opsForValue().increment(sequenceKey, 1);if (sequence (1L 32)) { // 序列号溢出重置为0stringRedisTemplate.expire(sequenceKey, 1, TimeUnit.SECONDS); // 设置1秒后过期sequence 0;}// 组合IDlong id (currentTimeSec 32) | sequence;return id;}
}
代码解释
EPOCH起始时间点例如2023-01-01 00:00:00转换为秒数。SEQUENCE_KEY_PREFIXRedis中存储序列号的键前缀。generateId 方法 currentTimeSec从起始时间点到现在的秒数。sequenceKey根据当前时间戳生成的Redis键。sequence使用 opsForValue().increment 方法生成序列号确保在同一秒内生成不同的ID。序列号溢出处理如果序列号达到最大值2^32 - 1则重置为0并设置键在1秒后过期。组合ID将时间戳左移32位然后与序列号进行按位或操作生成最终的64位ID。
测试代码
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;RestController
public class IdController {Autowiredprivate DistributedIdGenerator idGenerator;GetMapping(/generate-id)public long generateId() {return idGenerator.generateId();}
}