简体   繁体   English

Akka Actor中的Httpclient死锁

[英]Httpclient deadlock in Akka Actor

I have an actor which receive message,and download file by httpclient. 我有一个演员,他接收消息,并通过httpclient下载文件。
code sample: 代码示例:

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

Problems occurred after a few days. 几天后出现问题。
From log,it shows actor block at httpclient request. 从日志中,它显示在httpclient请求下的actor块。
Block is ok,but it seems httpclient deadlock,actor don't process any message further. 阻止是可以的,但是似乎httpclient死锁,actor不再处理任何消息。
How is that happens? 这是怎么回事?

log: 日志:

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  

thread dump: 线程转储:

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

If I understand your question, this might help explain what is going on. 如果我理解您的问题,这可能有助于解释发生了什么。 An actor processes messages from its mailbox serially. 参与者连续处理其邮箱中的消息。 It the HttpClient is blocking, then the actor will not complete processing that message, and will process no further message until the block is cleared and the message processing can be completed. 如果HttpClient处于阻塞状态,那么actor将不会完成对该消息的处理,并且在清除该阻塞并且可以完成消息处理之前,不会再处理其他消息。

If you wanted to have the actor not block, then wrap the call the HttpClient activity in a future or send the work off to a pool of actors to handle the situation while you continue to process. 如果希望不阻止参与者,则在以后包装调用HttpClient活动或将工作发送给参与者池以在继续处理时处理情况。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM