当前位置: 首页 > article >正文

Redis7——基础篇(八)

 前言:此篇文章系本人学习过程中记录下来的笔记,里面难免会有不少欠缺的地方,诚心期待大家多多给予指教。

基础篇:

  1. Redis(一)
  2. Redis(二)
  3. Redis(三)
  4. Redis(四)
  5. Redis(五)
  6. Redis(六)
  7. Redis(七)

接上期内容:上期完成了Redis集群的学习。下面开始学习Java集成Redis,话不多说,直接发车。


一、Java连接Redis的四种方式

(一)、底层客户端库

1、Jedis

1.1、定义

Jedis是Redis官方推荐的Java客户端,它提供了一套简洁易用的 API,用于与Redis 进行交互。Jedis支持同步、异步和管道操作,能够满足不同场景下的需求。


1.2、优劣势

优势:

  • 使用简单,学习成本低,对初学者友好。
  • 同步阻塞 I/O,在单线程环境下使用方便。
  • 与 Redis的命令对应性强,容易上手

劣势:

  • 在高并发场景下,由于同步阻塞 I/O 的特性,性能会受到一定影响
  • 多线程环境下,需要手动管理连接池,增加了开发复杂度

2、Lettuce

2.1、定义

Lettuce是一个基于Netty的可伸缩线程安全的Redis客户端,它支持同步、异步和响应式编程模型。Lettuce的设计目标是提供高性能和可扩展性,适用于各种复杂的应用场景。


2.2、优劣势

优势:

  • 基于Netty实现,支持异步 I/O,在高并发场景下性能表现出色
  • 线程安全,无需手动管理连接池。
  • 支持多种编程模型,灵活性高

劣势:

  • 相比Jedis,学习成本较高
  • API相对复杂,对于简单场景可能显得过于繁琐。


(二)、上层框架封装

1、RedisTemplate

1.1、定义

RedisTemplate是Spring Data Redis 提供的一个高级封装,它简化了Java与Redis的交互操作。RedisTemplate提供了丰富的方法,支持各种数据结构的操作,并且可以方便地进行事务管理和序列化配置。


1.2、优劣势

优势:

  • 与Spring 架无缝集成,使用方便
  • 对各种数据结构的操作进行了封装,代码简洁
  • 支持事务管理和序列化配置,提高了应用的灵活性和可维护性

劣势:

  • 依赖Spring框架,如果项目中没有使用 Spring,引入RedisTemplate会增加项目的复杂度
  • 相比底层客户端库,性能上可能会有一定损耗

2、Redisson

2.1、定义

Redisson是一个在Redis的基础上实现的Java驻内存数据网格(In-Memory Data Grid)。它不仅提供了一系列的分布式的Java常用对象,还提供了许多分布式服务,如分布式锁、分布式集合、分布式对象等,极大地简化了分布式系统的开发。


2.2、优劣势

优势:

  • 提供了丰富的分布式服务,开箱即用,像分布式锁、分布式集合等,非常适合构建分布式系统
  • 对Redis功能进行了高度抽象和扩展,使用起来更加便捷。
  • 支持多种序列化方式,兼容性好

劣势:

  • 相比直接使用 Redis 客户端,增加了一定的学习成本
  • 由于其功能丰富,依赖的包可能较多,在一些对依赖大小敏感的场景下不太适用。

二、实操

(一)、集成Jedis

1、新建项目

新建步骤略。最终效果图:

2、导入依赖

        <!--jedis-->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>5.2.0</version>
        </dependency>

3、编写方法

