【问题标题】:Response time too high for json webservice call via https url connection通过 https url 连接调用 json webservice 的响应时间太长
【发布时间】:2014-08-04 12:55:57
【问题描述】:

我正在使用 https url 连接将 json 内容发布到 url 中,并且我也收到了响应。但令人失望的是,电话的响应时间约为 2 分钟。在分析相同的内容时,我发现延迟是第一次连接到服务器。 这是我正在使用的代码 sn-p。谁能告诉我这个有什么问题?

import java.net.*;
import java.security.KeyStore;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.io.*;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;

import org.apache.axis2.java.security.TrustAllTrustManager;
import org.json.JSONObject;

public class httpsurl implements X509TrustManager {



public static void main(String s[]) throws ProtocolException {
    httpsurl.query("https://instance.service-now.com/incident.do?JSON");

}

public static void query(String URLName) {
    HttpsURLConnection con = null;
    try {

        JSONObject json = new JSONObject();
        json.put("parameter 1", "value 1");
        json.put("parameter 2", "value 2");



        sun.misc.BASE64Encoder encoder = new sun.misc.BASE64Encoder();
        Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(
                "proxy name", 8080));
        String encodedUserPwd = encoder
                .encode("username:password".getBytes());
          URL u = new URL(URLName);
  //            System.setProperty("http.keepAlive", "false");

        con = (HttpsURLConnection) u.openConnection(proxy);
        SSLContext mySsl = SSLContext.getInstance("TLS");
         mySsl.init(null, new TrustManager[]{new TrustAllTrustManager()}, null);
        con.setRequestProperty("connection", "close");
        con.setReadTimeout(10000);
         con.setConnectTimeout(15000);
        con.setRequestMethod("POST");
         con.setDoInput(true);
        con.setDoOutput(true);
        con.addRequestProperty("Content-Type",  "application/json");
        con.setRequestProperty("Authorization", "Basic " + encodedUserPwd);
         con.setUseCaches(false);
        con.setSSLSocketFactory(mySsl.getSocketFactory());

//          con.connect();          

        OutputStream os = con.getOutputStream();
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
                os, "UTF-8"));
        writer.write(json.toString());
          writer.flush();
        writer.close();
        os.close();



         // Get response
        int HttpsResult = con.getResponseCode();
        StringBuffer sb = new StringBuffer();
        if (HttpsResult == HttpsURLConnection.HTTP_OK) {
             BufferedReader br = new BufferedReader(new InputStreamReader(
                     con.getInputStream(), "utf-8"));
             String line = null;

             while ((line = br.readLine()) != null) {
                 sb.append(line + "\n");
             }
            br.close();

            System.out.println("" + sb.toString());
        } else {
            System.out.println(con.getResponseMessage());
        }




     } catch (MalformedURLException e) {

        e.printStackTrace();
    } catch (IOException e) {

        e.printStackTrace();
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        if (con != null) {
            con.disconnect();

        }
    }
}

@Override
public void checkClientTrusted(X509Certificate[] arg0, String arg1)
        throws CertificateException {
    // TODO Auto-generated method stub

}

@Override
public void checkServerTrusted(X509Certificate[] arg0, String arg1)
        throws CertificateException {
    // TODO Auto-generated method stub

}

@Override
public X509Certificate[] getAcceptedIssuers() {
    // TODO Auto-generated method stub
    return null;
}

}

提前致谢,

迪帕克

【问题讨论】:

  • 尝试使用 fiddler 检查它在哪里花费时间,如果是在创建 ssl 连接或其他地方
  • 如果我正在设置 json 对象,我发现延迟在以下行“OutputStream os = con.getOutputStream();”中。否则,如果我没有设置 json 对象,则在获取响应时会发生延迟。 " int HttpsResult = con.getResponseCode();"因此我假设,延迟是在我第一次连接到 url 的地方。即使将连接对象设为静态也无济于事。顺便说一句,即使我不使用 SSL,它也可以工作。

标签: java json httpsurlconnection


【解决方案1】:

可能有多个错误。如果没有更多的故障排除,很难说...根据我的经验,它可以是以下任何一种:

  1. 服务器端问题(调用确实需要很长的时间)——无论你是否使用http/https,响应速度都会很慢(https会稍微慢一些)
  2. DNS 查找时间(这会同时影响 http/https)。
  3. 防火墙问题(例如,执行 DNS 请求,或者主机名有多个 A 记录并且一些被阻止)。
  4. 在标记为安全的请求/响应中发送 Cookie,并且服务器没有良好的熵源(例如:http://theheat.dk/blog/?p=1539
  5. 我看到您使用的是TrustAllManager。在过去,我遇到过类似的问题。最好将自签名证书导入您的信任库。它似乎工作得更好。 (有关如何执行此操作的示例,请参阅 http://www.chrissearle.org/2007/10/25/Adding_self-signed_https_certificates_to_java_keystore/)。

您最好的诊断方法是 Wireshark。如果您可以使用 wireshark/tcpdump 显示您的代码在您执行 con.getOutputStream() 后立即启动网络连接并且 SYn/SYNC+ACK/ACK 发生得很快,那么您可以将矛头指向服务器。

祝你好运!

【讨论】:

  • 但是你能告诉我这些的解决方案吗?我遇到的另一种情况是,使用上述代码的另一台服务器的响应时间也很长。是否有助于进一步排除故障?
  • 我刚刚添加了一些关于TrustAllManager 的内容。在处理自签名证书时,通常最好将证书导入您的密钥库,而不是使用虚假的信任管理器。
  • 我同意。但即使没有信任经理,它似乎也能工作。 :(
猜你喜欢
  • 2022-06-14
  • 2021-07-04
  • 1970-01-01
  • 2011-05-03
  • 1970-01-01
  • 1970-01-01
  • 2020-04-22
  • 2019-06-01
  • 2021-12-13
相关资源
最近更新 更多