CPU 独立 Jetty 服务器停留在 95% 到 100% 之间
CPU stuck between 95% to 100% for Standalone Jetty server
我正在使用 Jetty 启动主 class 作为服务。下面是演示问题的代码摘录。
Server server = new Server(8080);
ResourceHandler resource_handler = new ResourceHandler();
resource_handler.setDirectoriesListed(true);
resource_handler.setWelcomeFiles(new String[] {"index.html"});
resource_handler.setResourceBase(".");
HandlerList handlers = new HandlerList();
handlers.setHandlers(new Handler[] {resource_handler, new DefaultHandler()});
server.setHandler(handlers);
server.start();
server.join();
我在 windows 机器上从 eclipse 运行这个应用程序,有 2 CPU.
启动这个应用程序后,我在不同的机器上执行下面的程序。下面的代码只是生成 100 个并发线程并执行一个简单的 http 请求以获取 index.html 页面。
ExecutorService service = Executors.newFixedThreadPool(100);
for (int i = 0; i < 10000; i++) {
service.execute(new Runnable() {
public void run() {
try {
long startTime = System.nanoTime();
URL url = new URL("http://localhost:8080");
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setRequestMethod("GET");
long endTime = System.nanoTime();
System.out.println(conn.getResponseMessage() + ":" + ((endTime - startTime)/1000000) + " (ms)");
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
service.shutdown();
当我执行这个程序时,服务器的 CPU 立即达到 100%(对于两个内核)。
我已尝试按照 https://wiki.eclipse.org/Jetty/Howto/High_Load 中的建议修改 maxThreads、acceptorThreads、缓冲区大小参数。
但即便如此,对于高负载,CPU 仍然停留在 95-100 之间。
所以这里的问题是,是否缺少任何配置来最小化 CPU?或者这是预期的,只能通过添加更多 CPU 或集群服务来纠正?
感谢您的帮助。
您说您在另一台机器上执行 运行 ExecutorService 部分,但 URL 是 http://localhost:8080
。这是负载测试的禁忌。
一些建议:
- 不要将客户端负载和服务器负载放在同一台机器上(不要作弊并试图将负载放在一台物理机器上的 2 个不同的 VM 上)
- 使用多台客户端机器,而不仅仅是 1 台(当 Jetty 开发人员测试负载特性时,我们至少使用 10:1 客户端机器与服务器机器的比例)
- 不要使用环回、虚拟网络接口、本地主机等进行测试。使用真实的网络接口。
- 不要使用不切实际的负载场景进行测试。服务器的实际使用情况是 HTTP/1.1 流水线连接,每个物理连接有多个请求。有些在快速网络上,有些在慢速网络上,有些甚至在不可靠的网络上(想想移动)
- 如果您必须使用 HttpURLConnection,请了解它如何管理其 HTTP 版本 + 连接(例如保持活动或 http/1.1 关闭),并确保阅读响应正文内容、关闭流和 disconnect() the connection.
我正在使用 Jetty 启动主 class 作为服务。下面是演示问题的代码摘录。
Server server = new Server(8080);
ResourceHandler resource_handler = new ResourceHandler();
resource_handler.setDirectoriesListed(true);
resource_handler.setWelcomeFiles(new String[] {"index.html"});
resource_handler.setResourceBase(".");
HandlerList handlers = new HandlerList();
handlers.setHandlers(new Handler[] {resource_handler, new DefaultHandler()});
server.setHandler(handlers);
server.start();
server.join();
我在 windows 机器上从 eclipse 运行这个应用程序,有 2 CPU.
启动这个应用程序后,我在不同的机器上执行下面的程序。下面的代码只是生成 100 个并发线程并执行一个简单的 http 请求以获取 index.html 页面。
ExecutorService service = Executors.newFixedThreadPool(100);
for (int i = 0; i < 10000; i++) {
service.execute(new Runnable() {
public void run() {
try {
long startTime = System.nanoTime();
URL url = new URL("http://localhost:8080");
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setRequestMethod("GET");
long endTime = System.nanoTime();
System.out.println(conn.getResponseMessage() + ":" + ((endTime - startTime)/1000000) + " (ms)");
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
service.shutdown();
当我执行这个程序时,服务器的 CPU 立即达到 100%(对于两个内核)。
我已尝试按照 https://wiki.eclipse.org/Jetty/Howto/High_Load 中的建议修改 maxThreads、acceptorThreads、缓冲区大小参数。
但即便如此,对于高负载,CPU 仍然停留在 95-100 之间。
所以这里的问题是,是否缺少任何配置来最小化 CPU?或者这是预期的,只能通过添加更多 CPU 或集群服务来纠正?
感谢您的帮助。
您说您在另一台机器上执行 运行 ExecutorService 部分,但 URL 是 http://localhost:8080
。这是负载测试的禁忌。
一些建议:
- 不要将客户端负载和服务器负载放在同一台机器上(不要作弊并试图将负载放在一台物理机器上的 2 个不同的 VM 上)
- 使用多台客户端机器,而不仅仅是 1 台(当 Jetty 开发人员测试负载特性时,我们至少使用 10:1 客户端机器与服务器机器的比例)
- 不要使用环回、虚拟网络接口、本地主机等进行测试。使用真实的网络接口。
- 不要使用不切实际的负载场景进行测试。服务器的实际使用情况是 HTTP/1.1 流水线连接,每个物理连接有多个请求。有些在快速网络上,有些在慢速网络上,有些甚至在不可靠的网络上(想想移动)
- 如果您必须使用 HttpURLConnection,请了解它如何管理其 HTTP 版本 + 连接(例如保持活动或 http/1.1 关闭),并确保阅读响应正文内容、关闭流和 disconnect() the connection.