java - 如何使用 Http 持久连接在循环中保持 Java 套接字低延迟?

标签 java sockets http

我正在使用一个 java 程序,该程序重复从 API 下载一些数据。我大约需要这些数据。每 1 秒和低延迟对我的应用程序很重要!所以我做了这样的事情(伪代码):

while (true)
   1: download from API
   2: sleep from remainder of 1 sec
end

平均下载时间为 40-50 毫秒。 当我省略 sleep 时间(第 2 步)时,平均下载时间为 6-8 毫秒。

我已经在许多不同的实现中尝试过此方法:HttpUrlConnection、HttpClient (Java11) 和 Apache HttpClient,但问题仍然存在。所以我做了自己的套接字实现,但问题仍然存在。有办法解决这个问题吗?

我试过 TCP_NO_DELAY 但没有结果。

我的套接字实现:

try (Socket socket = new Socket(hostname, 80)) {
    OutputStream writer = socket.getOutputStream();                     
    InputStream input = socket.getInputStream();                       

    for (int i = 0; i < 10; i++) {                   
        //request headers
        String request = "GET " + path + " HTTP/1.1"    + "\r\n" 
                        + "Host: " + hostname           + "\r\n"
                        + "Connection: keep-alive"      + "\r\n"
                        + "\r\n";
        byte[] wb = request.getBytes(StandardCharsets.US_ASCII);        
        writer.write(wb);

        String statusLine       = readInputStatusLine(input);
        LinkedHashMap headers   = readInputHeaders(input);
        String body             = readBody(headers, input);

        //SLEEP FOR A WHILE (THIS CAUSES DELAYS!!??)
        Thread.sleep(1000);                                             
    }
    socket.close();                                                    
}

最佳答案

另一个戴夫是对的!此问题是由某些服务器端(可能是缓存)问题引起的。我能够测试它并通过进行 2 个后续轮询而不是让线程 hibernate 来解决这个问题。我简单地扔掉第一个(慢速)民意调查,只使用第二个(快速)民意调查。设法获得约 4 倍的速度提升。感谢您的帮助。 伪代码:

while (true)
   1: Do GET and trow away
   2: Do GET and use
   3: sleep for remainder of 1 sec
 end

代码调整:

//SLEEP every second time
if (i % 2 == 0 ){
    totalTimeFast += dur;
    System.out.println(i + ": " + statusLine + ", body length = "
        + body.length() + ", dur=" + dur + " ms   FAST");
    Thread.sleep(Math.max(0, 1000-dur));   
} else {
    totalTimeSlow += dur;
    System.out.println(i + ": " + statusLine + ", body length = "
        + body.length() + ", dur=" + dur + " ms   SLOW");
}   

N=100 测试的部分结果:

90: HTTP/1.1 200 OK, body length = 187136, dur=8 ms   FAST
91: HTTP/1.1 200 OK, body length = 186658, dur=51 ms   SLOW
92: HTTP/1.1 200 OK, body length = 186658, dur=34 ms   FAST
93: HTTP/1.1 200 OK, body length = 186461, dur=51 ms   SLOW
94: HTTP/1.1 200 OK, body length = 186461, dur=7 ms   FAST
95: HTTP/1.1 200 OK, body length = 186374, dur=42 ms   SLOW
96: HTTP/1.1 200 OK, body length = 186374, dur=7 ms   FAST
97: HTTP/1.1 200 OK, body length = 186612, dur=39 ms   SLOW
98: HTTP/1.1 200 OK, body length = 186612, dur=5 ms   FAST
99: HTTP/1.1 200 OK, body length = 186550, dur=36 ms   SLOW
100: HTTP/1.1 200 OK, body length = 186550, dur=13 ms   FAST
Got 100 results with a  totaltimeFast of 1541 ms and totalTimeSlow of 4503 ms

关于java - 如何使用 Http 持久连接在循环中保持 Java 套接字低延迟?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56004523/

相关文章:

java - 发送 DELETE 时实现状态 200

java - 在 Android Studio 中初始化 TextToSpeech 类

C++ Cout 在一个变量中

c# - C# 库中是否有任何东西可以模拟 JavaScript 中的 Navigator 对象?

java - 将 saveInstanceState 与 Uri ArrayList 和适配器一起使用

java - 如何在 3 种不同的浏览器中在同一台电脑上并行运行 selenium html 套件?

C 使用 Open Server 在 LAN 上查找计算机

Java服务器帮助!

c - I/O 完成端口中的 select() 等价

c++ - 使用 BIO_read 时的部分 HTTP 响应