3.1、连接redis单机
public class JedisDemoTest {
    public static void main(String[] args) {
        Jedis jedis = new Jedis("192.168.112.129", 6379);
        jedis.auth("root");
        jedis.set("k1", "你好jedis");
        System.out.println(jedis.get("k1"));

        //key
        Set<String> keys = jedis.keys("*");
        for (String key : keys) {
            System.out.println(key);
        }
        System.out.println("jedis.exists====>" + jedis.exists("k2"));
        System.out.println(jedis.ttl("k1"));
        //String
        System.out.println(jedis.get("k1"));
        jedis.set("k4", "k4_redis");
        System.out.println("----------------------------------------");
        jedis.mset("str1", "v1", "str2", "v2", "str3", "v3");
        System.out.println(jedis.mget("str1", "str2", "str3"));

        //list
        System.out.println("----------------------------------------");
        jedis.lpush("myList", "v1", "v2", "v3", "v4", "v5");
        List<String> list = jedis.lrange("myList", 0, -1);
        for (String element : list) {
            System.out.println(element);
        }

        //set
        jedis.sadd("orders", "jd001");
        jedis.sadd("orders", "jd002");
        jedis.sadd("orders", "jd003");
        Set<String> set1 = jedis.smembers("orders");
        for (String string : set1) {
            System.out.println(string);
        }
        jedis.srem("orders", "jd002");
        System.out.println(jedis.smembers("orders").size());

        //hash
        jedis.hset("hash1", "userName", "lisi");
        System.out.println(jedis.hget("hash1", "userName"));
        Map<String, String> map = new HashMap<>();
        map.put("telephone", "138xxxxxxxx");
        map.put("address", "fatigue");
        map.put("email", "sxxxx@qq.com");//
        jedis.hmset("hash2", map);
        List<String> result = jedis.hmget("hash2", "telphone", "email");
        for (String element : result) {
            System.out.println(element);
        }

        //zSet
        jedis.zadd("zSet01", 60d, "v1");
        jedis.zadd("zSet01", 70d, "v2");
        jedis.zadd("zSet01", 80d, "v3");
        jedis.zadd("zSet01", 90d, "v4");

        List<String> zSet01 = jedis.zrange("zSet01", 0, -1);
        zSet01.forEach(System.out::println);
        // 关闭连接
        jedis.close();
    }
}

3.2、连接redis集群
public class JedisColonyDemoTest {
    public static void main(String[] args) {
        // 添加主节点
        HashSet<HostAndPort> jedisClusterNodes = new HashSet<>();
        jedisClusterNodes.add(new HostAndPort("192.168.112.129", 6379));
        jedisClusterNodes.add(new HostAndPort("192.168.112.130", 6381));
        jedisClusterNodes.add(new HostAndPort("192.168.112.129", 6380));
        // 连接redis集群
        JedisCluster cluster = new JedisCluster(jedisClusterNodes,"default","root");
        // 清除单机Redis设置的key
        // 如果用Jedis连接Redis集群模式下,
        // flushAll这类全局操作不能直接使用,在集群模式下对于一些全局操作命令(如 KEYS)的处理不够完善,
        // 没有内置的逻辑来处理 KEYS 命令在集群环境下的复杂性。
        for (HostAndPort node : jedisClusterNodes) {
            try (Jedis jedis = new Jedis(node.getHost(), node.getPort())) {
                jedis.auth("root");
                // 对每个节点执行 flushDB 命令
                jedis.flushDB();
                System.out.println("Flushed database on node: " + node);
            }
        }
        cluster.set("k1", "你好redis集群");
        System.out.println(cluster.get("k1"));

        System.out.println("cluster.exists====>" + cluster.exists("k2"));
        System.out.println(cluster.ttl("k1"));
        //String
        System.out.println(cluster.get("k1"));
        cluster.set("k4", "k4_redis");
        System.out.println("----------------------------------------");
        cluster.mset("str1{x}", "v1", "str2{x}", "v2", "str3{x}", "v3");
        System.out.println(cluster.mget("str1{x}", "str2{x}", "str3{x}"));

        //list
        System.out.println("----------------------------------------");
        cluster.lpush("myList", "v1", "v2", "v3", "v4", "v5");
        List<String> list = cluster.lrange("myList", 0, -1);
        for (String element : list) {
            System.out.println(element);
        }

        //set
        cluster.sadd("orders", "jd001");
        cluster.sadd("orders", "jd002");
        cluster.sadd("orders", "jd003");
        Set<String> set1 = cluster.smembers("orders");
        for (String string : set1) {
            System.out.println(string);
        }
        cluster.srem("orders", "jd002");
        System.out.println(cluster.smembers("orders").size());

        //hash
        cluster.hset("hash1", "userName", "lisi");
        System.out.println(cluster.hget("hash1", "userName"));
        Map<String, String> map = new HashMap<>();
        map.put("telephone", "138xxxxxxxx");
        map.put("address", "fatigue");
        map.put("email", "sxxxx@qq.com");//
        cluster.hmset("hash2", map);
        List<String> result = cluster.hmget("hash2", "telphone", "email");
        for (String element : result) {
            System.out.println(element);
        }

        //zSet
        cluster.zadd("zSet01", 60d, "v1");
        cluster.zadd("zSet01", 70d, "v2");
        cluster.zadd("zSet01", 80d, "v3");
        cluster.zadd("zSet01", 90d, "v4");

        List<String> zSet01 = cluster.zrange("zSet01", 0, -1);
        zSet01.forEach(System.out::println);
        cluster.close();
    }
}

