mm Home

Netty 본문

개발/기타

Netty

jess_m 2017. 11. 17. 15:01

Spring web-flux에서 Netty가 defualt 컨테이너로 사용된다.

그 동안 Servlet 컨테이너로 톰캣만 이용해서 Netty에 대해서 잘 몰랐었다.

Netty가 무엇인지 어떻게 사용되는지에 대해서 알아보자.

Netty를 이용한 전반적인 개발 이야기할 것은 아니고.. web-flux에서 어떻게 사용되었는지를 위해 이해하는 정도로만 공부해보았다.




예전에는..


먼저 전통적인 네트워크 프로그래밍에서는 하나의 Request를 할당하여 하나의 스레드를 할당하여 소켓을 열었다.(Blocking) 아래와 같은 코드로 표현할 수 있을 것이다.



accpet() 는 소켓 통신이 established 될 때까지 block 한다. BufferedReader와 PrintWriter는 소켓 통신에서 문자열(각 input, output)의 Stream으로 사용한다. 그리고 또 readLine에서 통신의 끝을 확인할 때까지 block 한다.

위 코드에서 알겠지만, 한번에 하나의 커넥션에 대해서만 핸들링 한다. 다수의 커넥션을 핸들링해야한다면, 새로운 스레드를 할당해야 한다. 아래와 같이 될 것이다.

Input과 Ouput을 위해 계속 기다려야하므로 리소스 낭비가 있을 수 밖에 없다.

(Netty in Action)


Java는 non-blocking I/O를 지원하기 위해 NIO(New I/O)를 JDK 1.4에 내놓았다. 그리고 NIO를 통해 아래와 같이 단일 스레드로 다수의 커넥션을 핸들링하는게 가능해졌다.

단일 스레드로 다수의 커넥션을 핸들링하므로 컨텍스트 스위칭 비용이 들지않고, 처리할 I/O가 없으면 다른 task에 스레드를 활용할 수도 있다. 자원에서 많은 이점이 생길뿐아니라, 자원이 여유있으니 이전보다 더 많은 커넥션을 생성할 수 있다.





그리고 Netty는 Java의 NIO 를 이용한 프레임워크이다.



'Netty는 비동기 event-driven 방식의 네트워크 프레임워크이다. 

네트워크 프레임워크로써 클라/서버 다양한 기능을 지원해준다.'



공부해본 걸 정리하면...

아래와 같은 프로세스로 동작하는 것으로 보인다.



중요 키워드에 대해 알아보자.


Channel

read, write, connect, bind 같이 I/O 작업이 가능한 컴포넌트 또는 네트워크 연결에 대한 인터페이스이다.

실제 클라이언트가 요청한 내용을 서버가 주고, 받기 위한 인터페이스라고 보면 될것 같다. (추상화된 소켓 표현)


Selector

요청에 대한 이벤트를 select 하게 해주어야 한다. 여러 이벤트 핸들러가 혼합될 수 있으므로 그것에 대한 구조화된 제공을 해준다.


EventLoop

Event-driven 어플리케이션이기 때문에 이벤트를 기다리기 위한 Loop가 필요하다. 해당 루프를 EventLoop라고 부르며, 계속해서 이벤트가 발생했는지 확인하고 이벤트를 Selector에게 넘겨주게 된다.


ChannelHandler

I/O 이벤트나 Operation을 핸들하는 핸들러이다. 실제 요청에 대한 핸들을 하기 위한 인터페이스라고 보면 될 것 같다.


ChannelPipeline

입력으로 출력을 전달할 수 있도록 파이프라이닝 한다.

이벤트 핸들러를 단일 처리기로 계속 연결하는 대신, 입력으로 출력을 전달할 수 있도록 파이프라인 개념을 통해 전체 처리에 대한 sequence를 연결한다.

Intercepting Filter pattern 개념.


Codec

Byte를 메세지로, 메세지를 Byte로 변환하는 것을 말한다. (Incoder + Decoder)

예를들어, ChannelPipeline내에 존재하는 ChannelHandler가 inbound는 HTTP의 바이트를 메세지로 변환하는 작업이 있을 것이고, outbound는 메세지를 HTTP를 위한 바이트로 변환하는 작업이 있을 것이다.






Netty는 Selector를 통하여 I/O 작업을 위한 채널을 관리한다. 

새로운 Request가 온다면, Selector가 새 Channel을 생성하고 해당 ChannelEvent를 파이프라이닝하여 서버작업을 진행하게 된다.

파이프라이닝 작업은 ChannelHandler 들로 구성되어 실제 요청에 대한 핸들러 작업을 진행하게 된다. 


여기서 Selector는 멀티 쓰레드로 구성되어졌다. 일반적인 서블릿 스레드는 Request를 하나의 스레드로 할당한 반면, Selector는 보다 적은 스레드풀로 Context-Switching 비용을 줄였다는 점이다. 여기에 더하여 해당 프로세스 내에 I/O에 대한 성능 향상을 했다고 한다. 





참고

http://seeallhearall.blogspot.kr/2012/05/netty-tutorial-part-1-introduction-to.html

http://ayedo.github.io/netty/2013/06/19/what-is-netty.html

http://tutorials.jenkov.com/netty/netty-channelpipeline.html

http://hatemogi.github.io/netty-startup/#1

Netty in action

'개발 > 기타' 카테고리의 다른 글

Reactive Programming  (0) 2017.11.10
HTTP 동작 과정  (0) 2017.10.26
OSI 7  (0) 2017.09.29
Hystrix  (0) 2017.08.17
Comments