2017-05-02 6 views
1

그래서 클라이언트에서 입력을 받고 큐에 클라이언트를 넣은 다음 큐에있는 각 클라이언트에 메시지를 반환하는 소켓을 가지고 있습니다. true를 반환합니다.많은 클라이언트가있는 Java 서버가 병목 현상없이 연결

이 대기열은 한 번에 수백 개의 클라이언트를 지원해야하지만 실제로 병목 현상을 일으키지 않아 실제로 수행 할 수있는 작업을 수행 할 수 있습니다. 큐가 충분히 높은 수준에 도달 할 경우

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(); 
       } 
      } 
     }); 
    } 
} 

지금 나는이 일이 일어날 생각입니다, 내 스레드 풀 완전히 모든으로 서버 병목됩니다

내가 지금까지 무엇을 가지고 스레드가 대기열의 클라이언트를 처리 할 때 사용되며 알고리즘에 대한 처리가 충분하지 않습니다.

EDIT : 알고리즘을 통해 값을 반환하고 사용자 응답을 기다리지 않고 특정 조건이 충족 된 후 사용자 클라이언트를 다시 연결하면 문제가 해결 될 것이라고 생각합니다.

+1

[netty] (http://netty.io/)를보십시오. 확장 가능한 클라이언트/서버 응용 프로그램을 훨씬 쉽게 작성할 수 있습니다. –

+0

클라이언트마다 별도의 스레드에서 각 허용 된 클라이언트에 대한 모든 I/O를 처리해야합니다. Java Tutorial의 Custom Networking 섹션을 참조하십시오. – EJP

+0

그래,하지만 고객이 100 명을 넘으면 클라이언트 당 하나의 스레드가 현실이 아니야 – BobbyMacBob

답변

1

기계 제한이없는 한 병목 현상이 처리 능력이 될 것 같지 않습니다. 일어날 가능성이 큰 것은 스레드 풀의 모든 스레드가 소비되어 클라이언트의 입력을 기다리는 것입니다. 풀에 스레드가 있기 때문에 디자인은 한 번에 많은 클라이언트를 처리 할 수 ​​있습니다.

몇 백 개의 클라이언트의 경우 간단히 각 클라이언트에 대한 스레드를 만드는 것을 고려해 볼 수 있습니다. 지원할 수있는 스레드 수에 대한 제한 리소스는 일반적으로 각 스레드가 필요로하는 스택의 메모리이며 처리 능력은 아닙니다. 충분한 메모리를 가진 최신 기계의 경우, 수천 개의 스레드가 개인적인 경험에 근거하여 문제가되지 않습니다. 조정해야하는 스레드 수를 제한하는 운영 체제 매개 변수가있을 수 있습니다.

매우 많은 수의 클라이언트를 처리해야하는 경우 사용 가능한 입력에 대해 소켓을 폴링하도록 코드를 설정하고 처리 할 입력이있는 소켓에 대해서만 처리를 수행 할 수 있습니다.