Je crée un serveur Web basé sur Java. Mais quand je le teste avec ApacheBench, il arrête parfois de répondre.Le serveur socket se bloque lors d'un test avec ab, en attente BufferedReader.readline()
Sur un Macbook Air:
ab -n 20000 -c 40 -d http://localhost:1080/
est garanti à délai d'attente après 16400 ou plusieurs demandes ont été faites.
Sur le bureau Ubuntu
ab -n 20000 -c 1000 -d http://localhost:1080/
pourrait faire avec succès la plupart du temps, mais parfois cesser de répondre après plusieurs passages.
J'ai identifié (à l'aide d'Eclipse) que lorsque le serveur cesse de répondre, il attend BufferedReader.readline() que je l'utilise pour lire l'en-tête de la requête HTTP. Mais je n'ai aucune idée de pourquoi ça l'attend.
Code d'essai est ici:
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, lors de l'écriture du code de test, j'ai trouvé quelque chose d'autre étrange
Si
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
String line = br.readLine();
est remplacé par
String line = "don't read the socket";
ab va échouer avec un tel message: "apr_socket_recv: Connexion refusée (111) Connexion réinitialisée par le pair (104)"
Mais localhost ouvert: 1080 avec Firefox 4 verra apparaître le message "ne pas lire le socket" .
Vous ne fermez pas vos prises en cas d'exception. Vous devriez changer pour que 's.close' soit dans un bloc finally. (Je ne sais pas si c'est le problème, mais ça aiderait à éclaircir les choses) –
N'aidant pas dans ce cas, mais je pense que vous avez raison. Code mis à jour. – CQD