Springboot lettuce连接池最大连接配置了1000个,但是pools只创建了一个连接

Java大佬~ 2019-05-31 09:57:17
我们在做消息推送功能,需要监听kafka队列的消息,然后从redis中获取消息的具体内容,因为这个kafka队列消息量很大(一般是一分钟几十万),所以我就配置了redis连接池,在这个服务中增大redis可用连接数量,配置如下


可以看出我最大配置了1000个连接池。
服务没启动之前redis,已有56个客户端连接上了redis。如果我的服务启动,应该会有很多连接。



现在启动我的服务


日志频繁的打印开启关闭连接池,然而redis连接的数量只多了一个,变成了57,感觉连接池没有发挥它的作用,总是在不断的开启和关闭,而且连接池的数量只有1个。



以下是我redis的配置
package com.aoetech.aoeim.dispatch.pre.config;

import com.aoetech.aoeim.protocol.protobuf.AoeImTransferPacket;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

/**
* 功能描述 redis序列配置
*
* @author Wuli
* @date 2019/4/11
**/
@Configuration
@EnableCaching // 开启缓存支持
public class RedisConfiguration {

@Bean(name = "redisTemplate1")
@SuppressWarnings("all")
public RedisTemplate<String, String> redisTemplate1(LettuceConnectionFactory lettuceConnectionFactory) {
lettuceConnectionFactory.setShareNativeConnection(false);

RedisTemplate<String, String> template = new RedisTemplate<>();
// 配置连接工厂
template.setConnectionFactory(lettuceConnectionFactory);
//使用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.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jacksonSeial.setObjectMapper(om);
// 值采用json序列化
template.setValueSerializer(new StringRedisSerializer());
//使用StringRedisSerializer来序列化和反序列化redis的key值
template.setKeySerializer(new StringRedisSerializer());
// 设置hash key 和value序列化模式
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(new StringRedisSerializer());
template.afterPropertiesSet();
return template;
}

@Bean(name = "redisTemplate2")
@SuppressWarnings("all")
public RedisTemplate<String, Object> redisTemplate2(LettuceConnectionFactory lettuceConnectionFactory) {
lettuceConnectionFactory.setShareNativeConnection(false);

RedisTemplate<String, Object> template = new RedisTemplate<>();
// 配置连接工厂
template.setConnectionFactory(lettuceConnectionFactory);
//使用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.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jacksonSeial.setObjectMapper(om);
//使用protobuf进行序列化
template.setValueSerializer(new ProtocbufRedisSerializer<>(AoeImTransferPacket.TransferPacket.class));
//使用StringRedisSerializer来序列化和反序列化redis的key值
template.setKeySerializer(new StringRedisSerializer());
// 设置hash key 和value序列化模式
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(new ProtocbufRedisSerializer<>(AoeImTransferPacket.TransferPacket.class));
template.afterPropertiesSet();

return template;
}

}


下面这个是我调试的截图,可以看出,我的连接池的配置信息是加载进来了的,但是pools数量只有一个,这到底是怎么回事啊,为这个快烦死了,有大佬遇到类似的问题吗...



求大佬们帮我,50分献上
...全文
7078 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
白云恋苍狗 2021-01-07
  • 打赏
  • 举报
回复 1
16楼正解 lettuce连接池生效需要配置timeBetweenEvictionRunMillis
Dongft 2020-10-19
  • 打赏
  • 举报
回复
所以请问楼主, 最后的结论是?
客串一回 2020-07-27
  • 打赏
  • 举报
回复
lettuce的连接是线程安全的,需要连接池的必要性有多少呢
Java大佬~ 2020-07-21
  • 打赏
  • 举报
回复
引用 14 楼 javabro 的回复:
你要知道red is是单线程
都支持多线程了
国产零零八 2020-07-07
  • 打赏
  • 举报
回复
shareNativeConnection默认为true,表示多个LettuceConnection将共享一个native connection ValidateConnection默认是false的,也就是说只要connection不为null,就不会归还,每次用同一个connection 如果开启validate的话,每次get的时候都会validate一下,而其validate方法不仅判断isOpen,还判断ping,如果超时等,则会将连接释/归还,再重新获取一次(如果使用连接池的话,则重新borrow一次) 这篇文章中源码分析的很细 链接:https://www.jianshu.com/p/8dfbdd958b99
国产零零八 2020-07-07
  • 打赏
  • 举报
