下面的 HttpServer 程序在没有 HTTP keepalive 的情况下可以轻松处理 8000 个请求/秒,但在使用 keepalive 的情况下只能处理 22 个请求/秒。
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
public class HSTest {
public static void main(String[] args) throws IOException {
HttpServer hs = HttpServer.create(new InetSocketAddress(30006), 1000);
hs.createContext("/", new HttpHandler() {
public void handle(HttpExchange he) throws IOException {
byte[] FILE = "xxxxx".getBytes();
he.sendResponseHeaders(200, FILE.length);
OutputStream os = he.getResponseBody();
os.write(FILE);
os.flush();
he.close();
}
});
hs.start();
}
}
这是keepalive的样子:
请注意数据包 6、12 和 17 的巨大延迟。在第一个数据包之后,它们总是略高于 40 毫秒。相反,没有keepalive一切都很好:
在第一个毫秒结束之前,这是 3 个完整的请求!
我在 debian sid Linux amd64 上使用 OpenJDK 8,客户端和服务器都在同一台机器上,并通过 localhost 接口进行通信。为了测试,我使用ab -n 100000 -c 1 http://localhost:30006/
(no keepalive) 和ab -n 100000 -c 1 -k http://localhost:30006/
(keepalive),以及 curl 和 chromium(默认情况下都使用 keepalive)。
那么是什么导致了 HTTP keepalive 请求的 40 毫秒延迟,以及如何使我的服务器更快?