redis sentinel模式 及idea 开发方式+redisson

此内容要在 前一篇 主从模式基础之上阅读

在主从模式的基础上增加 sentinel 

 

 

主从模式的运行配置

 

 

conf配置文件

sentinel monitor mymaster 192.168.1.138 6385 2
192.168.1.138 6385  master
2 重新选举时达到数量

s1/sentinetl.conf

port 27001
sentinel announce-ip 192.168.1.138
sentinel monitor mymaster 192.168.1.138 6385 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000
dir "/opt/module/redis-stack/s1"

s2/sentinetl.conf

port 27002
sentinel announce-ip 192.168.1.138
sentinel monitor mymaster 192.168.1.138 6385 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000
dir "/opt/module/redis-stack/s2"

 

s3/sentinetl.conf

port 27003
sentinel announce-ip 192.168.1.138
sentinel monitor mymaster 192.168.1.138 6385 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000
dir "/opt/module/redis-stack/s3"

 

执行命令启动sentinel

bin/redis-sentinel s1/sentinel.conf

 

Idea 中bean

下面连接的redis 是 sentinel的地址 

@Component
public class BeanRedisson {

    //sentinel 模式
    @Bean
    public  Redisson redisson()
    {

        List<String> sentinellist=new ArrayList<>();
        sentinellist.add("redis://192.168.1.138:27001");
        sentinellist.add("redis://192.168.1.138:27002");
        sentinellist.add("redis://192.168.1.138:27003");
        Config config=new Config();
        config.useSentinelServers().setMasterName("mymaster").setDatabase(0).setSentinelAddresses(sentinellist);
        return (Redisson) Redisson.create(config);
    }
}

 

 yml

LETTUCE 的配置

  redis:
    sentinel:
      master: mymaster
      nodes:
        - 192.168.1.138:27001
        - 192.168.1.138:27002
        - 192.168.1.138:27003

 lettuce 读写分离

这个配置类会被执行 owerride原的操作

package com.hmdp.config;

import io.lettuce.core.ReadFrom;
import org.springframework.boot.autoconfigure.data.redis.LettuceClientConfigurationBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration;

@Configuration
public class LettuceConfig {
    /**
     * 定义这个bean 目的是让lettuce 优先在repliate节点读取数据
     * @return
     */
    @Bean
    public LettuceClientConfigurationBuilderCustomizer lettuceClientConfigurationBuilderCustomizer(){

        return  new LettuceClientConfigurationBuilderCustomizer() {
            @Override
            public void customize(LettuceClientConfiguration.LettuceClientConfigurationBuilder clientConfigurationBuilder) {
                clientConfigurationBuilder.readFrom(ReadFrom.MASTER);

                System.out.println("lettuce read config is actived.");
            }
        };

    }
}

 

java

@RestController
@RequestMapping("/stock")
public class RedisLockTest {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private Redisson redisson;

    @RequestMapping("init")
    public Result addStock(@RequestParam("count") String count) {

        String tipmsg = "";
        String stockkey = "stock:101";

        synchronized (this) { //synchronized 单线程锁 不能解决分布式并发问题
            if (StrUtil.isBlank(count))
                count = "1000";
            stringRedisTemplate.opsForValue().set(stockkey, count);
            String redisStock = stringRedisTemplate.opsForValue().get(stockkey);
            return Result.ok("库存初始化成功:" + redisStock);
        }
    }


    @RequestMapping("/substock")
    public Result substock() {
        String tipmsg = "";
        String stockkey = "stock:101";
        String stockLockkey = "stockLock:101";
        String clientThreadID = UUID.randomUUID().toString().replace("-", "");//用于标识当前进程,redis 锁删除时判断是当前进程的锁


        //synchronized (this){  //synchronized 单线程锁 不能解决分布式并发问题
        // ctrl+alt +L 格式化代码
        //利用 redisson 工具 创建一个锁对象
        RLock redissonLock = redisson.getLock(stockLockkey);
        redissonLock.lock();//默认30s 每隔10秒检测一下主线程没有完成则续命锁 tryLockInnerAsync  lua scripts
        try {

            //redis 分布式锁实现
            //设置有效期
          /*  boolean isredisLock = stringRedisTemplate.opsForValue().setIfAbsent(stockLockkey,"stockLockValue", 10, TimeUnit.SECONDS);//redis setnx(key,value)

            if (!isredisLock) {
                return Result.fail(stockLockkey + "获取失败。");

            }*/


            String stock = stringRedisTemplate.opsForValue().get(stockkey);
            System.out.println(stockkey + "执行了。");
            if (stock == "null" || StrUtil.isBlank(stock))//isEmpty() 只是对字符串长度为 0 进行判断,没有对null 进行判断,所以isEmpty()可能 有空指针的情况
            {
                tipmsg = "当前库存记录不存在。key:" + stockkey;
                //return Result.fail(tipmsg);
            } else {

                int stockInt = Integer.parseInt(stock);//redis.get(stockkey)
                if (stockInt > 0) {
                    int realStock = stockInt - 1;
                    //redis 字符 串操作 所以key value都必须是string
                    stringRedisTemplate.opsForValue().set(stockkey, StrUtil.toString(realStock));//jedis.set(key,value)
                    tipmsg = "库存扣减成功,剩余库存:" + realStock;
                    //return Result.ok(tipmsg);
                } else {

                    tipmsg = "库存不足:" + stockkey;
                    //return Result.fail(tipmsg);
                }
            }

            return Result.ok(tipmsg);

        } finally {
            //try catch 解决异常导致的死锁问题
         /*   if(clientThreadID.equals(stringRedisTemplate.opsForValue().get(stockLockkey))) {//判断是否为自已的锁
                //删除redis 分步式锁
                //TODO 但是此时如果锁的有效期 失效了。。此时再另有一个进程重新进行了加锁,那么此时删除的锁已经是别的锁了,因不自已的锁已经到期自动释放了
                //TODO 这个问题可以通过 锁续命来解决 就是在主线程之外增加一个分线程,只要主线程不结束 就自动完成锁有效期的延长 redisson已经封装好了
                stringRedisTemplate.delete(stockLockkey);
            }*/
            redissonLock.unlock();//解锁
        }


    }
}

 

 

redisson idea 中启动信息

2023-03-01 16:10:16.577  INFO 67124 --- [           main] org.redisson.Version                     : Redisson 3.19.3
2023-03-01 16:10:17.176  INFO 67124 --- [           main] o.r.c.SentinelConnectionManager          : master: redis://192.168.1.138:6385 added
2023-03-01 16:10:17.180  INFO 67124 --- [           main] o.r.c.SentinelConnectionManager          : slave: redis://192.168.1.138:6386 added
2023-03-01 16:10:17.180  INFO 67124 --- [           main] o.r.c.SentinelConnectionManager          : slave: redis://192.168.1.138:6387 added
2023-03-01 16:10:17.191  INFO 67124 --- [isson-netty-4-8] o.r.c.SentinelConnectionManager          : sentinel: redis://192.168.1.138:27003 added
2023-03-01 16:10:17.192  INFO 67124 --- [isson-netty-4-9] o.r.c.SentinelConnectionManager          : sentinel: redis://192.168.1.138:27002 added
2023-03-01 16:10:17.192  INFO 67124 --- [sson-netty-4-10] o.r.c.SentinelConnectionManager          : sentinel: redis://192.168.1.138:27001 added
2023-03-01 16:10:17.216  INFO 67124 --- [sson-netty-4-19] o.r.c.pool.MasterPubSubConnectionPool    : 1 connections initialized for 192.168.1.138/192.168.1.138:6385
2023-03-01 16:10:17.253  INFO 67124 --- [isson-netty-4-2] o.r.c.pool.MasterConnectionPool          : 24 connections initialized for 192.168.1.138/192.168.1.138:6385
2023-03-01 16:10:17.258  INFO 67124 --- [sson-netty-4-31] o.r.c.pool.PubSubConnectionPool          : 1 connections initialized for 192.168.1.138/192.168.1.138:6387
2023-03-01 16:10:17.258  INFO 67124 --- [sson-netty-4-32] o.r.c.pool.PubSubConnectionPool          : 1 connections initialized for 192.168.1.138/192.168.1.138:6386
2023-03-01 16:10:17.294  INFO 67124 --- [isson-netty-4-5] o.r.connection.pool.SlaveConnectionPool  : 24 connections initialized for 192.168.1.138/192.168.1.138:6386
2023-03-01 16:10:17.295  INFO 67124 --- [sson-netty-4-29] o.r.connection.pool.SlaveConnectionPool  : 24 connections initialized for 192.168.1.138/192.168.1.138:6387
2023-03-01 16:10:18.079  INFO 67124 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8081 (http) with context path ''
2023-03-01 16:10:18.155  INFO 67124 --- [           main] com.hmdp.HmDianPingApplication           : Started HmDianPingApplication in 6.287 seconds (JVM running for 7.421)

 

测试

 

posted on 2023-03-01 16:23  hztech  阅读(211)  评论(0编辑  收藏  举报

导航