4、测试用例 

4.1、单机测试结果

 直接main方法启动,

redis客户端:


4.2、redis集群测试结果

控制台输入:

redis客户端:


(二)、集成Lettuce

1、导入依赖

        <!--lettuce-->
        <dependency>
            <groupId>io.lettuce</groupId>
            <artifactId>lettuce-core</artifactId>
            <version>6.5.4.RELEASE</version>
        </dependency>

 *注意:如果你的Springboot版本为3.4.3,那么导入这个依赖后,可能需要清除IDEA缓存,不然一直无法new RedisURI类。刷新过maven也没用,只有清除缓存重启后才成功,就很奇怪( ╯□╰ )。


2、编写方法

2.1、连接Redis单机
public class LettuceDemoTest {
    public static void main(String[] args) {
        // 构建 RedisURI 对象
        RedisURI uri = RedisURI.builder(RedisURI.create("redis://192.168.112.129"))
                .withPort(6379)
                .withAuthentication("default", "root")
                .withDatabase(0)
                .build();
        // 创建连接客户端
        RedisClient client = RedisClient.create(uri);
        StatefulRedisConnection<String, String> conn = client.connect();
        // 操作命令api
        RedisCommands<String, String> commands = conn.sync();
        // 清空Jedis设置的key
        commands.flushdb();
        //keys
        List<String> list = commands.keys("*");
        for (String s : list) {
            System.out.println(s);
        }
        //String
        commands.set("k1", "hello Lettuce");
        String s1 = commands.get("k1");
        System.out.println("String s ===" + s1);

        //list
        commands.lpush("myList2", "v1", "v2", "v3");
        List<String> list2 = commands.lrange("myList2", 0, -1);
        for (String s : list2) {
            System.out.println("list ssss===" + s);
        }
        //set
        commands.sadd("mySet2", "v1", "v2", "v3");
        Set<String> set = commands.smembers("mySet2");
        for (String s : set) {
            System.out.println("set ssss===" + s);
        }
        //hash
        Map<String, String> map = new HashMap<>();
        map.put("k1", "138xxxxxxxx");
        map.put("k2", "fatigue");
        map.put("k3", "zzyybs@126.com");//课后有问题请给我发邮件

        commands.hmset("myHash2", map);
        Map<String, String> retMap = commands.hgetall("myHash2");
        for (String k : retMap.keySet()) {
            System.out.println("hash  k=" + k + " , v==" + retMap.get(k));
        }

        //zSet
        commands.zadd("myzSet2", 100.0, "s1", 110.0, "s2", 90.0, "s3");
        List<String> list3 = commands.zrange("myzSet2", 0, 10);
        for (String s : list3) {
            System.out.println("zSet ssss===" + s);
        }

        //sort
        SortArgs sortArgs = new SortArgs();
        sortArgs.alpha();
        sortArgs.desc();

        List<String> list4 = commands.sort("myList2", sortArgs);
        for (String s : list4) {
            System.out.println("sort ssss===" + s);
        }

        //关闭
        conn.close();
        client.shutdown();
    }
}

