Lettuce线程池问题

一.背景

Lettuce是一个高性能基于Java编写的Redis驱动框架,底层集成了Project Reactor提供天然的反应式编程,通信框架集成了Netty使用了非阻塞IO5.x版本之后融合了JDK1.8的异步编程特性。

因为项目中用到了多redis数据源,需要修改Lettuce客户端的加载方式。

多数据源的加载方式可以看我的另一篇文章,传送门:https://blog.csdn.net/rongshisuo/article/details/103437166

二.数据源代码

直接上加载多数据源的Lettuce核心代码:


    /**
     * 创建redis连接工厂
     */
    public LettuceConnectionFactory createConnectionFactory(Detail detail) {
        //创建pool
        GenericObjectPoolConfig pool = getDefaultLettucePool(100, 200, 50 ,3000, true);
        //创建连接
        RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration();
        configuration.setDatabase(detail.getDatabase());
        configuration.setHostName(detail.getHost());
        configuration.setPort(detail.getPort());
        configuration.setPassword(detail.getPassword());

        LettucePoolingClientConfiguration.LettucePoolingClientConfigurationBuilder builder = LettucePoolingClientConfiguration.builder();
        builder.poolConfig(pool);
        builder.commandTimeout(Duration.ofSeconds(detail.getTimeout()));

        LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(configuration, builder.build());
        connectionFactory.afterPropertiesSet();

        return connectionFactory;
    }


    /**
     * 设置连接池属性
     */
    public GenericObjectPoolConfig getDefaultLettucePool(int maxIdle, int minIdle, int maxActive, int maxWait, boolean testOnBorrow) {
        GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
        poolConfig.setMaxIdle(maxIdle);
        poolConfig.setMinIdle(minIdle);
        poolConfig.setMaxTotal(maxActive);
        poolConfig.setMaxWaitMillis(maxWait);
        poolConfig.setTestOnBorrow(testOnBorrow);
        poolConfig.setTimeBetweenEvictionRunsMillis(3000);
        return poolConfig;
    }

    class Detail {

        private String host;
        private int port;
        private String password;
        private int database;
        private int timeout;
        private Map pool;

        public String getHost() {
            return host;
        }

        public void setHost(String host) {
            this.host = host;
        }

        public int getPort() {
            return port;
        }

        public void setPort(int port) {
            this.port = port;
        }

        public String getPassword() {
            return password;
        }

        public void setPassword(String password) {
            this.password = password;
        }

        public int getDatabase() {
            return database;
        }

        public void setDatabase(int database) {
            this.database = database;
        }

        public int getTimeout() {
            return timeout;
        }

        public void setTimeout(int timeout) {
            this.timeout = timeout;
        }

        public Map getPool() {
            return pool;
        }

        public void setPool(Map pool) {
            this.pool = pool;
        }
    }

三.案例分析/发现问题

下面进行案例分析:

分析工具:arthas

测试代码:get和set两个方法

    @Autowired
    private RedisCache redisCache;

    @RequestMapping("/get")
    public String get(){
        String str = redisCache.get("111111").toString();
        return str;
    }


    @RequestMapping("/set")
    public void set(){
        redisCache.set("demo111111","demo111111");
    }

测试结果:

get,耗费25ms,简直不可思议,耗时太长了

set也是同样的结果

四.解决问题

接下来一步步追进去,寻找原因:发现每次都会获取连接,在获取连接过程中,耗费了10ms,

怀疑是连接池的原因,将连接池摘除,redis恢复正常

主要代码如下:

    /**
     * 创建redis连接工厂
     */
    public LettuceConnectionFactory createConnectionFactory(Detail detail) {

        RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration();
        configuration.setDatabase(detail.getDatabase());
        configuration.setHostName(detail.getHost());
        configuration.setPort(detail.getPort());
        configuration.setPassword(detail.getPassword());
        /*LettucePoolingClientConfiguration.LettucePoolingClientConfigurationBuilder builder = LettucePoolingClientConfiguration.builder();
        builder.poolConfig(pool);
        builder.commandTimeout(Duration.ofSeconds(detail.getTimeout()));*/
        LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(configuration);
        connectionFactory.afterPropertiesSet();
        return connectionFactory;
    }

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(redis,架构笔记,redis,java)