Java 기반 웹 서버를 만들고 있습니다. 그러나 ApacheBench로 테스트 할 때 때때로 응답을 멈 춥니 다. 맥북 에어에 ab로 테스트 할 때 소켓 서버가 멈추었습니다. BufferedReader.readline()
:ab -n 20000 -c 40 -d http://localhost:1080/
는 16,400 이상의 요청이 완료 된 후에 시간 초과 보장됩니다. 우분투 데스크탑
ab -n 20000 -c 1000 -d http://localhost:1080/
에
성공적으로 대부분의 시간을 완료,하지만 때로는 여러 실행 후 응답을 중지 할 수 있습니다.이클립스를 사용하여 서버가 응답을 멈췄을 때 HTTP 요청 헤더를 읽는 데 사용하는 BufferedReader.readline()을 기다리고 있음을 확인했습니다. 그러나 나는 왜 그것이 기다리고 있는지 전혀 모른다.
테스트 코드는 여기에 있습니다 :
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();
}
}
}
}
}
BTW 테스트 코드를 작성할 때, 나는
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
String line = br.readLine();
이
String line = "don't read the socket";
로 대체
경우 다른 이상한 것을 발견
ab "apr_socket_recv : 연결이 거부되었습니다 (111) 피어 (104)에 의한 연결 재설정"
Firefox 4에서 localhost : 1080을 열면 "소켓을 읽지 마십시오"라는 메시지가 나타납니다. .
예외가 발생할 경우 소켓을 닫지 않습니다. 's.close'가 finally 블록에 있도록 변경해야합니다. (문제인지 여부는 확실하지 않지만 명확한 정보를 얻는 데 도움이됩니다.) –
이 경우 도움이되지 않지만 나는 당신이 옳다고 생각합니다. 코드가 업데이트되었습니다. – CQD