느린 것을 걱정하지 말고, 멈춰서는 것을 걱정하라

음,, 카프카를 공부하려니 주키퍼에 대한 내용이 많이 나오고 주키퍼를 공부하니,,, 갖고있는 라이브러리에 네티를 사용하기에 네티를 공부하고, 주키퍼, 카프카를 다시공부하여 지식의 질을 높이기 위해 공부를 시작한다. 이번에 공부하는 책은 네티 인 액션이다. 

 

네티 (netty.io)
네티는 유지 관리가 용이한 고성능 프로토콜 서버와 클라이언트를 신속하게 개발하기 위한 비동기식 이벤트 기반 네트워크 애플리케이션 프레임워크이다.    

고성능 프로토콜 서버와 클라이언트라,, 감이 안잡히지만 일단 읽는다,, 나중에 코드를 작성하다 보면 언젠간 이해하게 되지 않을까?

 

 

고성능 시스템은 단순히 높은 수준의 코딩 기술 뿐만이 아니라 네트워킹, 멀티스레딩, 동시성을 비롯한 여러 복잡한 분야에 대한 전문 기술을 필요로 한다. 네티는 이 도메인 지식을 네트워킹 초심자도 이용할 수 있도록 한곳으로 모았다.

 

자바의 네트워킹

자바 초기 시절(1995 ~ 2002)부터 까다로운 세부 사항을 감추기 위한 객체 지향 파사드가 적지 않게 선보였지만, 복잡한 클라이언트/ 서버 프로토콜을 제작하려면 여전히 많은 양의 보일러플레이트 코드를 작성해야 했고, 모든 사항이 매끄럽게 작동하게 하려면 틈틈이 내부를 들춰봐야 했다. 

 

이러한 최초의 자바 API는 네이티브 시스템 소켓 라이브러리가 제공하는 이른바 블로킹 함수만 지원했다. 옛날에 학부시절 자바 채팅프로그램을 만들때, 새로운 socket을 받기위해 끊임없이 기다리는 상태, 그리고 메시지를 전달할때까지 연결된 소켓도 기다리는 상태. 이 상태를 블로킹 되었다고 말하는 듯 하다.

 

이러한 코드의 문제(블로킹 함수를 쓰는 문제를 말하는듯)는 다음과 같다.

  1. 여러 스레드가 입력이나 출력 데이터가 들어오기를 기다리며 무한정 대기 상태로 유지될 수 있다.

  2. 각 스레드가 스택 메모리를 할당해야 하는데, 운영체제에 따라 다르지만 스택의 기본 크기는 64kb, 1mb까지 차지할 수 있다. (접속자가 많아지면 소켓 오브젝트가 많이 생성되고 이것들은 각각의 스레드로 관리되어야 하는데, 이러할 경우 많은 메모리를 차지할 수 있겠단 생각을 한다.)

  3. 셋째, JVM이 물리적으로 아주 많은 수의 스레드를 지원할 수 있지만, 동시 접속이 한계에 이르기 훨씬 전부터 컨텍스트 전환에 따른 오버헤드가 심각한 문제가 될 수 있다.

 

자바 NIO

블로킹 시스템 호출 방식 외에도 네이티브 소켓 라이브러리에는 오래전부터 네트워크 리소스 사용률을 세부적으로 제어할 수 있는 논블로킹 호출이 포함돼 있다.

 

셀렉터

java.nio.channels.Selector 클래스는 자바의 논블로킹 입출력 구현의 핵심으로서, 논블로킹 Socket의 집합에서 입출력이 가능한 항목을 지정하기 위해 이벤트 통지 API를 이용한다.

  • 적은수의 스레드로 더 많은 연결을 처리할 수 있으므로 메모리 관리와 컨텍스트 전환에 따르는 오버헤드가 감소한다.
  • 입출력을 처리하지 않을 때는 스레드를 다른 작업에 활용할 수 있다.

직접 자바 NIO API를 이용해 제작하는 애플리케이션도 많지만 이 작업을 올바르고 안전하게 하기는 아주 어렵다. 특히 부하가 높은 상황에서 입출력을 안정적이고 효율적으로 처리하고 호출하는 것과 같이 까다롭고 문제발생 위험이 높은 일은 네티와 같은 고성능 네트워킹 전문가에게 맡기는게 좋다. (자바 NIO를 잘 사용하기가 어려운데 이를 쉽게 해주는 툴이 네티인듯 하다.)

 

네티 소개

 저수준 API를 직접 이용하면 복잡성이 심화되며, 구하기 어려운 특수한 고급 인력에 대한 의존성이 높아진다는 사실을 그간의 길고 고통스러운 경험을 통해 알고 있다. 따라서 기반 구현의 복잡성을 단순한 추상화(복잡한 기능을 간단하게 사용하되 그 기능에 대한 구현은 몰라도 되는 개념인듯)로 감추는 객체 지향의 기본 개념을 도입해야 한다.

 

이 기본 원칙은 특히 분산 시스템 개발 분야에서 공통적인 프로그래밍 작업을 위한 솔루션을 캡슐화하는 다양한 프레임워크의 개발 동기가 됐다. 전문 개발자라면 적어도 이러한 하나 이상의 프레임워크에 익숙하다고 가정해도 좋을 것이다. 

 

