- Jedis
- Lettuce
- Redisson
:都提供了基于Redis操作的Java API,只是封装程度,具体实现稍有不同。
1.1、Jedis
- 是Redis的Java实现的客户端。
- 支持基本的数据类型5种:String、Hash、List、Set、Sorted Set。
特点:使用阻塞的I/O,方法调用同步,程序流需要等到socket处理完I/O才能执行,不支持异步操作。Jedis客户端实例不是线程安全的,需要通过连接池来使用Jedis。
1.2、Lettuce
-
用于线程安全同步,异步和响应使用,支持集群,Sentinel,管道和编码器。
-
基于Netty框架的事件驱动的通信层,其方法调用是异步的。
-
Lettuce的API是线程安全的,所以可以操作单个Lettuce连接来完成各种操作。
-
有2个缺陷就是高并发下没有及时回收导致OOM和间接性断连问题`
1.3、Redisson
优点:分布式锁,分布式集合,可通过Redis支持延迟队列。
可以整合其他实现如redis、springcache、等…
1.4、spring再次封装redisTemplete源码
- redisTemplete:lettuce、jedid操作redis的底层客户端。
- spring再次封装redisTemplete 在 (RedisAutoConfiguration)自动配置里面能看见
SpringBoot2.0以后默认使用 Lettuce作为操作redis的客户端
- springboot2.0以后默认使用lettuce作为操作redis的客户端,他使用进行网络通讯
- Lettuce新,使用netty,吞吐量大
1.1.1、OOM堆外内存溢出问题与方案
lettuce 操作netty的时候,没有及时的进行内存释放,导致OutOfDirectMemoryError
2种解决办法:
第一种:
lettuce的高并发下没有及时回收内存的bug导致:
1、 netty堆外内存溢出
2、 netty如果没有指定堆外内存,他默认使用 -Xmx300m
3、 这个问题:可以通过netty的-Dio.netty.maxDirectMemory进行设置,但是治标不治本,加大-Xmx的配置,但是没有及时得到内存释放,一定会出现这个异常
第二种:
不采用Lettuce作为底层,切换成Jedis。等官方更新Lettuce客户端
1.1.2、Connection断连问题与方案
lettuce 的Connection长时间会断开,导致
- 因为Socket连接断已经是事实,而且在分布式环境中,网络分区是必然的。
- 在网络环境,Redis 服务器主动断掉连接是很正常的,【lettuce 的作者也提及 lettuce 一天发生一两次重连是很正常的】
RedisCommandTimeoutException解决方案:
第一种:netty提供另一个参数的设置:TCP_USER_TIMEOUT,这个参数就是为了针对单独设置某个应用程序的超时重传的设置
第二种:lettuce提供了NettyCustomizer进行扩展,netty所提供的【心跳机制–IdleStateHandler】
【心跳机制】
1、 分析客户端自己做心跳检测,一旦发现Channel死了,主动关闭ctx.close(),那么ChannelInactived事件一定会被触发了。
2、 缺点:增加了客户端的压力
1.1.3、Netty防止内存泄露常识
- 在AbstractNioByteChannel.NioByteUnsafe.read() 处创建了ByteBuf并调用 pipeline.fireChannelRead(byteBuf) 送入Handler链。
- 根据上面的谁最后谁负责原则,每个Handler对消息可能有三种处理方式
- 对原消息不做处理,调用 ctx.fireChannelRead(msg)把原消息往下传,那不用做什么释放。
- 如果已经不再调用ctx.fireChannelRead(msg)传递任何消息,那更要把原消息release掉。
- 假设每一个Handler都把消息往下传,Handler并也不知道谁是启动Netty时所设定的Handler链的最后一员,所以Netty在Handler链的最末补了一个TailHandler,如果此时消息仍然是ReferenceCounted类型就会被release掉。
1.4.1、公共配置抽取
1.4.2、第一个redis数据源
1.4.2、第二个redis数据源
参数配置类
第二数据源配置
1.6.1、注入方式说明
@Autowired 默认按照类型进行注入
- required属性,并且默认为true
- required = true 注入bean的时候该bean必须存在,不然就会注入失败!启动就报错
- required = false 注入bean的时候如果bean存在,就注入成功,如果没有就忽略跳过,启动不会报错。 但是不能直接使用,因为doRequiredTest为NULL!
@Resource 默认按照名称进行注入
有两个重要属性,分别是name和type
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/bian-cheng-ri-ji/20472.html