2.2、连接Redis集群
public class LettuceColonyDemoTest {
    public static void main(String[] args) {
        HashSet<RedisURI> uris = new HashSet<>();
        uris.add(RedisURI.builder().withHost("192.168.112.129")
                .withPort(6379).withAuthentication("default", "root").build());
        uris.add(RedisURI.builder().withHost("192.168.112.130")
                .withPort(6381).withAuthentication("default", "root").build());
        uris.add(RedisURI.builder().withHost("192.168.112.129")
                .withPort(6380).withAuthentication("default", "root").build());
        RedisClusterClient client = RedisClusterClient.create(uris);
        StatefulRedisClusterConnection<String, String> con = client.connect();
        RedisAdvancedClusterCommands<String, String> clusterCommands = con.sync();

        // 清除单机Redis设置的key
        // Lettuce连接Redis集群模式下,能使用flushAll命令
        // 因为Lettuce内部实现了智能的路由机制,能够自动将 KEYS 命令分发到集群中的各个节点,并将结果聚合返回
        clusterCommands.flushallAsync();
        //keys
        List<String> list = clusterCommands.keys("*");
        for (String s : list) {
            System.out.println(s);
        }
        //String
        clusterCommands.set("k1", "hello Lettuce");
        String s1 = clusterCommands.get("k1");
        System.out.println("redis集群===" + s1);

        //list
        clusterCommands.lpush("myList2", "v1", "v2", "v3");
        List<String> list2 = clusterCommands.lrange("myList2", 0, -1);
        for (String s : list2) {
            System.out.println("list ssss===" + s);
        }
        //set
        clusterCommands.sadd("mySet2", "v1", "v2", "v3");
        Set<String> set = clusterCommands.smembers("mySet2");
        for (String s : set) {
            System.out.println("set ssss===" + s);
        }
        //hash
        Map<String, String> map = new HashMap<>();
        map.put("k1", "138xxxxxxxx");
        map.put("k2", "fatigue");
        map.put("k3", "zzyybs@126.com");//课后有问题请给我发邮件

        clusterCommands.hmset("myHash2", map);
        Map<String, String> retMap = clusterCommands.hgetall("myHash2");
        for (String k : retMap.keySet()) {
            System.out.println("hash  k=" + k + " , v==" + retMap.get(k));
        }

        //zSet
        clusterCommands.zadd("myzSet2", 100.0, "s1", 110.0, "s2", 90.0, "s3");
        List<String> list3 = clusterCommands.zrange("myzSet2", 0, 10);
        for (String s : list3) {
            System.out.println("zSet ssss===" + s);
        }

        //sort
        SortArgs sortArgs = new SortArgs();
        sortArgs.alpha();
        sortArgs.desc();

        List<String> list4 = clusterCommands.sort("myList2", sortArgs);
        for (String s : list4) {
            System.out.println("sort ssss===" + s);
        }

        //关闭
        con.close();
        client.shutdown();
        client.close();
    }
}

3、测试用例

3.1、单机测试结果

 控制台输出:

redis客户端:


3.2、redis集群测试结果

控制台输出:

redis客户端:


(三)、集成RedisTemplate

1、新建配置文件

新建application.properties文件:

server.port=8080
spring.application.name=RedisDemo
# ========================logging=====================
logging.level.root=info
logging.level.xxx.xx.xxx=info
logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger- %msg%n

logging.file.name=D:/myLogs/RedisDemo.log
logging.pattern.file=%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger- %msg%n

# ========================redis单机=====================
spring.data.redis.database=0
#修改为自己的真实IP
spring.data.redis.host=xxx.xxx.xxx.xxx
spring.data.redis.port=6379
spring.data.redis.password=xxxx
spring.data.redis.lettuce.pool.max-active=8
spring.data.redis.lettuce.pool.max-wait=-1ms
spring.data.redis.lettuce.pool.max-idle=8
spring.data.redis.lettuce.pool.min-idle=0

2、导入依赖

        <!--SpringBoot通用依赖模块-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--SpringBoot与Redis整合依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
        </dependency>
        <!--日志-->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.24.3</version>
        </dependency>
        <!-- swagger3生成接口文档依赖-->
        <dependency>
            <groupId>org.springdoc</groupId>
            <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
            <version>2.3.0</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.30</version>
        </dependency>

3、编写业务类

