2017-05-02 5 views
1

Also was ich versuche zu tun ist ein Socket, der Eingang vom Client erhält, den Client in die Warteschlange setzen und dann eine Nachricht an jeden Client in der Warteschlange, wenn mein Algorithmus gibt wahr zurück.Java Server mit vielen Clients verbinden ohne Engpässe

Diese Warteschlange sollte ein paar hundert Clients auf einmal unterstützen, aber gleichzeitig nicht den Flaschenhals des Servers, so dass es tatsächlich tun kann, was es tun soll.

Dies ist, was ich bisher:

private static final int PORT = 25566; 
private static final int THREADS = 4; 
private ExecutorService service; 

public void init() throws IOException, IllegalStateException { 
    ServerSocket serverSocket; 
    serverSocket = new ServerSocket(PORT); 
    service = Executors.newCachedThreadPool(); 
    Socket socket; 
    while(true) { 
     socket = serverSocket.accept(); 
     System.out.println 
      ("Connection established with " + socket.getInetAddress().toString()); 
     service.execute(() -> { 
      Scanner scanner = null; 
      PrintWriter output = null; 
      String line = null; 
      try { 
       scanner = new Scanner(new InputStreamReader(socket.getInputStream())); 
       output = new PrintWriter(socket.getOutputStream()); 
      } catch(IOException e) { 
       e.printStackTrace(); 
      } 
      try { 
       if (scanner == null || output == null) 
        throw new IllegalStateException("Scanner/PrintWriter is " + "null!"); 
       line = scanner.nextLine(); 
       while (line.compareTo("QUIT") != 0) { 
        /* This is where input comes in, queue for the algorithm, 
         algorithm happens then returns appropriate values */ 

        output.flush(); 
        line = scanner.nextLine(); 
       } 
      } finally { 
       try { 
        System.out.println 
         ("Closing connection with " + socket.getInetAddress().toString()); 
        if(scanner != null) { 
         scanner.close(); 
        } 
        if(output != null) { 
         output.close(); 
        } 
        socket.close(); 
       } catch(IOException e) { 
        e.printStackTrace(); 
       } 
      } 
     }); 
    } 
} 

Nun, was ich denke, mit diesem passieren wird, ist, wenn die Warteschlangen hoch genug Ebenen erreichen kann, wird mein Thread-Pool vollständig den Server als alle der Engpass Threads werden verwendet, um die Clients in der Warteschlange zu behandeln, und es wird nicht genügend Verarbeitung für den Algorithmus geben.

EDIT: Nach einer Reihe von Tests, denke ich, es wird funktionieren, wenn in den Algorithmus den Wert zurückgibt dann trennt, nicht auf Benutzerantwort warten, aber den Benutzer Client erneut verbinden, wenn bestimmte Bedingungen erfüllt sind.

+1

Werfen Sie einen Blick auf [netty] (http://netty.io/). Es erleichtert das Schreiben von skalierbaren Client/Server-Anwendungen. –

+0

Sie müssen alle E/A zu jedem akzeptierten Client in einem separaten Thread pro Client behandeln. Siehe den Abschnitt Benutzerdefiniertes Netzwerk des Java-Lernprogramms. – EJP

+0

Ja, aber wenn Sie> 100 Kunden haben, ist ein Thread pro Client nicht realistisch – BobbyMacBob

Antwort

1

Es ist unwahrscheinlich, dass Ihr Flaschenhals Strom verarbeitet, es sei denn, Sie sind maschinenlimitiert. Es ist wahrscheinlicher, dass alle Threads in Ihrem Thread-Pool konsumiert werden und auf Eingaben von den Clients warten. Ihr Design kann nur so viele Clients gleichzeitig verarbeiten, wie Threads im Pool vorhanden sind.

Für einige hundert Clients können Sie einfach einen Thread für jeden Client erstellen. Die begrenzende Ressource für die Anzahl der Threads, die unterstützt werden können, ist normalerweise Speicher für den Stack, den jeder Thread benötigt, und nicht die Verarbeitungsleistung; Für eine moderne Maschine mit viel Speicher sind tausend Threads kein Problem, basierend auf persönlichen Erfahrungen. Möglicherweise gibt es einen Betriebssystemparameter, der die Anzahl der Threads begrenzt, die Sie möglicherweise anpassen müssen.

Wenn Sie eine sehr große Anzahl von Clients verwalten müssen, können Sie Ihren Code so einrichten, dass er Sockets nach verfügbaren Eingaben abfragt und die Verarbeitung nur für diejenigen Sockets durchführt, deren Eingabe verarbeitet werden muss.

Verwandte Themen