2011-01-16 3 views
1

안녕하세요. 저는 잘 확장되고 수천 개의 클라이언트에 서비스를 제공하는 서버 프로그램을 만들고 있습니다. 문제는 Apache MINA가 너무 무거워서 사용하지 않기로 결정하고 대신 내 고객 클라이언트를 작성한 것입니다. Java에서 비동기 소켓 작업을 수행 한 적은 한 번도 없었지만 (C#을 사용하면 훨씬 쉽습니다.하지만이 프로젝트를 Java로 작성하는 것이 더 좋았습니다. 소켓 읽기 이외의 모든 작업에서이 프로젝트에 익숙하므로이 프로젝트를 사용하는 방법을 이해하려고 노력했습니다.) 스레드 풀이 올바르게 나를 위해 어렵습니다. Apache MINA 문서를 사용하여 작업을 수행하는 방법에 대한 아이디어를 얻었습니다. 두 가지 질문이 있습니다.Executors.newFixedThreadPool을 사용하는 비동기 Java NIO에 도움이 필요합니다.

  1. 스레드 풀이 올바르게 사용 되었습니까? Apache MINA의 기본 스레드 크기는 CPU 코어 수 +1입니다. 그러나 수천 명의 클라이언트를 수용하기 위해 실제로 코어 2 듀오에 3 스레드 스레드 풀을 사용해야합니까?
  2. 클라이언트로부터받은 각 메시지에 대해 두 번 버퍼를 다시 할당한다는 것은 알고 있습니다. 각 메시지는 두 개의 패킷으로, 한 개의 헤더는 상수 4 바이트이고 그 길이는 헤더에 지정된 내용 패킷입니다. 버퍼 오버런을 검사하는 고정 된 크기의 버퍼를 사용하는 쉬운 방법이 있습니까? 그래도 동작은 동일하지만 버퍼를 끊임없이 재 할당 할 필요가 없습니다.

    private static final int THREADS = Runtime.getRuntime().availableProcessors() + 1; 
    private ServerSocket socket; 
    private ExecutorService threadPool; 
    private int port; 
    
    public ClientListener(int port) { 
        this.port = port; 
        threadPool = Executors.newFixedThreadPool(THREADS); 
    } 
    
    public void init() { 
        try { 
         socket = new ServerSocket(port); 
        } catch (IOException ex) { 
        } 
    } 
    
    public void run() { 
        while (true) { 
         try { 
          ClientSession s = new ClientSession(socket.accept()); 
          threadPool.execute(s); 
         } catch (IOException ex) { 
         } 
        } 
    } 
    

    대로 ClientSession 관련 코드 :

    private Socket socket; 
    private byte[] buffer; 
    private boolean isHeader; 
    
    public ClientSession(Socket socket) { 
        this.socket = socket; 
        this.buffer = new byte[4]; 
        this.isHeader = true; 
    } 
    
    public void run() { 
        InputStream in; 
        try { 
         in = socket.getInputStream(); 
         out = socket.getOutputStream(); 
        } catch (IOException ex) { 
         return; 
        } 
        while (!socket.isClosed()) { 
         try { 
          int read = in.read(buffer); 
          if (read == -1) 
           break; 
          receive(read); 
         } catch (IOException ex) { 
          break; 
         } 
        } 
    } 
    
    private void receive(int readBytes) { 
        if (isHeader) { 
         if (readBytes >= 4) { 
          buffer = new byte[getPacketLength(buffer)]; 
          isHeader = false; 
         } else { 
          System.out.println("Not enough data received from client " + socket.getInetAddress() + " to decode packet."); 
         } 
        } else { 
         if (readBytes >= buffer.length) { 
          processMessage(new LittleEndianByteArrayReader(decryptData(buffer)), this); 
          buffer = new byte[4]; 
          isHeader = true; 
         } else { 
          System.out.println("Not enough data received from client " + socket.getInetAddress() + " to decode packet (needed " + buffer.length + ", received " + readBytes + ")."); 
         } 
        } 
    } 
    

    당신은하지 않습니다 여기

    ClientListener cl = new ClientListener(1234); 
    cl.init(); 
    new Thread(cl).start(); 
    

    이 ClientListener에 대한 관련 코드입니다 : 여기

내가 리스너를 시작하는 방법 getPacketLength, processMessage, decrypt에 대한 코드를 알아야합니다. 데이터 및 클래스 LittleEndianByteArrayReader,하지만 꽤 그 메서드/클래스의 목적을 분명히 확신 해요.

+0

무엇이 튀어 나오는지는 단지 당신이 예외를 삼키는 것입니다. 적어도 기록하십시오. – dogbane

+0

이것은 단지 코드 스 니펫입니다. 실제 코드에서는 상세한 메시지와 함께 java.util.Logger를 사용하여 로그합니다. –

+0

NIO를 전혀 사용하지 않으십니까? 당신은 Selector가 필요합니다. –

답변

0

귀찮은 사람. 아파치 MINA가 실제로 NIO를 사용한다는 것을 알았습니다. 그래서 혼란 스러웠습니다. 선택기를 사용하여 요청을 처리하는 데 실제로 하나의 스레드 만 있으면됩니다. 모든 답변을 주셔서 감사 드리며 혼란에 대해 사과드립니다.

+1

이 답변은 코멘트 여야합니다. – finnw

0

차단 IO 시나리오의 스레드 수는 클라이언트 수와 각 클라이언트 연결 시간이 계산되어야합니다. 각 사용자의 각 연결에는 스레드가 필요합니다.

세 개의 스레드 만 있으면 사용자는 세 개의 TCP 연결을 열고 서버로 데이터를 전송하지 않고 연결 시간 제한까지 단순히 서버를 차단할 수 있습니다.

+0

Apache MINA에 대한이 사이트를보기 전까지 정확히 내가 생각한 것 : http : // mina.apache.org/configuring-thread-model.html "I/O 작업자 스레드 수 구성"섹션에서 I/O 프로세서 스레드를 제외한 모든 작업자 스레드는 한 번에 하나의 스레드 만 실행합니다. 그러나 I/O 프로세서 스레드의 최대 크기는 CPU 코어 수 + 1이므로 혼란 스러웠습니다. 아마도 그들은 내가 갈 방법과 다르게 작동할까요? –

관련 문제