4

複数のスレッドを実行するtomcat-spring4.2アプリケーションがあります。各スレッドは1つのキューからデキューしますが、キューには複数のスレッドが割り当てられています。Redis dequeueの 'parking to wait'状態のスレッド

状況はうまく始まりますが、数時間/〜500kのデキュー操作後、スレッドは非常に遅い速度でデキューします。私はオレンジ色、すなわち公園 のスレッドを参照してくださいjvisualvmで

次のようにスレッドダンプは次のとおりです。

"EMLT_2" - Thread [email protected] 
    java.lang.Thread.State: WAITING 
    at sun.misc.Unsafe.park(Native Method) 
    - parking to wait for <2cf42d7> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) 
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) 
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039) 
    at org.apache.commons.pool2.impl.LinkedBlockingDeque.takeFirst(LinkedBlockingDeque.java:583) 
    at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:442) 
    at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:363) 
    at redis.clients.util.Pool.getResource(Pool.java:48) 
    at redis.clients.jedis.JedisPool.getResource(JedisPool.java:86) 
    at com.mycomp.sam.processors.SimpleDequeuer.dequeue(SimpleDequeuer.java:25) 
    at com.mycomp.sam.processors.EMLT.run(EMLT.java:29) 
    at java.lang.Thread.run(Thread.java:745) 

    Locked ownable synchronizers: 
    - None 

"EMLT_1" - Thread [email protected] 
    java.lang.Thread.State: WAITING 
    at sun.misc.Unsafe.park(Native Method) 
    - parking to wait for <2cf42d7> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) 
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) 
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039) 
    at org.apache.commons.pool2.impl.LinkedBlockingDeque.takeFirst(LinkedBlockingDeque.java:583) 
    at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:442) 
    at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:363) 
    at redis.clients.util.Pool.getResource(Pool.java:48) 
    at redis.clients.jedis.JedisPool.getResource(JedisPool.java:86) 
    at com.mycomp.sam.processors.SimpleDequeuer.dequeue(SimpleDequeuer.java:25) 
    at com.mycomp.sam.processors.EMLT.run(EMLT.java:29) 
    at java.lang.Thread.run(Thread.java:745) 

    Locked ownable synchronizers: 
    - None 

デキュー方法は次のとおりです。

public String dequeue(String queue) { 
     try (Jedis jedis = jedispool.getResource()) { 
      List<String> str = jedis.blpop(10, queue); 
      if(str!=null){ 
       return str.get(1); 
      } 
      else 
       return null; 
     } 
    } 

は、入力に感謝します。アプリはポスト再開後もしばらく元気に機能します。 プールconfに:

<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig"> 
    <property name="maxIdle" value="10" /> 
    <property name="maxTotal" value="70" /> 
    <property name="minIdle" value="10" /> 
</bean> 
<bean id="jedispool" class="redis.clients.jedis.JedisPool"> 
    <constructor-arg name="poolConfig" ref="poolConfig" /> 
    <constructor-arg name="host" value="${REDIS_HOST}" /> 
    <constructor-arg name="port" value="6379" /> 
</bean> 
+0

これは接続リークだと思っていましたが、リソースで試してはいけません。 –

+0

すべての研究の結果、プールにもう1つのクラスが注入されていることが判明しました。長く書いて忘れてしまい、接続リークが発生しました。愚かな –

答えて

1

あなたのjedisプールは、接続の外に実行されて表示されます。 returnResourceObjectまたはreturnResourceでリソースを返していますか? (私はどちらも非難されていることは知っていますが、まだled版のjedisで動作しています)。

jedisプールは、DBCP/Apacheプールとまったく同じではありません。

私は同様の問題があり、上記の方法を呼び出すと終了しました。

一方、Redisは非常に速いので、あなたのスキーマを再考し、blpop(キューごとに1つ)を呼び出すスレッドがほとんどなく、他のスレッドにその値を転送するので、それらは知らない彼らがする必要がない場合は赤十字について。

+0

私はそう思っていましたが、どうすればそれを確認できますか?私は 'try(Jedis jedis = jedispool.getResource()){'とは別に何もしません。これらのメソッドを明示的に呼び出す必要はありますか? –

+0

少なくとも私の場合はそうしなければならなかった、そうでなければ動作しませんでした。 –

+0

レタスに切り替えることを考える。 '最後に{ \t \t \t IF(!jedis = NULL){ \t \t \t \t jedispool.returnResourceObject(jedis)。 \t \t \t} \t \t} 'didntの助け –

関連する問題