JavaベースのWebサーバーを作成しています。しかし、私がApacheBenchでテストしているときに、応答が止まることがあります。 Macbook Airはオンabでテストしたときにソケットサーバーがハングしました。BufferedReader.readline()
:
ab -n 20000 -c 40 -d http://localhost:1080/
は16400の以上の要求が行われた後にタイムアウトすることが保証されます。 Ubuntuのデスクトップで
ab -n 20000 -c 1000 -d http://localhost:1080/
が正常にほとんどの時間をし、時にはいくつかの実行後に応答を停止可能性があります。
私は、サーバーが応答を停止したときに、HTTP要求ヘッダーの読み取りに使用するBufferedReader.readline()を待機していることを確認しました。しかし、私はなぜそれが待っているのか分かりません。
テストコードここにある:
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
String line = br.readLine();
が
String line = "don't read the socket";
に置き換えている場合は
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();
}
}
}
}
}
はところで、テストコードを書くとき、私は他の何か奇妙な
を見つけました
abこのようなメッセージで失敗します:「apr_socket_recv:接続が拒否(111)ピアによってリセット接続(104)」
しかし、オープンはlocalhost:Firefoxの4との1080年には「ソケットを読んでいない」混乱は表示が表示されます。
例外が発生した場合でもソケットを閉じるわけではありません。 's.close'がfinallyブロックに入るように変更する必要があります。 (それが問題なのかどうかは分かりませんが、それは明確なことを助けるでしょう) –
このケースでは役に立たないが、私はあなたが正しいと思う。コードが更新されました。 – CQD