본문 바로가기

SpringWebflux

[Netty] @Sharable 어노테이션과 ChannelHandler 인스턴스 관리

728x90

Netty를 사용하면서 클라이언트로부터 들어오는 데이터를 처리하는 ChannelHandler의 역할과 관리 방법은 매우 중요합니다. 특히, @Sharable 어노테이션의 사용과 각 클라이언트 연결에 대한 ChannelHandler 인스턴스 생성 방식은 데이터 무결성 및 애플리케이션의 성능에 큰 영향을 미칩니다.

 

'ChannelHandler'와 '@Sharable'의 이해


ChannelHandler는 Netty에서 네트워크 이벤트를 처리하는 주요 구성 요소입니다. 클라이언트의 연결, 데이터 수신 등 이벤트가 발생할때마다 Netty는 해당 ChannelHandler를 통해 이를 처리합니다.

 

@Sharable 어노테이션은 하나의 ChannelHandler 인스턴스가 여러 ChannelPipeline 에서 안전하게 공유될 수 있음을 나타냅니다. 하지만 이 어노테이션을 사용할 때 주의해야 할 점이 있습니다. 공유된 ChannelHandler 인스턴스는 여러 클라이언트 연결에 걸쳐 동시에 접근될 수 있으므로, 핸들러 내부에서 상태를 저장하거나 변경하는 동작이 있을 경우 동시성 문제가 발생할수 있습니다.

 

 

왜 각 연결마다 새로운 인스턴스를 사용하는가?


 DataDecoder와 같이 클라이언트로부터 들어오는 데이터를 파싱하는 핸들러의 경우, 내부 상태를 관리하거나 변화시키는 로직을 포함할 가능성이 높습니다. 이런 핸들러에 @Sharable 을 사용하면, 여러 클라이언트 연결 간의 데이터 무결성 문제나 동기화 문제가 발생할 수 있습니다.

 

따라서, 이런 경우에는 각 클라이언트 연결마다 새로운 ChannelHandler 인스턴스를 생성하는 것이 권장됩니다. 이 방식은 각 연결이 독립된 핸들러 인스턴스를 사용함으로써 동시성 문제를 예방할 수 있습니다.

 

구현 방법

public class SimpleDataChannelInitializer extends ChannelInitializer<SocketChannel> {
    @Override
    protected void initChannel(SocketChannel ch) {
        ChannelPipeline p = ch.pipeline();
        p.addLast(new DataDecoder()); // 새로운 인스턴스 생성
        // 다른 핸들러 추가
    }
}

 

위 예시에서, DataDecoder 인스턴스는 initChannel 메소드가 호출될 때마다 새로 생성됩니다. 이렇게 하면 각 클라이언트 연결은 서로 다른 DataDecoder 인스턴스를 사용하게 되므로, 핸들러 간의 상태 간섭없이 안전하게 데이터를 처리할 수 있습니다.

 

정리

Netty를 사용할 때 ChannelHandler의 인스턴스 관리는 중요한 고려 사항입니다. 특히 상태를 저장하거나 변경하는 로직을 포함한 핸들러의 경우, 각 연결마다 새로운 인스턴스를 생성하는 것이 안전합니다. 

 

728x90