【发布时间】:2023-04-01 01:12:01
【问题描述】:
我正在制作一个基于 Java 的 Web 服务器。但是当我使用 ApacheBench 对其进行测试时,它有时会停止响应。
在 Macbook Air 上:
ab -n 20000 -c 40 -d http://localhost:1080/
保证在完成 16400 个或更多请求后超时。
在 Ubuntu 桌面上
ab -n 20000 -c 1000 -d http://localhost:1080/
大部分时间都可以成功,但有时会在运行几次后停止响应。
我已经确定(使用 Eclipse)当服务器停止响应时,它正在等待 BufferedReader.readline(),我用它来读取 HTTP 请求标头。但我不知道它为什么要等待。
测试代码在这里:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class TestServer {
public static void main(String[] args){
ServerSocket socket = null;
try{
socket = new ServerSocket(1080);
ExecutorService pool = Executors.newFixedThreadPool(10);
while(true){
Socket s = socket.accept();
pool.execute(new RequestHandler(s) );
}
}
catch(Exception e){
e.printStackTrace();
}
finally{
if(null!=socket){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
class RequestHandler implements Runnable{
final Socket s;
public RequestHandler(Socket s) {
this.s = s;
}
public void run() {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
String line = br.readLine();
PrintWriter pw = new PrintWriter(s.getOutputStream());
pw.print("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n");
pw.print(line);
pw.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally{
if(s!=null){
try {
s.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
顺便说一句,在写测试代码的时候,我发现了一些奇怪的地方
如果
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
String line = br.readLine();
被替换为
String line = "don't read the socket";
ab 将失败并显示以下消息:“apr_socket_recv: Connection denied (111)Connection reset by peer (104)”
但是使用 Firefox 4 打开 localhost:1080 会看到“不读取套接字”的混乱出现。
【问题讨论】:
-
如果发生异常,您不会关闭套接字。您应该进行更改,以便
s.close在 finally 块中。 (不确定这是否是问题,但它会帮助解决问题) -
在这种情况下没有帮助,但我认为你是对的。代码已更新。
标签: java sockets readline serversocket apachebench