绝地武士池如何运作?

Posted

技术标签:

【中文标题】绝地武士池如何运作?【英文标题】:How Jedis Pool works? 【发布时间】:2014-02-09 09:59:33 【问题描述】:

我正在使用 Jedis 池来管理与 Redis 服务器的连接。我的一个示例代码如下:

public Set<String> getTopArticleList(int start, int end) 
    Set<String> list = null;
    Jedis j = JedisFactory.getInstance().getJedisPool().getResource();
    Pipeline pipe = j.pipelined();
    try 
        // do stuff with redis
        pipe.sync();
     catch (JedisConnectionException jex) 
        JedisFactory.getInstance().getJedisPool().returnBrokenResource(j);
     finally 
        JedisFactory.getInstance().getJedisPool().returnResource(j);
    
    return list;

创建和检索 Jedis 池的代码:

class JedisFactory 
    private static JedisPool jedisPool;
    public JedisFactory() 
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        jedisPool = new JedisPool(
            poolConfig,
            RedisDBConfig.HOST,
            RedisDBConfig.PORT,
            RedisDBConfig.TIMEOUT,
            RedisDBConfig.PASSWORD
        );
    

    public JedisPool getJedisPool() 
        return jedisPool;
    

    public static JedisFactory getInstance() 
        if (instance == null) 
            instance = new JedisFactory();
        
        return instance;
    
             

问题是在达到限制连接数后,无法再访问网络。我做错了吗?

【问题讨论】:

能把JedisFactory的全部代码加进去吗?尤其是 getInstance() impl 和 getJedisPool()? 我添加了 JedisFactory 的完整代码 您使用 2 个或更多线程吗?可能是多线程问题? 我的应用是一个servlet web,当然还有多线程。 那么您应该保护您的 JedisFactory 和 JedisPool 实例,将它们设置为静态最终(使用急切实例化)或易失性(使用双重检查锁定 - 延迟实例化)。如果没有,每个线程都可以制作它的本地副本(为了性能),对象可以被实例化两次。因此,您可能在运行时有许多 JedisPool 实例,这些实例只是向您的 redis 服务器发送垃圾邮件,而没有足够的连接。 【参考方案1】:

您还没有配置池的 ma​​xTotal 大小,默认值只有 8。您可以将 JedisFactory 构造函数更改为:


    public JedisFactory() 
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        poolConfig.setMaxTotal(128);
        jedisPool = new JedisPool(poolConfig, RedisDBConfig.HOST, RedisDBConfig.PORT, RedisDBConfig.TIMEOUT, RedisDBConfig.PASSWORD);
    

还要注意 WhenExhaustedAction (WHEN_EXHAUSTED_BLOCK) 的默认值,因为它可能不是您想要的行为。

Jedis 使用 Apache Commons Pool,你可以在这里阅读它的参数:GenericObjectPool

【讨论】:

你有没有提到 JedisPoolConfig 参数的文件?我试图搜索,但只是得到了一个没有描述的函数 api 列表。例如,我想知道“WhenExhaustedAction”是做什么的? JedisPoolConfig 没有 setMaxActive。这甚至不会编译。 @JohnMerlino 你说得对,在最新版本的 Jedis 中,他们将 commons-pool 更改为 2.X 版本,所以现在新方法称为 setMaxTotal(),将很快更新答案.

以上是关于绝地武士池如何运作?的主要内容,如果未能解决你的问题,请参考以下文章

Java技术专题「技术盲区」从源码来看看线程池是如何回收和维持运作线程的核心技术体系

猫武士四部曲下三本的内容,求求了

如何在 spring-data 2.0.x 中创建 RedisCacheManager

面试题 -- 如何设计一个线程池

敏捷武士:看敏捷高手交付卓越软件pdf

如何禁止吃鸡游戏,如何屏蔽局域网用户玩绝地求生终结者2荒野行动等手游?