3.1、新建controller
@RestController
@Tag(name = "订单管理", description = "订单的创建和查询操作")
public class OrderController {
    @Resource
    private OrderService orderService;

    /**
     * redis单机
     */
    @RequestMapping(value = "/order/add", method = RequestMethod.POST)
    public void addOrder() {
        orderService.addOrder();
    }

    @RequestMapping(value = "/order/{id}", method = RequestMethod.GET)
    public String findUserById(@PathVariable Integer id) {
        return orderService.getOrderById(id);
    }

    /**
     * redis集群
     */
    @RequestMapping(value = "/cluster/order/add", method = RequestMethod.POST)
    public void clusterAddOrder() {
        orderService.clusterAddOrder();
    }

    @RequestMapping(value = "cluster/order/{id}", method = RequestMethod.GET)
    public String clusterFindUserById(@PathVariable Integer id) {
        return orderService.clusterFindUserById(id);
    }
}

3.2、新建service

*注意:只编写String类型的数据操作,其他类型的API操作,私底下练习

@Service
@Slf4j
public class OrderService {
    public static final String ORDER_KEY = "order:";

    @Resource
    private RedisTemplate<String, String> redisTemplate;

    public void addOrder() {
        int keyId = ThreadLocalRandom.current().nextInt(1000) + 1;
        String orderNo = UUID.randomUUID().toString();
        redisTemplate.opsForValue().set(ORDER_KEY + keyId, "订单编号" + orderNo);
        log.info("redis单机=====>编号{}的订单流水生成:{}", keyId, orderNo);
    }

    public String getOrderById(Integer id) {
        System.out.println(redisTemplate.opsForList().range("myList", 0, -1));
        HashMap<String, String> map = new HashMap<>();
        map.put("k1", "k2");
        map.put("k3", "k4");
        map.put("k5", "k6");
        redisTemplate.opsForValue().multiSet(map);
        return redisTemplate.opsForValue().get(ORDER_KEY + id);
    }

    public void clusterAddOrder() {
        int keyId = ThreadLocalRandom.current().nextInt(1000) + 1;
        String orderNo = UUID.randomUUID().toString();
        redisTemplate.opsForValue().set(ORDER_KEY + keyId, "订单编号" + orderNo);
        log.info("redis集群=====>编号{}的订单流水生成:{}", keyId, orderNo);
    }

    public String clusterFindUserById(Integer id) {
        return redisTemplate.opsForValue().get(ORDER_KEY + id);
    }
}

3.3、新建config

这个配置主要是生成接口文档。

@Configuration
public class OpenAPIConfig {
    @Bean
    public OpenAPI customOpenAPI() {
        String currentDate = DateTimeFormatter.ofPattern("yyyy-MM-dd").format(LocalDateTime.now());
        return new OpenAPI().info(new Info()
                .title("springBoot利用swagger3构建api接口文档 " + "\t" + currentDate)
                .description("springboot+redis整合")
                .version("1.0")
                .termsOfService("https://www.baidu.com/"));
    }
}

3.4、连接redis单机


3.5、连接redis集群


4、测试接口

启动项目,访问http://localhost:8080/swagger-ui/index.html

4.1、单机测试结果

控制台输出:

redis客户端:

Q:数据是存进去了,但是为啥是乱码的?在连接redis客户端的时候加上了-c的参数还是乱码?为啥通过接口获取的数据是正常的,但是通过redis客户端去查看的又是乱码?

A:是因为序列化方式不一致造成。键(key)和值(value)都是通过spring提供的Serializer序列化到数据库的。RedisTemplate默认使用的是JdkSerializationRedisSerializer。解决办法就是统一序列化方式。

新建RedisConfig类:

@Configuration
public class RedisConfig {
    /**
     *设置存储key的序列化方式
     * @param redisConnectionFactory 创建与Redis连接的工厂类
     */
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        //设置String
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(new StringRedisSerializer());
        // 设置hash、set、zSet、list.....
        redisTemplate.afterPropertiesSet();

        return redisTemplate;
    }
}

重启项目,重新测试:

问题解决。


4.2、redis集群测试结果

修改application.properties文件,注释redis单机配置:

重启项目,进行测试:

