2014-09-21 22 views
1

我遇到了一个奇怪的问题。我希望有人会找出原因。 代码:在新线程中使用Apache HttpClient,我不知道它是否运行完毕

public static void asyncSend(final RoomNotification notification, final int retryTimes) { 

    Thread thread = new Thread(new Runnable() { 
     @Override 
     public void run() { 
      boolean finish = false; 
      try { 
       ObjectMapper mapper = new ObjectMapper(); 
       String messageString = mapper.writeValueAsString(notification); 
       logger.info("json to send to Hipchat :{}", messageString); 
    #1   Content content = Request.Post("https://api.hipchat.com/v2/room/<hidden>/notification?auth_token=<hidden>") 
         .bodyString(messageString, ContentType.APPLICATION_JSON) 
         .execute().returnContent(); 
    #2   logger.info("Hipchat return:{}", content.asString()); 
       finish = true; 
      } catch (ClientProtocolException e) { 
       e.printStackTrace(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } finally { 
    #3   logger.info("send Hipchat {}:\n{}", finish ? "successfully" : "unsuccessfully", notification.message); 
       if (finish) { 
        return; 
       } 
       //如果失败,且还有重试次数就重新发送 
       if (retryTimes > 0) { 
        logger.info("retry sending Hipchat, retry times remain:{}\nmessage:{}", retryTimes, notification.getMessage()); 
        try { 
         Thread.sleep(10000); //重试前暂停10秒 
        } catch (InterruptedException e) { 
         e.printStackTrace(); 
        } 
        asyncSend(notification, retryTimes - 1); 
       } else { 
        logger.info("no retry times remain, finally send Hipchat unsuccessfully.\nmessage:{}", notification.getMessage()); 
       } 
      } 
     } 
    }); 

    thread.start(); 
} 

的问题是,有时在既不#2也不#3的线将被运行。这是否意味着线程无一例外地崩溃,或者#1线路从未完成运行? 第1行的代码是Apache Httpcomponents的参考。

我浅析浅析日志刚才下面的输出显示:

[[email protected] ~]$ grep "json to send to Hipchat" tomcat-mixi/logs/catalina.out | wc -l 
216 
[[email protected] ~]$ grep "send Hipchat successfully" tomcat-mixi/logs/catalina.out | wc -l 
197 
[[email protected] ~]$ grep "send Hipchat unsuccessfully" tomcat-mixi/logs/catalina.out | wc -l 
14 

所以这个问题发生5(216-197-14)次。 希望有人能帮助我!

回答

0

除非您收到的错误严重到finally块无法执行,否则最可能的问题是Request.Post从不返回。

有几种方法可以找出发生了什么。所有这些都应该在程序仍在运行时完成,但所有正在进行呼叫的线程都应该结束。

  1. 检查打开的TCP连接:在Windows或Unix下,在shell或命令提示符下使用“netstat”。此命令显示您的计算机和服务器之间的所有当前TCP连接。检查是否有更多的开放连接比应该。

  2. 创建完整堆栈转储:在unix下找出Java进程的PID(使用“ps”),然后发出“kill -QUIT [pid]”(用您找到的PID替换[pid]) 。在Windows下,它可能更复杂:如果从命令行启动Java程序,请按CTRL + BREAK。或者你可以使用jstack(见https://blogs.oracle.com/pcmreddy/entry/using_jstack_on_windows)。所有这些写入标准输出所有正在运行的线程的堆栈跟踪。检查是否仍然在Request.Post调用中的线程。

您也可以在应用程序仍在执行时执行此操作。但是,你必须区分挂起的线程和运行正常的线程,并恰好在Request.Post调用中。这可能有助于检查TCP连接和/或堆栈跟踪几次,并在几秒钟之间查看发生了什么变化。你也可以给你的线程名包含开始时间,以便更容易地检测线程转储中长时间运行的线程。

+0

谢谢@Thomas。这个答案适用于我! – 2014-11-13 03:25:35

+0

我用jstack,发现有些线程很长一段时间都停留在AppacheHttpClient的方法中。看起来他们正在等待被唤醒。我认为这是AppacheHttpClient的一个缺陷。最后,我放弃了这个机制,并使用nodejs来实现这一点。 – 2014-11-13 03:40:19

相关问题