【Redis】之 SpringBoot 项目整合 Redis 实战

一、Spring 项目整合 Redis


1、引入 Redis 依赖:

<!-- 引入redis -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

2、添加 Redis 相关配置:

Spring:
	redis:
		host: 192.168.56.10
		port: 6379

由于我们测试的 Redis 是没有设置密码的,所以只需要设置主机和端口号即可,如果 Redis 服务器设置了密码,则需要配置密码。

3、使用 Redis

配置好 Redis 之后,我们操作 Redis 使用的是 Spring Boot 自动配置好的 RedisTemplate<Object, Object> 这个模板类来操作的,这个类的泛型都是 Object 的,所以是通用的,但由于 String 类型比较常用,所以 Redis 还特意准备了一个 StringRedisTemplate 类来操作数据类型是 String 的 Redis 数据。

public class StringRedisTemplate extend RedisTemplate<String, String> {
    ....
}

下面是实际开发中使用 StringRedisTemplate 案例:

@Resource
private StringRedisTemplate stringRedisTemplate;

public Map<String, List<Catelog>> getCatalogJson() {
    // 构建操作数据的 ValueOperations 对象
    ValueOperations<String, String> ops = stringRedisTemplate.opsForValue();
    
    // 从缓存中查询数据
    String catalogJson = ops.get("catalogJson");
    if (StringUtils.isEmpty(catalogJson)) {
        // 缓存中没有数据,查询数据库
        Map<String, List<Catelog>> catalogJsonFromDb = getCatalogJsonFromDb();
        // 把查到的数据对象转换为 JSON 放入缓存中
        String jsonData = JSON.toJSONString(catalogJsonFromDb);
        ops.set("catalogJson");
        // 返回查询结果
        return catalogJsonFromDb;
    }
    
    // 转为指定的对象
    Map<String, List<Catelog>> result = JSON.parseObject(catalogJson, new TypeReference<Map<String, List<Catelog>>>(){});

    return result;
}

StringRedisTemplate 通过 ValueOperations 来操作数据,并且提供了操作不同数据的 ValueOperations 构造方法:

  • opsForValue():用于操作 value 是简单数据类型的字符串
  • opsForHash():用于操作 value 是 hash 类型的,相当于 value 也是 key-value 类型的字符车
  • opsForList():用于操作 value 是 list 类型的字符串
  • opsForSet():用于操作 value 是 set 类型的字符串
  • opsForZset():用于操作 value 是 zset(有序 set) 类型的字符串

注意:不管是操作那种数据类型,由于我们使用的是 StringRedisTemplate,所以它的 value 值都是 String 类型的,只是不同的数据类型操作会进行字符串转化而已,比如把 hash 转为 string,把 list 转为 string。

在把数据假如缓存逻辑中,把数据转为了 JSON 字符串,因为 JSON 具有跨语言特性,所以,转为 JSON 可以做到跨平台兼容。JSON 的操作使用的是阿里巴巴的 fastjson 工具,当加入缓存时使用 toJSONString 把对象转为 JSON 字符串,从缓存中获取数据时,使用 parseObject 来把 JSON 字符串转为 Java 对象。


二、Redis 堆外内存溢出问题


由于 SpringBoot 2.0 以后都是默认使用 lettuce 作为操作 Redis 的客户端,而它底层使用的是 netty 进行网络通信。由于 lettuce 的 bug 问题,会在 Redis 进行压测时出现堆外内存溢出:OutOfDirectMemoryError。

这个 bug 是 netty 的问题导致的,如果我们启动 Java 应用程序时设置了虚拟机内存参数:-Xmx300m,那么如果 netty 没有指定堆外内存,则会默认使用 -Xmx300m 参数,一旦内存超过设置这个数就会造成堆外内存溢出。

当然,我们可以通过 -Dio.netty.maxDirectMemory 参数设置 netty 的堆外内存,但通过这种方式去调大堆外内存是行不通的,随着程序的运行,迟早会出现这个错误。

可以通过以下两种方式解决这个问题:

  • 1)、升级 lettuce 客户端
  • 2)、切换使用 jedis 客户端

注意lettucejedis 都是操作 Redis 的底层客户端,只是 SpringBoot 对这些客户端进行了再次封装成 RedisTemplate。

切换方式为,在 Redis 依赖中排除 lettuce ,并引入 jedis 客户端依赖:

<!-- 引入redis -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
    <!-- 排除默认的 lettuce 客户端 -->
    <exclusions>
        <exclusion>
            <groupId>io.lettuce</groupId>
            <artifactId>lettuce-core</artifactId>
        </exclusion>
    </exclusions>
</dependency>

<!-- 引入 Jedis 客户端 -->
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
</dependency>

这样就不会报堆外内存溢出错误了。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值