redis客户端:

初步看来,连接redis集群没毛病。


Q:假设集群中,有主机服务宕机了,从机上位后,程序是否还能正常从redis集群获取与写入数据呢?

A:读能正常但是写不正常

手动关闭6379,模拟测试一下。

是需要手动开启刷新节点拓扑网落的,

#支持集群拓扑动态感应刷新,自适应拓扑刷新是否使用所有可用的更新,默认false关闭
spring.data.redis.lettuce.cluster.refresh.adaptive=true
#定时刷新 毫秒
spring.data.redis.lettuce.cluster.refresh.period=2000

不然,当某个Master主机宕机后,虽然从机上位了,但还是不可用的(针对于这个key刚好落在宕机的Master上)。


(四)、集成Redisson

1、导入依赖

        <dependency>
            <groupId>org.redisson</groupId>
            <artifactId>redisson-spring-boot-starter</artifactId>
            <version>3.45.0</version>
        </dependency>

2、编写业务类

2.1、新建controller
@RestController
@Tag(name = "Redisson订单管理", description = "订单的创建和查询操作")
public class RedissonOrderController {
    @Resource
    private RedissonOrderService redissonOrderService;

    /**
     * redisson连接redis单机
     */
    @RequestMapping(value = "/redisson/order/add", method = RequestMethod.POST)
    public void redissonAddOrder() {
        redissonOrderService.redissonAddOrder();
    }

    @RequestMapping(value = "/redisson/order/{id}", method = RequestMethod.GET)
    public String redissonFindUserById(@PathVariable Integer id) {
        return redissonOrderService.redissonFindUserById(id);
    }

    /**
     * redisson连接redis集群
     */
    @RequestMapping(value = "/redisson/cluster/order/add", method = RequestMethod.POST)
    public void redissonClusterAddOrder() {
        redissonOrderService.redissonClusterAddOrder();
    }

    @RequestMapping(value = "/redisson/cluster/order/{id}", method = RequestMethod.GET)
    public String redissonClusterFindUserById(@PathVariable Integer id) {
        return redissonOrderService.redissonClusterFindUserById(id);
    }

}

2.2、新建service

*注意:只编写String类型的数据操作,其他类型的API操作,私底下练习。

@Service
@Slf4j
public class RedissonOrderService {
    public static final String ORDER_KEY = "order:";

    private final RedissonClient redissonSingleClient;

    private final RedissonClient redissonColonyClient;

    @Autowired
    public RedissonOrderService(@Qualifier("redissonColonyClient") RedissonClient redissonColonyClient,
                                @Qualifier("redissonSingleClient") RedissonClient redissonSingleClient) {
        this.redissonColonyClient = redissonColonyClient;
        this.redissonSingleClient = redissonSingleClient;
    }

    public void redissonAddOrder() {
        int keyId = ThreadLocalRandom.current().nextInt(1000) + 1;
        String orderNo = UUID.randomUUID().toString();
        redissonSingleClient.getBucket(ORDER_KEY + keyId).set("订单编号" + orderNo);
        log.info("redisson连接redis单机=====>编号{}的订单流水生成:{}", keyId, orderNo);
    }

    public String redissonFindUserById(Integer id) {
        RBucket<Object> bucket = redissonSingleClient.getBucket(ORDER_KEY + id);
        return (String) bucket.get();
    }

    public void redissonClusterAddOrder() {
        int keyId = ThreadLocalRandom.current().nextInt(1000) + 1;
        String orderNo = UUID.randomUUID().toString();
        redissonColonyClient.getBucket(ORDER_KEY + keyId).set("订单编号" + orderNo);
        log.info("redisson连接redis集群=====>编号{}的订单流水生成:{}", keyId, orderNo);
    }

    public String redissonClusterFindUserById(Integer id) {
        RBucket<Object> bucket = redissonColonyClient.getBucket(ORDER_KEY + id);
        return (String) bucket.get();
    }
}

