3

Jedis を使用して Redis データベースにアクセスする Tomcat アプリケーションを実行しています。時々、アプリケーション全体がブロックされます。JavaMelody を使用して Tomcat を監視したところ、オブジェクトが Jedis インスタンスを要求したときに、問題が JedisPool に関連しているように見えることがわかりました。

catalina-exec-74
java.lang.Object.wait(Native Method)
java.lang.Object.wait(Object.java:503)
org.apache.commons.pool.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:1104)
redis.clients.util.Pool.getResource(Pool.java:20)
....

これは私が使用している JedisPoolConfig です

JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxActive(20);
poolConfig.setTestOnBorrow(true);
poolConfig.setTestOnReturn(true);
poolConfig.setMaxIdle(5);
poolConfig.setMinIdle(5);
poolConfig.setTestWhileIdle(true);
poolConfig.setNumTestsPerEvictionRun(10);
poolConfig.setTimeBetweenEvictionRunsMillis(10000);
jedisPool = new JedisPool(poolConfig, "localhost");

したがって、明らかに一部のスレッドは Jedis インスタンスを取得しようとしますが、プールが空でインスタンスを返すことができないため、デフォルトのプール動作は待機です。

私はすでにコード全体を再確認しており、すべての Jedis インスタンスを以前に使用したプールに戻したと確信しています。そのため、インスタンスが不足している理由がわかりません。

プールに残っているインスタンスの数を確認する方法はありますか? アプリケーションがブロックされないように、maxActive パラメータの適切な値を見つけようとしています。

Jedis インスタンスをプールに戻さない以外に、メモリ ホールを作成する方法はありますか?

4

3 に答える 3

4

リソースをプールに戻すことは重要なので、忘れずに行ってください。そうしないと、アプリを閉じるときに、リソースが戻るのを待ちます。

https://groups.google.com/forum/?fromgroups=#!topic/jedis_redis/UeOhezUd1tQ

各 Jedis メソッド呼び出しの後、リソース プールを返します。アプリはおそらくすべてのスレッドを使用し、一部が削除されるのを待機しています。これにより、説明している動作が発生する可能性があり、アプリがブロックされている可能性があります。

Jedis jedis = JedisFactory.jedisPool.getResource();
try{
    jedis.set("key","val");
}finally{
    JedisFactory.jedisPool.returnResource(jedis);
}
于 2012-12-19T15:48:36.913 に答える
0

jedis プールを使用する場合、 を使用してリソースを取得するたびgetResource()に を呼び出す必要がありますreleaseResource()。また、スレッドの数がリソースよりも多い場合、スレッドの競合が発生します。Java ThreadLocal を使用して、スレッドごとに Jedis 接続を行う方がはるかに簡単であることがわかりました。したがって、スレッドごとに、jedis 接続が既に存在するかどうかを確認します。はいの場合はそれを使用し、そうでない場合は実行中のスレッドの接続を作成します。これにより、注意が必要なロックの競合やエラー状態が発生しなくなります。

于 2021-07-27T12:30:12.773 に答える