네티는 네트워킹 도메인에서 가장 유명한 자바용 프레임워크다. 네티는 사용하기 쉬운 API를 전면에 내세우고 자바의 고급 API 로 내부를 무장함으로써 개발자에게 중요한 각 애플리케이션의 고유 영역에 집중하게 해준다. 

 

범주

네티의 특징

설계

단일 API로 블로킹과 논블로킹 방식의 여러 전송 유형을 지원. 단순하지만 강력한 스레딩 모델. 진정한 비연결 데이터그램 소켓 지원. 재사용 지원을 위한 논리 컴포넌트 연결

이용 편이성

자세한 Javadoc과 광범위한 예제. J아 1.6+을 제외한 추가 의존성 없음.(일부 옵션 기능을 이용하려면 자바 1.7+ 및/ 또는 추가 의존성이 필요할 수 있음)

성능

코어 자바 API보다 높은 처리량과 짧은 지연 시간. 풀링과 재사용을 통한 리소스 소비 감소. 메모리 복사 최소화

견고성

저속, 고속 또는 과부하 연결로 인한 OutOfMemoryError가 발생하지 않음. 고속 네트워크 상의 I/O 애플리케이션에서 일반적인 읽기/쓰기 비율 불균형이 발생하지 않음.

보안

완벽한 SSL/TLS 및 StartTLS 지원. 애플릿이나 OSGi 같은 제한된 환경에서도 이용 가능.

커뮤니티 주도
개발

빨리 그리고 자주 릴리스됨

 

비동기식 이벤트 기반 네트워킹

 

 비동기, 즉 동기화되지 않은 이벤트는 사실 우리에게 아주 익숙하다. 좋은 예로 이메일이 있다. 보낸 메시지의 답장이 바로 올수도 있지만 답장이 없는 경우도 있고, 메시지를 보내는 동안 예기치 않은 메시지를 받을 수도 있다.

 또한 비동기 이벤트는 정돈된 관계를 가질 수 있다. 일반적으로 답변은 질문한 사항에 대해서만 받을 수 있고, 답변을 기다리는 동안 다른 일을 할 수 도 있다.

  • 논블로킹 네트워크 연결은 작업 완료를 기다릴 필요가 없게 해준다. 완전 비동기 입출력은 이 특징을 바탕으로 한 단계 더 나아간다. 비동기 메서드는 즉시 반환하며 작업이 완료되면 직접 또는 나중에 이를 통지한다.

  • 셀렉터는 적은 수의 스레드로 여러 연결에서 이벤트를 모니터링 할 수 있게 해준다. 

 

네티의 핵심 컴포넌트

  • Channel

  • 콜백

  • Future

  • 이벤트와 핸들러

이러한 구성 요소는 리소스, 논리, 알람이라는 각기 다른 종류의 구조를 나타낸다. 

 

Channel

 

 하나 이상의 입출력 작업(예: 읽기 또는 쓰기)을 수행할 수 있는 하드웨어 장치, 파일, 네트워크 소켓, 프로그램 컴포넌트와 같은 엔티티에 대한 열린 연결

 일단 Channel을 들어오는(인바운드) 데이터와 나가는(아웃바운드) 데이터를 위한 운송수단이라고 생각한다. Channel은 열거나 닫고, 연결하거나 연결을 끊을 수 있다.

 

 

콜백

 

콜백은 간단히 말해 다른 메서드로 자신에 대한 참조를 제공할 수 있는 메서드다. 다른 메서드에서는 이 참조가 가리키는 메서드를 필요할 때 호출할 수 있따. 콜백은 광범위한 프로그래밍 상황에서 이용되며 관심 대상에게 작업 완료를 알리는 가장 일반적인 방법중 하나다.

 

 

Future

 

Future는 작업이 완료되면 이를 애플리케이션에 알리는 한 방법이다. 이 객체는 비동기 작업의 결과를 담는 자리표시자 역할을 하며, 미래의 어떤 시점에 작업이 완료되면 그결과에 접근할 수 있게 해준다. 

 

JDK는 java.util.concurrent.Future 인터페이스를 제공하지만, 제공되는 구현에는 수동으로 작업 완료 여부를 확인하거나 완료되기 전까지 블로킹하는 기능만 있다. 그래서 네티는 비동기 작업이 실행됐을 때 이용할 수 있는 자체 구현 ChannelFuture를 제공한다. 

 

 

이벤트와 핸들러

 

네티는 작업의 상태 변화를 알리기 위해 고유한 이벤트를 이용하며, 발생한 이벤트를 기준으로 적절한 동작을 트리거할 수 있다. 다음과 같은 동작이 포함된다.

  • 로깅

  • 데이터 변환

  • 흐름 제어

  • 애플리케이션 논리

 

인바운드 데이터나 연관된 상태 변화로 트리거되는 이벤트는 다음을 포함한다.

  • 연결 활성화 또는 비활성화

  • 데이터 읽기

  • 사용자 이벤트

  • 오류 이벤트


책의 내용을 정리하면서, 중요하다고 생각된 부분을 옮겨 적었다. 또한 내 생각에 대해서는 초록색으로 약간 주석(?) 처럼 글을 작성해 놓았는데, 솔직히 잘 이해가 되지 않는다. 옛날, 어떤 사람이 말해준 백문이 불여 일타라고 하지 않았던가. 일단 네티를 사용해 가면서, 위에서 말한 장점들에 대해 느낌적인 느낌으로 받아들이도록 하자.

profile

느린 것을 걱정하지 말고, 멈춰서는 것을 걱정하라

@주현태

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!