java - Akka Actor 中的 Httpclient 死锁

标签 java httpclient akka actor

我有一个 Actor ,它接收消息,并通过httpclient下载文件。
代码示例:

@Override
public void onReceive(Object message) throws Exception {
    HttpClient client = new DefaultHttpClient();
    ...
    httpGet.releaseConnection()
    ...
}

几天后出现问题。
从日志中,它显示了 httpclient 请求时的 actor block 。
阻止是可以的,但似乎 httpclient 死锁,actor 不进一步处理任何消息。
这是怎么发生的?

日志:

Sending message to DownloadActor  
...DownloadActor Receive message  
BasicClientConnectionManager:159 - Get connection for route  
...  

BasicClientConnectionManager:201 - Releasing connection  
Sending message to DownloadActor  
...DownloadActor Receive message  
BasicClientConnectionManager:159 - Get connection for route  

Sending message to DownloadActor  
Sending message to DownloadActor  
Sending message to DownloadActor  
Sending message to DownloadActor  
Sending message to DownloadActor  

线程转储:

"grabSystem-akka.actor.default-dispatcher-67" prio=10 tid=0x00007fa4d4004800 nid=0x2ad8 waiting on condition [0x00007fa5671a7000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x0000000411a2a010> (a akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinPool)
        at scala.concurrent.forkjoin.ForkJoinPool.scan(ForkJoinPool.java:2075)
        at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
        at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)

"grabSystem-akka.actor.default-dispatcher-66" prio=10 tid=0x00007fa4b4001000 nid=0x5ea runnable [0x00007fa5679ae000]
   java.lang.Thread.State: RUNNABLE
        at java.net.SocketInputStream.socketRead0(Native Method)
        at java.net.SocketInputStream.read(SocketInputStream.java:152)
        at java.net.SocketInputStream.read(SocketInputStream.java:122)
        at org.apache.http.impl.io.AbstractSessionInputBuffer.read(AbstractSessionInputBuffer.java:204)
        at org.apache.http.impl.conn.LoggingSessionInputBuffer.read(LoggingSessionInputBuffer.java:82)
        at org.apache.http.impl.io.ChunkedInputStream.read(ChunkedInputStream.java:177)
        at org.apache.http.conn.EofSensorInputStream.read(EofSensorInputStream.java:138)
        at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:283)
        at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:325)
        at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:177)
        - locked <0x0000000412038e10> (a java.io.InputStreamReader)
        at java.io.InputStreamReader.read(InputStreamReader.java:184)
        at java.io.Reader.read(Reader.java:140)
        at org.apache.http.util.EntityUtils.toString(EntityUtils.java:233)
        at org.apache.http.util.EntityUtils.toString(EntityUtils.java:273)
        at com.baidu.grab.core.DownloadActor.onReceive(DownloadActor.java:102)
        at akka.actor.UntypedActor$$anonfun$receive$1.applyOrElse(UntypedActor.scala:167)
        at akka.actor.Actor$class.aroundReceive(Actor.scala:465)
        at akka.actor.UntypedActor.aroundReceive(UntypedActor.scala:97)
        at akka.actor.ActorCell.receiveMessage(ActorCell.scala:516)
        at akka.actor.ActorCell.invoke(ActorCell.scala:487)
        at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:238)
        at akka.dispatch.Mailbox.run(Mailbox.scala:220)
        at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(AbstractDispatcher.scala:393)
        at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
        at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
        at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
        at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)

最佳答案

如果我理解你的问题,这可能有助于解释发生了什么。参与者连续处理来自其邮箱的消息。如果 HttpClient 正在阻塞,那么参与者将无法完成该消息的处理,并且不会处理进一步的消息,直到清除该阻塞并且可以完成消息处理。

如果您想让 Actor 不阻塞,请在将来包装 HttpClient Activity 的调用,或者将工作发送到 Actor 池以在您继续处理时处理这种情况。

关于java - Akka Actor 中的 Httpclient 死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27373703/

相关文章:

java - 导航栏中的底部按钮是什么,您有时会看到它用于更改设置

java - Akka Actor 和 future : Understanding by example

java - Android 中的 SQLite 替换和外键

java - 如何用Dozer实例化子类?

ruby HTTPClient - SSL 和设置 _auth

java - 如何在对象 Java 中映射 HttpResponse

java - Apache HttpClient 异常 PKIX 路径构建失败

scala - 使用 Akka Http 进行多个绑定(bind)

mysql - 如何在Akka Actor中使用MYSQL jdbc实现

java - JButton KeyBinding 和 setActionCommand