Java 적응기 02 - Netty

Posted by 엘키의 주절 주절 on July 28, 2017

개요

Java에서 가장 만족한 것이 무엇이냐고 물어본다면 나는 단연 Netty라고 말할 것이다. (그 다음은 Akka)

네트워크 라이브러리 작업을 많이 해본 나로썬, 같은 포지션의 Netty (같은 퀄리티라고 안했다)를 보면서 여러가지 감정이 들었다.

네트워크 라이브러리 작업시 고찰

내가 네트워크 라이브러리 작업을 하며 고민한 것은 아래와 같다

  • 어디까지를 라이브러리의 역할로 두고, 어디까지가 사용자에게 맡길 것인가?
    • 프로젝트마다 특화된 기능을 어떻게 주입 받을 것인가?
      • 자체 암호화, 압축, 보안 등을 위한 패킷 구성
      • 패킷 슬라이스
        • 뭉쳐오는 패킷을 잘라주기
      • 패킷 이벤트를 구현 프로젝트에 어떻게 전달 할 지
      • 워커 스레드 처리 방식
      • 소켓 이벤트 스레드 (IOCP Worker thread 같은) 에서 워커 스레드로 전달하는 방식.
  • 위 기능들의 기본 값을 어떻게 제공해야 사용자에게 편리한 좋은 라이브러리가 되는 가?

특히나 나의 경우 여러 번 작업한 라이브러리에서, 이 부분에 대해 만족하지 못했다.

물론 Netty도 완벽하진 않지만 오랜 기간 많은 사용자들에게 사용되어오며, 적정선을 잘 찾은 느낌이다.

사용법도 아주 간단한 편에 속하며, 패킷 디코딩 문제를 여러가지 템플릿을 제공하며 특수화해서 처리 할 수도 있게끔 유연한 옵션을 제공했다.

나의 경우는 특화 or 기본 값만 생각했는데, Netty는 템플릿으로 여러가지 선택지를 미리 구현해두고 관리하고 있었다.

그리고 난 비동기 동작 요청 (주로 Send고, Connect, Disconnect 등)을 별도의 핸들러를 통해서만 받았는데, 이에 대한 것도 Future로 처리 한 점도 훌륭했다. (나도 boost asio와 POSA2를 보고 변경하기 시작했지만 Netty의 비동기 패턴 적용 시점은 나보다 훨씬 빨랐다.)

적절한 사용 난이도와 확장성

굳이 프레임워크처럼 구현된 라이브러리와 비교하지 않더라도 C++에서 가장 범용적으로 쓰이는 네트워크 라이브러리인 boost asio에 비교했을 때 boost asio는 스레딩 제어를 비롯한 코어단 구현시 사용자의 선택에 따라 최적화 할 수 있게끔, 개발자가 직접 코딩하는 영광(?)을 안겨주고 학습 코스트도 함께 높였다.

즉 멀티 스레드에 대한 높은 이해와, boost asio API에 대한 높은 이해 (실제론 epoll이나 IOCP 개발을 해본 사람은 어느정도 이해할 수 있는 수준의 추상화긴 했다만은, 생각보다 처음 만져보는 사람들이 능수 능란하게 boost asio API를 사용하지 못한 경우를 많이 봤다.)를 필요로 하기에 궤를 달리한다.

내가 주로 사용하는 언어에 Netty와 같은 쉽게 사용할 수 있는 소켓 라이브러리가 존재한다는 것은 축복이며, Java진영이 Netty를 바탕으로 소켓 서버나 클라이언트가 필요한 수많은 라이브러리가 개발 코스트를 낮추어 많이 개발 될 수 있었다.

마치며

내가 내린 결론은 이런 부분마저 언어 철학의 차이가 아닌가 싶다.

C++은 선택지를 개발자에게 주어, 작은 부분까지 세심하게 결정하고 코스트를 다르게 가져갈 수 있게끔 하는 최적화에 큰 가치를 두는 문화이고, Java는 최적화의 여지가 줄어들 지언정 사용이 편하고 일정 수준 이상의 퍼포먼스를 내는 것에 큰 가치를 두는게 아닌가 싶다.

Netty를 사용한 경험이 내가 Java진영에서의 개발에 우호적인 생각을 갖게 된 첫 계기였다.