[Java/Netty] Netty 개념과 아키텍처

천승주·2022년 9월 19일
0

Java의 네트워킹

네트워킹 초기에 시작한 개발자는 C언어 소켓 라이브러리의 복잡성을 배우고 다양한 운영체제의 단점을 처리하는 데 많은 시간을 보냈다. 첫번째 Java API(java.net)는 기본 시스템 소켓 라이브러리에서 제공하는 소위 blocking 기능만 지원했다. 다음은 이러한 호출을 사용하는 서버코드의 예이다.

ServerSocket serverSocket = new ServerSocket(portNumber);
// accept()는 ServerSocket에서 연결이 설정될 때까지 차단된 다음 클라이언트와 서버 간의 통신을 위해 새 Socket을 반환
Socket clientSocket = serverSocket.accept();
// BufferedReader, PrintWriter는 Socket의 Input output 스트림에서 파생된다.
// BufferedReader는 문자 입력 스트림에서 텍스트를 읽고
// PrintWriter는 개체의 형식화된 표현을 텍스트 출력 스트림에 인쇄한다.
BufferedReader in = new BufferedReader(
	new InputStreamReader(clientSocket.getInputStream()));
    PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
    String request, response;
    // 줄 바꿈 또는 캐리지 리턴으로 끝나는 문자열을 읽을 때까지 blocking
    while((request = in.readLine()) != null) { 
    	if("Done".equals(request)) break;
    	// 클라이언트의 요청이 처리됨
    	response = processRequest(request);
    	System.out.println(response);
    }
        	
  • 이 코드는 한번에 하나의 연결만 처리한다. 여러개의 동시 클라이언트를 관리하려면 아래와 같이 새 클라이언트 소켓마다 새 스레드를 할당해야 한다.

이러한 접근방식은 자원을 낭비할 가능성이 높다.
1. 어떤 시점에서는 많은 스레드가 휴면 상태일 수 있고 입출력 데이터가 라인에 나타나기를 기다리고 있다.
2. 각 스레드에는 OS에 따라 기본 크기가 64KB에서 1MB인 스택 메모리 할당이 필요하다.
3. JVM이 물리적으로 매우 많은 수의 스레드를 지원할 수 있더라도 컨텍스트 전환의 오버헤드는 해당 제한에 도달하기 훨씬 전에 예를 들어 10000개의 연결에 도달할 때까지 문제가 되기 시작한다.

동시성에 대한 이러한 접근 방식은 소수의 클라이언트에 적합할 수 있지만 100000개 이상의 동시 연결을 지원하는 데 필요한 리소스로 인해 이상적이지 않다. 그에 대한 대안이 Java NIO이다.

Java NIO

Netty 핵심구성요소

  • channels
  • callbacks
  • futures
  • events and handlers
  • codec

Channel

채널은 Java NIO의 기본 구조이다. 채널은 하드웨어 장치, 파일, 네트워크 소켓, 읽기, 쓰기 와 같은 하나 이상의 개별 I/O 작업을 수행할 수 있는 프로그램 구성 요소와 같은 엔티티에 대한 열린 연결이다. 채널은 들어오는(인바운드) 데이터와 나가는 (아웃바운드) 데이터를 위한 수단으로 생각하면 된다. 따라서 열리거나 닫힐 수 있고 연결되거나 연결 해제될 수 있다.

Callback

콜백은 단순히 다른 메서드에 대한 참조가 제공된 메서드이다. 이를 통해 후자는 적절한 시간에 전자를 호출할 수 있다. 콜백은 광범위한 프로그래밍 상황에서 사용되며 작업이 완료되었음을 알리는 가장 일반적인 방법 중 하나이다.

Netty는 이벤트를 처리할 때 내부적으로 콜백을 사용한다. 콜백이 트리거되면 interface ChannelHandler의 구현으로 이벤트를 처리할 수 있다.

public class ConnectHandler extends ChannelInboundHandlerAdapter {
	@Override
    public void channelActive(ChannelHandlerContext ctx) throw Exception {
    	// 새연결이 설정되면 콜백 ChannelHandler의 channelActive()가 호출되고 메세지를 인쇄한다.
    	System.out.println("Client " + ctx.channel().remoteAddress() + " connected");
    }
}

Futures

작업이 완료되었을 때 애플리케이션에 알리는 또 다른 방법이 Future다. 이 개체는 비동기 작업의 결과에 대한 자리 표시자 역할을 한다. 미래의 어느 시점에서 완료되고 결과에 대한 액세스를 제공한다.

Ch

Events and Handlers

Codec

0개의 댓글