gpt4 book ai didi

Java 多线程 Web 服务器 - 不接收多个 GET 请求

转载 作者:可可西里 更新时间:2023-11-01 16:52:58 27 4
gpt4 key购买 nike

我有一个非常基本的多线程 web 服务器的启动,它可以接收所有 GET 请求,只要它们一次一个。

但是,当多个GET请求同时进来时,有时会全部收到,有时会丢失一些。

我通过创建一个带有多个指向我的网络服务器的图像标签的 html 页面并在 firefox 中打开该页面来对此进行测试。我总是使用shift+刷新。

这是我的代码,我一定是在做一些根本性的错误。

public final class WebServer
{
public static void main(String argv[]) throws Exception
{
int port = 6789;

ServerSocket serverSocket = null;
try
{
serverSocket = new ServerSocket(port);
}
catch(IOException e)
{
System.err.println("Could not listen on port: " + port);
System.exit(1);
}

while(true)
{
try
{
Socket clientSocket = serverSocket.accept();
new Thread(new ServerThread(clientSocket)).start();
}
catch(IOException e)
{

}
}
}
}

public class ServerThread implements Runnable
{
static Socket clientSocket = null;

public ServerThread(Socket clientSocket)
{
this.clientSocket = clientSocket;
}

public void run()
{
String headerline = null;
DataOutputStream out = null;
BufferedReader in = null;

int i;

try
{
out = new DataOutputStream(clientSocket.getOutputStream());
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

while((headerline = in.readLine()).length() != 0)
{
System.out.println(headerline);
}
}
catch(Exception e)
{

}
}

最佳答案

首先,@skaffman 的评论是正确的。您不应该像您的代码当前所做的那样捕获并忽略异常。总的来说,这是一种糟糕的做法。在这种情况下,您很可能会丢弃能够告诉您真正问题所在的证据。

其次,我认为您可能对服务器的功能存在误解。无论您如何实现,服务器每秒只能处理一定数量的请求。如果您向它提出的请求多于此,则必须删除一些请求。


我怀疑正在发生的事情是您在短时间内发送了太多请求,并压垮了操作系统的请求缓冲区。

当您的代码绑定(bind)到服务器套接字时,操作系统会设置一个请求队列来保存绑定(bind) IP 地址/端口上的传入请求。这个队列的大小是有限的,如果新请求到来时队列已满,操作系统将丢弃请求。这意味着如果您的应用程序不能足够快地接受请求,一些请求将被丢弃。

你能做些什么?

  • ServerSocket.bind(...) 过载这允许您指定要保留在操作系统级队列中的请求的 backlog。您可以使用这个……或使用更大的积压工作。
  • 您可以更改主循环以更快地从队列中提取请求。当前代码的一个问题是您正在为每个请求创建一个新线程。线程创建成本高,可以通过使用线程池回收之前请求使用的线程来降低成本。

注意事项

你需要小心一点。您很可能可以修改您的应用程序以在短期内接受(而不是丢弃)更多请求。但从长远来看,您应该只在实际处理请求时尽可能快地接受请求。如果它接受它们的速度比您处理它们的速度快,那么就会发生许多不好的事情:

  • 所有尝试处理请求的线程都会占用大量内存。这将以各种方式增加 CPU 开销。
  • 您可能会增加对内部 Java 数据结构、数据库等的争用,从而降低吞吐量。
  • 您将增加处理和回复单个 GET 请求所需的时间。如果延迟太长,客户端可能会超时请求...并重新发送。如果发生这种情况,服务器所做的工作将被浪费。

为了防止这种情况发生,实际上最好不要急切地接受尽可能多的请求。相反,使用有界线程池,并调整池大小(等)以优化吞吐率,同时将处理单个请求的时间保持在合理的范围内。

关于Java 多线程 Web 服务器 - 不接收多个 GET 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4910033/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com