자바 네트워크 소녀 Netty" 공부하면서 정리한 내용입니다.
1. 이벤트 루프
a. 이벤트 처리 방식
애플리케이션이 이벤트를 처리하는 방법은 크게 2가지로 구분된다.
1. 이벤트 리스너 + 이벤트 처리 스레드
- 일반적으로 UI 프레임워크에서 사용하는 방식
- 이벤트 메서드를 이벤트 리스너에 등록하고, 이벤트가 발생했을 때 이벤트 처리 스레드(싱글 스레드)에서 등록된 메서드 수행
2. 이벤트 큐 + 이벤트 루프
- 1번 방식보다 프레임워크 구현이 복잡하지만 프레임워크 사용자는 간단하게 사용할 수 있음.
- 이벤트 큐에 이벤트 등록하고, 이벤트 루프가 이벤트 큐에 접근하여 처리
- 이벤트 큐는 다중 스레드(이벤트 루프)에서 공유
- 이벤트 결과를 돌려주는 방식으로는 콜백패턴과 퓨쳐패턴이 있다.
b. 싱글스레드와 멀티스레드 이벤트 루프
1. 싱글 스레드 이벤트 루프
- 이벤트 처리 스레드가 하나로 단순하고 예측 가능한 동작을 보장
- 다중 코어 CPC에서 리소스를 비효율적으로 사용(처리시간이 오래 걸린다.)
2. 멀티 스레드 이벤트 루프
- 이벤트 처리 스레드가 여러 개로 구현이 복잡
- 다중 코어 CPU 리소스를 효율적으로 활용(여러 개의 작업을 동시에 처리하기 때문에 처리시간이 빠를 수 있음)
- 멀티스레드의 단점이 그대로 적용(스레드 경합, 컨텍스트 스위칭, OOM 발생)
- 이벤트 발생순서와 실행 순서 불일치 문제(다중 스레드가 하나의 이벤트 큐를 공유하기 때문)
c. Netty의 이벤트 루프
Netty는 싱글 스레드/멀티 스레드 이벤트 루프를 모두 지원한다.
이벤트 루프 스레드 설정
EventLoopGroup bossEventLoopGroup = new NioEventLoopGroup(1); // 스레드 개수 설정
또한 멀티 스레드에서 이벤트 발생순서와 실행 순서 보장
이벤트 큐를 이벤트 루프 스레드의 내부에 둠으로써 순서를 보장.
채널에서 이벤트가 발생하는데 채널은 이벤트 루프에 등록되며 각 이벤트 루프(스레드) 내부에서 이벤트 큐를 관리하기 때문에 이벤트 발생순서와 실행순서 불일치 문제를 해결할 수 있었다.
2. Netty의 비동기 I/O 처리
Netty에서는 비동기 호출을 위 두 가지 패턴을 제공한다. 첫번째는 리액터 패턴의 구현체인 이벤트 핸들러, 두번째는 퓨처 패턴의 구현체인 ChannelFuture이다.
이벤트 핸들러(리액터 패턴)는 앞에서 많이 다루었기 때문에 다루지 않겠다.
https://soonmin.tistory.com/73
[Netty] 채널 파이프라인과 코덱
"자바 네트워크 소녀 Netty" 공부하면서 정리한 내용입니다. 1. 채널 파이프라인 a. 채널 파이프라인 구조 채널파이프라인은 채널과 이벤트 핸들러 사이에서 연결 통로 역할은 한다. b. 채널 파이프
soonmin.tistory.com
ChannelFuture 예제 코드
클라이언트로부터 데이터를 수신하면 클라이언트에게 데이터를 그대로 전송한 후 데이터 전송이 완료되면 연결된 채널을 닫는 코드이다.
public class EchoServerHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
ChannelFuture channelFuture = ctx.writeAndFlush(msg); // 비동기 메서드(ChannelFuture를 돌려 받는다.)
channelFuture.addListener(ChannelFutureListener.CLOSE); // 채널 종료하는 리스너 등록
}
}
Netty는 몇가지 기본 채널 리스너를 제공한다.
- ChannelFutureListener.CLOSE
- ChannelFuture 객체가 작업 완료 이벤트를 수신했을 때 채널을 닫는다.(성공여부 상관없이 수행)
- ChannelFutureListener.CLOSE_ON_FAULURE
- ChannelFuture 객체가 작업 완료 이벤트를 수신하고 결과가 실패일 때 채널을 닫는다.
- ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE
- ChannelFuture 객체가 작업 완료 이벤트르 수신하고 결과가 실패일 때 채널 예외 이벤트를 발생시킨다.
채널 리스너를 직접 구현하여 사용할 수 있다.
위 예제와 동일한 동작을 하는 코드이다. ChannelFutureListenr 인터페이스를 구현해서 리스너에 등록할 수 있다.
public class EchoServerHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
// 데이터가 수신될 때 수행할 코드
ChannelFuture channelFuture = ctx.writeAndFlush(msg);
channelFuture.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
System.out.println("전송한 msg: " + msg);
future.channel().close();
}
});
}
}
'Back-end > 기타' 카테고리의 다른 글
[Netty] Netty 단위 테스트 작성하기 (0) | 2024.01.17 |
---|---|
[Netty] 바이트버퍼(ByteBuffer) (0) | 2024.01.15 |
[Netty] 채널 파이프라인과 코덱 (0) | 2024.01.12 |
[Netty] Netty의 Bootstrap(부트스트랩) (0) | 2024.01.12 |
[Netty] 네트워크 프레임워크 Netty란? (1) | 2024.01.11 |