从API请求数据时如何停止连接超时

时间:2017-03-22 06:46:30

标签: java connection-timeout

我正在使用获取不明飞行物瞄准事件数据的API。 我试图找出在ArrayList Incident内有多少疑似恶作剧,这些恶作剧在给定的时间范围内发生每个不明飞行物事件。

以下是代码段:

for (Incident i : incidents)
    {
        try {
            b = API.getIncidentDetails(i.getIncidentID()).toLowerCase().contains("hoax");
        } catch (Exception e2) {
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
    if (b)
    {
        ++hoaxes;
    }

我认为在数组中循环并检查事件描述getIncidentDetails中是否包含单词hoax会很容易,但事实证明getIncidentDetails方法是API正在向服务器发出请求(不出所料),我每秒多次调用该方法最终导致服务器超载(我认为)并导致ConnectException超时。我无法编辑API的内部工作方式,因此我无法手动处理请求的编写方式。

这是错误:

java.net.ConnectException: Connection timed out: connect
at java.net.DualStackPlainSocketImpl.connect0(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(Unknown Source)
at java.net.AbstractPlainSocketImpl.doConnect(Unknown Source)
at java.net.AbstractPlainSocketImpl.connectToAddress(Unknown Source)
at java.net.AbstractPlainSocketImpl.connect(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at sun.security.ssl.SSLSocketImpl.connect(Unknown Source)
at sun.security.ssl.BaseSSLSocketImpl.connect(Unknown Source)
at sun.net.NetworkClient.doConnect(Unknown Source)
at sun.net.www.http.HttpClient.openServer(Unknown Source)
at sun.net.www.http.HttpClient.openServer(Unknown Source)
at sun.net.www.protocol.https.HttpsClient.<init>(Unknown Source)
at sun.net.www.protocol.https.HttpsClient.New(Unknown Source)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.getNewHttpClient(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect0(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect(Unknown Source)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream0(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(Unknown Source)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(Unknown Source)
at api.ufo.Connection.sendRESTfulQuery(Connection.java:83)
at api.ufo.API.getIncidentDetails(API.java:105)

这是连接中的第83行:

  url = null;sslFactory = null; label267: try { wr = new DataOutputStream(con.getOutputStream());

con是一个HttpsURLConnection实例。

编辑:这是在班级中与con相关的所有代码。敏感信息替换为ignoredURL;它们都是完全相同的。我不太了解连接和连接池,但是从一些谷歌搜索告诉我它看起来没有使用池,并且看起来连接也没有关闭。

  HttpURLConnection con;
  HttpURLConnection con;
  if ("omittedURL".contains("localhost"))
  {

    URL url = new URL("http://omittedURL/" + query);

    con = (HttpURLConnection)url.openConnection();
  }
  else
  {
    url = new URL("https://omittedURL/" + query);

    sslFactory = (SSLSocketFactory)SSLSocketFactory.getDefault();

    con = (HttpsURLConnection)url.openConnection();

    ((HttpsURLConnection)con).setSSLSocketFactory(sslFactory);
  }


  con.setRequestMethod("POST");

  con.setDoOutput(true);

  url = null;sslFactory = null; label267: try { wr = new DataOutputStream(con.getOutputStream());
  }
  finally {
    DataOutputStream wr;
    url = sslFactory; break label267; if (url != sslFactory) url.addSuppressed(sslFactory);
  }
  if (con.getResponseCode() != 200)
  {
    System.err.println("API Response Error Code: " + con.getResponseCode());
  }


  return Utils.processJSONInputStream(con.getInputStream());

结束编辑

我以为我可以使用Thread.sleep在每个请求之间稍微延迟,但设置延迟太小并不能解决问题,并且设置延迟太大会导致用户在数据获取之前等待几分钟显示。

相反,我只是等了3秒钟,如果它超时,但是3秒似乎不足以阻止接下来的几个请求超时或花费太长时间。我尝试了15秒,但没有太大的区别。在请求开始花费1000+毫秒完成之前,它通常会经历200-400个请求,然后超时。 incidents通常有5000 + Incident秒,请求平均需要32毫秒。

目前需要花费10分钟+来循环〜{5000}方法调用getIncidentDetails,这已经太长了。我希望能够将其减少到平均3-5分钟。

我想到有一个Thread发出请求,另一个Thread检查请求是否花了太长时间然后interrupt请求Thread,但是我不知道如何实现它,因为不幸的是我仍然是一个菜鸟。如果这是一个好主意,请提供一些关于如何完成它的提示。

感谢阅读。如果您需要更多信息,请询问。

0 个答案:

没有答案