2.3、新建config
@Configuration
public class RedissonConfig {
    /**
     * redisson连接redis单机
     */
    @Bean(name = "redissonSingleClient")
    @Primary
    public RedissonClient redissonSingleClient() {
        Config config = new Config();
        // 单机模式
        config.useSingleServer().setAddress("redis://192.168.112.131:6381").setPassword("root");
        // 设置 JSON 序列化编解码器
        config.setCodec(new JsonJacksonCodec(new ObjectMapper()));
        return Redisson.create(config);
    }

    /**
     * redisson连接redis集群
     */
    @Bean(name = "redissonColonyClient")
    public RedissonClient redissonColonyClient() {
        Config config = new Config();
        // 设置JSON序列化编解码器
        config.setCodec(new JsonJacksonCodec(new ObjectMapper()));
        // 集群模式
        config.useClusterServers().addNodeAddress("redis://192.168.112.129:6379",
                        "redis://192.168.112.129:6380",
                        "redis://192.168.112.130:6381",
                        "redis://192.168.112.130:6382",
                        "redis://192.168.112.131:6383",
                        "redis://192.168.112.131:6384")
                .setScanInterval(2000)// 集群状态扫描间隔时间,单位是毫秒
                .setPassword("root");
        return Redisson.create(config);
    }
}

2.4、连接redis单机


2.5、连接redis集群


3、测试接口

3.1、单机测试结果

控制台输出:

redis客户端:


3.2、redis集群测试结果

控制台输出:

redis客户端:


三、总结

在Java开发中,与 Redis 进行高效整合是提升系统性能和可扩展性的关键环节。本文为你详细介绍四种主流的Java整合Redis的方式,涵盖底层客户端库Jedis和Lettuce,以及上层框架封装RedisTemplate和Redisson。

Jedis以其简单易懂的使用方式脱颖而出,对于刚刚接触 Redis 集成的初学者而言,它就像一位耐心的导师,引导着开发者逐步熟悉 Redis的操作。同时,由于其在单线程环境下表现稳定,成为单线程应用场景的理想选择。

Lettuce则凭借卓越的性能在高并发领域独树一帜。它基于 Netty 实现,具备出色的异步处理能力和线程安全性,能够在高并发的浪潮中稳健前行,为高并发场景提供强大的支持。

RedisTemplate与Spring框架深度融合,仿佛是为Spring项目量身定制的利器。在 Spring 项目中,使用RedisTemplate可以轻松地与其他Spring组件协同工作,极大地提高了开发效率,让开发者能够更加专注于业务逻辑的实现。

Redisson作为一个独立的框架,不依赖于任何特定的框架,它专注于分布式系统的开发,提供了丰富的分布式数据结构和服务,如分布式锁、分布式集合等,为分布式系统的搭建提供了全方位的解决方案。

在实际的项目开发中,我们应根据项目的具体需求和应用场景,审慎地选择合适的整合方式。希望本文能够帮助你更好地掌握 Java与Redis的集成技术,为项目注入强大的性能和可扩展性动力。


ps:努力到底,让持续学习成为贯穿一生的坚守。学习笔记持续更新中。。。。


http://www.kler.cn/a/563816.html

相关文章:

  • 如何免费使用稳定的deepseek
  • 通义灵码2.0 AI 程序员体验:优化与问题解决的全过程
  • 千峰React:案例一
  • 【QT 一 | 信号和槽】
  • 技术分享:MyBatis 动态 SQL 的应用 <choose>, <when>, <otherwise>
  • 如何用python将pdf转为text并提取其中的图片
  • 细说STM32F407单片机RS485收发通信实例及调试方法
  • pycharm远程连接服务器运行pytorch
  • <02.26>Leetcode
  • 航旅纵横测试开发一面面经
  • PyTorch下三角矩阵生成函数torch.tril的深度解析
  • Python 高级特性-迭代器
  • 机器学习01
  • servlet相关
  • 【漫画机器学习系列】102.带泄露线性整流函数(Leaky ReLU)
  • playwright GitHub Actions运行测试
  • Fetch 是用于发起HTTP请求的API body 部分
  • 服务器主板可以单独升级吗?有什么影响?
  • 超过DeepSeek、o3,Claude发布全球首个混合推理模型,并将完成新一轮35亿美元融资...
  • 上海商米科技通信工程师后端开发岗内推