回复
引用 10 楼 Java大佬~ 的回复:
偶尔翻到了,这个貌似很久之前我就解决了,附上关键代码 lettuceConnectionFactory.setValidateConnection(false); lettuceConnectionFactory.setShareNativeConnection(false); springboot默认关闭了多个连接池,默认只有一个。其实多个线连接池意义也不大,redis是单线程的
这才是关键点,lenttuce确实默认关闭了连接池。 lettuce默认的shareNativeConnection参数为true,validateConnection为false
-小末 2020-05-26
  • 打赏
  • 举报
回复
lettuce在多线程下共用一个连接,线程安全,不用连接池也行。jedis必须用连接池才能保证线程安全
danxiao898 2020-01-13
  • 打赏
  • 举报
回复
引用 17 楼 Java大佬~的回复:
[quote=引用 16 楼 danxiao898 的回复:] 配置time-between-eviction-runs属性为正值,min-idle才会生效。
真的吗[/quote] 试一下就知道了。具体可以看我博客,有详细说明。
Java大佬~ 2020-01-09
  • 打赏
  • 举报
回复
引用 16 楼 danxiao898 的回复:
配置time-between-eviction-runs属性为正值,min-idle才会生效。
真的吗
danxiao898 2019-12-26
  • 打赏
  • 举报
回复 1
配置time-between-eviction-runs属性为正值,min-idle才会生效。
雨潇先生 2019-12-09
  • 打赏
  • 举报
回复
引用 10 楼 Java大佬~ 的回复:
偶尔翻到了,这个貌似很久之前我就解决了,附上关键代码 lettuceConnectionFactory.setValidateConnection(false); lettuceConnectionFactory.setShareNativeConnection(false); springboot默认关闭了多个连接池,默认只有一个。其实多个线连接池意义也不大,redis是单线程的
试了下,始终还是只有一个。
javabro 2019-12-06
  • 打赏
  • 举报
回复
你要知道red is是单线程
bug制造艺术家 2019-12-02
  • 打赏
  • 举报
回复
我设置了 setShareNativeConnection 为false 不适用同一个连接 也不好使
bug制造艺术家 2019-12-02
  • 打赏
  • 举报
回复
大佬你这问题最后怎么解决的
Java大佬~ 2019-09-05
  • 打赏
  • 举报
回复
偶尔翻到了,这个貌似很久之前我就解决了,附上关键代码 lettuceConnectionFactory.setValidateConnection(false); lettuceConnectionFactory.setShareNativeConnection(false); springboot默认关闭了多个连接池,默认只有一个。其实多个线连接池意义也不大,redis是单线程的
Java大佬~ 2019-05-31
  • 打赏
  • 举报
回复
顶帖顶帖,求助
Java大佬~ 2019-05-31
  • 打赏
  • 举报
回复
引用 5 楼 水边2 的回复:
看了一下RedisTemplate的实现,execute方法里有一句:
} finally {
    RedisConnectionUtils.releaseConnection(conn, factory);
}
而且我也测试了一下启动100个线程去操作Redis,确实只开了一个tcp连接,而且 代码最终都会走到关闭的代码: conn.close(); 没认真翻其它代码,不确定是不是实现问题。
我用的boot2.1.3,默认连接池是lettuce,我把他改成jedis连接池,连接池的数量确实上来了,但是还是不停的打印这些…redis开启连接,redis关闭连接的日志
游北亮 2019-05-31
  • 打赏
  • 举报
回复
看了一下RedisTemplate的实现,execute方法里有一句:
} finally {
    RedisConnectionUtils.releaseConnection(conn, factory);
}
而且我也测试了一下启动100个线程去操作Redis,确实只开了一个tcp连接,而且 代码最终都会走到关闭的代码: conn.close(); 没认真翻其它代码,不确定是不是实现问题。
Java大佬~ 2019-05-31
  • 打赏
  • 举报
回复
引用 1 楼 水边2 的回复:
这个参数叫 max-active, 所以,它的意思是最大活动连接数,目的是避免你的程序把Redis的连接耗光了,导致别人连不上。 你的程序在连接Redis的时候,池里有空闲的连接,就直接复用, 只有在池里无空闲连接,并且总连接数小于 max-active时,才会创建新的连接,明白吗?
我设置了 min-idle: 20
那么就算我没有用,池子里也应该保持20个连接数量吧
Java大佬~ 2019-05-31
  • 打赏
  • 举报
回复
我设置了 min-idle: 20 那么就算我没有用,池子里也应该保持20个连接数量吧
加载更多回复(2)

67,515

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