redis 实现分布式全局唯一id

采用INCR命令来实现分布式全局ID生成。

1、lettuce客户端实现

        <!--redis,有两种实现:lettuce 和 jedis 。默认是使用lettuce。-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
# Redis配置
spring.redis.host=192.168.1.160
#Redis服务器连接端口
spring.redis.port=6379
#Redis服务器连接密码(默认为空)
spring.redis.password=123456
#连接池最大连接数(使用负值表示没有限制)
spring.redis.max-active=8
#连接池最大阻塞等待时间(毫秒)(使用负值表示没有限制)
spring.redis.max-wait=30000
#连接池中的最大空闲连接
spring.redis.max-idle=8
#连接池中的最小空闲连接
spring.redis.min-idle=0
#连接超时时间(毫秒)
spring.redis.timeout=30000
@Configuration
public class RedisConfig {
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        // 配置连接工厂
        template.setConnectionFactory(factory);
        //使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值(默认使用JDK的序列化方式)
        Jackson2JsonRedisSerializer jacksonSeial = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        // 指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和public
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        // 指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如String,Integer等会跑出异常
        om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
        jacksonSeial.setObjectMapper(om);
        // key序列化
        template.setKeySerializer(new StringRedisSerializer());
        // value序列化
        template.setValueSerializer(jacksonSeial);
        // Hash key序列化
        template.setHashKeySerializer(new StringRedisSerializer());
        // Hash value序列化
        template.setHashValueSerializer(jacksonSeial);
        template.afterPropertiesSet();
        return template;
    }
}
@Service
public class RedisService {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    private static final String ID_KEY = "id:generator:order";
    private static final long BASE_ID = 1000000000;

    /**
     * 生成唯一ID
     * @date 2022/7/18 16:03
     */
    public long getUniqueId() {
        long inc = stringRedisTemplate.opsForValue().increment(ID_KEY);
        System.out.println(BASE_ID + inc);
        return BASE_ID + inc;
    }
}

2、jedis客户端实现

        <!-- Jedis客户端依赖 -->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
        </dependency>
jedis.pool.host=192.168.1.201
jedis.pool.port=6379
jedis.pool.password=123456
jedis.pool.timeout=7200
jedis.pool.config.maxTotal=1000
jedis.pool.config.maxIdle=100
jedis.pool.config.minIdle=50
jedis.pool.config.maxWaitMillis=1000
jedis.pool.config.testOnBorrow=true
@Configuration
public class RedisConfig   {
    @Bean
    public JedisPoolConfig jedisPoolConfig(@Value("${jedis.pool.config.maxTotal}") int maxActive,
                                           @Value("${jedis.pool.config.maxIdle}") int maxIdle,
                                           @Value("${jedis.pool.config.minIdle}") int minIdle,
                                           @Value("${jedis.pool.config.maxWaitMillis}") long maxWaitMillis,
                                           @Value("${jedis.pool.config.testOnBorrow}") boolean testOnBorrow) {
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxTotal(maxActive);
        jedisPoolConfig.setMaxIdle(maxIdle);
        jedisPoolConfig.setMinIdle(minIdle);
        jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);
        jedisPoolConfig.setTestOnBorrow(testOnBorrow);
        return jedisPoolConfig;
    }

    @Bean
    public JedisPool jedisPool(@Value("${jedis.pool.host}") String host,
                               @Value("${jedis.pool.port}") int port,
                               @Value("${jedis.pool.password}") String password,
                               @Value("${jedis.pool.timeout}") int timeout, JedisPoolConfig jedisPoolConfig) {
        if (password == null || password.length() == 0) {
            return new JedisPool(jedisPoolConfig, host, port, timeout);
        }
        return new JedisPool(jedisPoolConfig, host, port, timeout, password);
    }

}
@Service
public class RedisService {
    @Autowired
    private JedisPool jedisPool;

    private static final String ID_KEY = "id:generator:order";
    private static final long BASE_ID = 1000000000;

    /**
     * 生成唯一ID
     * @date 2022/7/18 16:03
     */
    public long getUniqueId() {
        Jedis jedis = jedisPool.getResource();
        long inc = jedis.incr(ID_KEY);
        System.out.println(BASE_ID + inc);
        return BASE_ID + inc;
    }
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Redis分布式锁是一种基于Redis分布式实现方式,通过Redis实现分布式系统中共享资源的互斥访问。具体注解如下: 1. 分布式锁的实现方式:使用Redis的setnx命令实现分布式锁,即在Redis中创建一个键值对,当键不存在时才能创建成功,表示获取锁成功,否则获取锁失败。在释放锁时,删除对应的键值对即可。 2. 锁的唯一性:分布式锁需要保证锁的唯一性,可以通过在锁的键名中添加全局唯一的标识符,如应用程序的名称、服务器的IP地址等。 3. 锁的过期时间:为了防止死锁,需要给锁设置过期时间,可通过Redis的expire命令设置键的过期时间。 4. 锁的重入性:分布式锁需要支持重入,即同一个线程可以多次获取同一个锁,需要在锁的值中添加线程ID等标识符,以便在释放锁时判断是否是同一个线程。 5. 锁的释放方式:分布式锁需要支持手动和自动释放,手动释放即调用del命令删除锁的键值对,自动释放即设置锁的过期时间,在过期后Redis会自动删除键值对。 6. 锁的容错性:分布式锁需要保证容错性,即在获取锁失败时不会导致系统异常或数据丢失,可以通过重试机制或设置超时时间来实现。 7. 锁的并发性:分布式锁需要保证并发性,即在高并发情况下多个线程可以同时获取锁,需要使用Redis的lua脚本实现原子性操作,避免并发问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值