Concurrency 拧入';停车等候';Redis出列状态

Concurrency 拧入';停车等候';Redis出列状态,concurrency,locking,java.util.concurrent,jedis,apache-commons-pool,Concurrency,Locking,Java.util.concurrent,Jedis,Apache Commons Pool,我有一个运行多线程的tomcat-spring4.2应用程序。每个线程仅从一个队列中退出队列,但是有多个线程分配给一个队列 开始时一切正常,但在几个小时/~500k的出列操作之后,我发现线程出列速度非常慢 在jvisualvm中,我看到橙色的线程,即park 线程转储如下所示: "EMLT_2" - Thread t@64 java.lang.Thread.State: WAITING at sun.misc.Unsafe.park(Native Method) - par

我有一个运行多线程的tomcat-spring4.2应用程序。每个线程仅从一个队列中退出队列,但是有多个线程分配给一个队列

开始时一切正常,但在几个小时/~500k的出列操作之后,我发现线程出列速度非常慢

在jvisualvm中,我看到橙色的线程,即park 线程转储如下所示:

"EMLT_2" - Thread t@64
   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 t@63
   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_2”-线程t@64
java.lang.Thread.State:正在等待
在sun.misc.Unsafe.park(本机方法)
-停车等待(java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
位于java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
位于java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
位于org.apache.commons.pool2.impl.LinkedBlockingDeque.takeFirst(LinkedBlockingDeque.java:583)
位于org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:442)
位于org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:363)
位于redis.clients.util.Pool.getResource(Pool.java:48)
位于redis.clients.jedis.JedisPool.getResource(JedisPool.java:86)
位于com.mycop.sam.processors.simpledQueuer.dequeue(simpledQueuer.java:25)
在com.mycop.sam.processors.EMLT.run(EMLT.java:29)上
运行(Thread.java:745)
锁定可拥有的同步器:
-没有
“EMLT_1”-螺纹t@63
java.lang.Thread.State:正在等待
在sun.misc.Unsafe.park(本机方法)
-停车等待(java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
位于java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
位于java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
位于org.apache.commons.pool2.impl.LinkedBlockingDeque.takeFirst(LinkedBlockingDeque.java:583)
位于org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:442)
位于org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:363)
位于redis.clients.util.Pool.getResource(Pool.java:48)
位于redis.clients.jedis.JedisPool.getResource(JedisPool.java:86)
位于com.mycop.sam.processors.simpledQueuer.dequeue(simpledQueuer.java:25)
在com.mycop.sam.processors.EMLT.run(EMLT.java:29)上
运行(Thread.java:745)
锁定可拥有的同步器:
-没有
出列方法为:

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; 
        }
    }
公共字符串出列(字符串队列){
试试看(绝地武士=jedispool.getResource()){
List str=jedis.blpop(10,队列);
如果(str!=null){
返回str.get(1);
}
其他的
返回null;
}
}
我们将感谢您的投入。重新启动后,该应用程序在一段时间内仍能正常运行。 池配置:

<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>

看来你的绝地武士池已经没有连接了。 您是使用returnResourceObject还是returnResource返回资源?(我知道这两个版本都不受欢迎,但它们仍然适用于最新版本的绝地武士)

请记住,绝地武士池与DBCP/Apache池并不完全相同

我有一个类似的问题,当我调用上面的方法时它就结束了


另一方面,由于Redis速度非常快,也许你应该重新考虑你的模式,让很少的线程调用blpop(每个队列一个),并将值转发给其他线程,因此那些不知道Redis的线程(如果不知道的话)。

认为这是连接泄漏,但是使用资源的尝试不应该做到这一点。毕竟,研究发现,该池被注入到另一个类中,编写时间很长,被遗忘,并且存在连接泄漏。傻,我也这么认为,但我该怎么证实呢?除了try(Jedis Jedis=jedispool.getResource())之外,我没有做任何特别的事情。{我需要显式调用这些方法吗?至少在我的情况下我必须这样做,否则它不会起作用。考虑切换到莴苣。
最后{if(Jedis!=null){jedispool.returnResourceObject(Jedis);}
如果你有一些额外的想法可以尝试,请直接调用jedis.close()。然后将此设置添加到你的池配置maxWaitMillis:100。最后一个设置应该可以缓解这个问题,但它仍然存在。因此,对于你的池大小,可能有太多的请求,你会被淹没。