ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [세미나][Netty] 네트워크 프로그래밍 1
    세미나 2023. 1. 25. 22:32

     

     

     

    네트워크 프로그래밍

    네트워크로 연결된 둘 이상의 컴퓨터 사이에서의 데이터 송수신 프로그램의 작성을 의미한다.

    이때 소켓이라는 것을 기반으로 프로그래밍하기 때문에 소켓 프로그래밍이라고도 부른다.

    따라서 네트워크 프로그래밍을 할 때는 운영체제에서 소켓이라는 소프트웨어 모튤을 제공해주고 그것을 이용하여 프로그래밍을 한다. 소켓을 이용하면 내부적으로 어떻게 통신하는 지 정확하게 알지 못하더라도 컴퓨터끼리 네트워크 상에서 데이터를 주고 받을 수 있다.

     

    여기서 소켓의 동작 방식이 블로킹과 논블로킹 두 가지 모드로 나뉜다고 하는데 이건 조금 있다가 살펴보도록 하자.

     


     

    Netty는 NIO 기반의 네트워크 프로그래밍이기 때문에 Netty에 대해 살펴보기 전에 NIO가 뭔지 잠깐 보고 가도록 하자.

     

    네티가 나오기 이전에는 Java NIO를 이용했었다. 하지만 Java NIO만을 이용해서 네트워크 애플리케이션을 작성하는 일은 매우 어렵고 비효울적이기 때문에 예상치 못한 버그를 만들어 낼 수 있다.

    네티는 단순히 네트워크 동신과 관련된 기능을 제공할 뿐만 아니라 일반적으로 네트워크 애플리케이션에서 사용하는 다양한 기능들을 포함하고 있다. 덕분에 네트워크 프로그래밍이나 멀티스레드와 관련된 처리보다는 비즈니스 로직에 좀 더 집중할 수 있게 되었다.

    즉, 네티는 네트워크 애플리케이션을 빠르고 쉽게 개발할 수 있도록 다양하고 강력한 기능들을 제공한다.

     

    Java NIO(New Input Output)

    기존 IO패키지를 개선하기 위해 나온 패키지다.

     

    자바는 C/C++처럼 직접 메모리를 관리하고 OS레벨의 시스템 콜을 직접 사용하기는 어렵다.
    자바는 JVM 위에서 동작하므로 주로 C/C++에 비하면 느리다.
    자바가 특별히 성능이 좋지 않은 부분은 IO다. IO 성능 문제를 개선하는 것이 바로 java.nio 패키지다.

     

    기존 IO와 NIO의 차이

    구분 IO NIO
    입출력 방식 스트림 방식 채널 방식
    버퍼 방식 넌버퍼 버퍼
    비동기 방식 지원 안 함 지원
    블로킹/넌블로킹 방식 블로킹 방식만 지원 블로킹/넌블로킹 방식 모두 지원

     

    스트림 vs 채널

    IO는 스트림으로부터 한 번에 여러 바이트를 읽는다. 따라서 데이터를 읽거나 출력할 때 입력 스트림, 출력 스트림을 생성해야한다.

    NIO는 채널을 사용하여 양방향 입출력이 가능하기 때문에 입출력을 위한 별도의 채널을 생성할 필요가 없다.

     

    넌버퍼 vs 버퍼

    IO는 버퍼를 사용하지 않기 때문에 출력 스트림이 1바이트를 쓰면 입력 스트림이 1바이트를 읽는다. 이러한 방식은 속도가 느리다.

    NIO는 버퍼를 사용하여 채널에서 버퍼에 저장된 데이터를 출력하고 입력된 데이터를 버퍼에 저장한다. 따라서 데이터의 위치를 이동해 가면서 필요한 부분만 읽고 쓰는 것이 가능하다.

     

    블로킹과 논블로킹

    IO는 입력 스트림의 read()를 호출하면 데이터가 입력되기 전까지 스레드는 블로킹이 되고 출력 스트림의 write()를 호출하면 데이터 출력 전까지 스레드는 블로킹된다. 

    IO 스레드가 블로킹 되면 다른 일을 할 수 없고 블로킹을 빠져나오기 위해 인터럽트도 할 수 없다. 블로킹을 빠져나오는 방법은 스트림을 닫는 것이다.

    NIO는 블로킹과 넌블로킹 특징을 모두 가지고 있다. IO 블로킹과의 차이점은 NIO 블로킹은 스레드를 인터럽트 함으로써 빠져나올 수가 있다는 것이다.

    NIO의 논블로킹은 입출력 작업 준비가 완료된 채널만 선택해서 작업 스레드가 처리하기 때문에 작업 스레드가 블로킹 되지 않는다. NIO 넌블로킹의 핵심 객체는 멀티플렉서인 Selector이다. 셀렉터는 복수 개의 채널 중에서 이벤트가 준비 완료된 채널을 선택하는 방법을 제공해준다.

     

    selector

    Java NIO Selector는 하나의  스레드가 여러 개의 input channel을 모니터링 하는 것이 가능하다.

    이러한 메커니즘으로 단일 스레드에서 여러 채널을 쉽게 관리가 가능하다.

     

    IO vs NIO

    NIO는 다수의 연결이나 파일들을 논블로킹이나 비동기 처리할 수 있어서 많은 스레드 생성을 피하고 스레드를 효과적으로 재사용한다는 장점이 있다. 그래서 NIO는 연결 수가 많고 하나의 입출력 처리 작업이 오래 걸리지 않는 경우에 사용하는 것이 좋을 것이다. 스레드에서 입출력 처리가 오래 걸린다면 대기하는 작업의 수가 늘어나게 되므로 장점이 사라진다.

     

    많은 데이터 처리의 경우 IO가 좋을 수 있다.  NIO는 버퍼 할당 크기가 문제가 되고, 모든 입출력 작업에 버퍼를 무조건 사용해야 하므로 즉시 처리하는 IO부다 성능 저하가 있을 수 있다. 연결 클라이언트 수가 적고 전송되는 데이터가 대용량이면서 순차적으로 처리될 필요성이 있는 경우 IO로 구현하는 것이 좋은 선택일 수 있다.

     


     

    Netty란?

    비동기 이벤트 기반 네트워크 프레임워크이고, 유지 관리가 용이한 고성능 프로토콜 서버와 클라이언트를 신속하게 개발할 수 있도록 한다.

     

     

    Netty를 왜 쓰는가?

    네티는 적절한 추상화 모델을 제공하기 때문에 간단한 코드 작성만으로 안정적이고 빠른 네트워트 애플리케이션을 개발할 수 있게 도와준다.

     


     

    Netty의 주요 키워드

    • 비동기
    • 이벤트 기반
    • 고성능
    • 추상화

     

    동기 VS 비동기

    동기식 호출 

    특정 서비스를 호출하면 완료될 때까지 그 응답을 기다리는 방식

    -> 함수 결과를 호출한 쪽에서 처리하므로 쉬운 디버깅과, 직관적인 흐름 추적이 가능하다.

    -> 서비스가 종료될 때까지 호출자가 마냥 기다려야 하므로 컴퓨팅 자원을 비효율적으로 사용

     

    비동기식 호출

    서비스를 호출한 후 즉시 응답을 받고, 다른 작업을 하다가 처리가 완료되었는지 확인하여 결과를 받는 방식

    -> 함수의 결과를 호출한 쪽에서 처리하지 않는다. 

    -> 요청 결과를 기다리는 시간에 다른 작업을 수행할 수 있으므로 효율적으로 자원을 사용

     

    => 동기, 비동기는 함수 또는 서비스의 호출 방식을 뜻함.

     

    블로킹 VS 논블로킹

    블로킹

    요청한 작업이 성공하거나 에러가 발생하기 전까지는 응답을 돌려주지 않는다.

    => 호출된 메소드의 작업이 끝날때 까지 호출한 메소드에게 제어권을 넘겨주지 않고 대기하게 만든다면 블로킹이다.

     

    논블로킹

    요청한 작업의 성공 여부와 상관없이 바로 결과를 돌려준다.

    => 어떤 메소드 실행 과정에서 다른 메소드를 호출한다고 해도, 호출된 메소드의 완료 여부와 상관 없이 바로 제어권을 다시 넘겨받아 호출한 메소드가 계속해서 다른 작업을 처리할 수 있도록 한다.

     

    그래서 동기 / 비동기와 블로킹 / 논블로킹이 다른 점은 뭘까?

    동기와 비동기는 호출되는 함수의 작업 완료 여부를 누가 신경쓰냐에 초점

    => 함수의 작업 완료를 호출한 함수가 신경을 쓰면 동기, 함수의 작업 완료를 호출된 함수가 신경쓰면 비동기

     

    블로킹과 논블로킹은 호출되는 함수가 바로 리턴하느냐 마느냐에 초점

    => 호출된 함수가 바로 리턴하지 않고, 제어권을 가지고 있으면서 해당 함수가 종료될 때 제어권을 넘긴다면 블로킹, 호출된 함수가 완료되지 않아도 제어권을 바로 호출한 함수에게 넘긴다면 논블로킹

     

    이벤트 기반 프로그래밍

    프로그래밍 패러다임 중 하나로 프로그램의 흐름이 특정 이벤트에 따라 결정되는 것을 말한다.

    이벤트 기반 프로그래밍은 전통적으로 사용자 인터페이스가 포함된 프로그램에 많이 사용된다.

    예를 들어 마우스 클릭에 반응하는 코드가 이에 해당된다. 이와 같이 이벤트 기반 프로그래밍은 각 이벤트를 먼저 정의해두고 발생한 이벤트에 따라서 코드가 실행되도록 프로그램을 작성한다.

     

     

    추상화 수준

    이벤트를 나눌 때 작은 단위로 나누었는지 큰 단위로 나누었는지의 정도를 말한다.

    이벤트의 추상화가 너무 고수준이면 세부적인 제어가 힘들어지고, 반대로 매우 저수준으로 추상화하면 한 동작에 대해서 너무 많은 이벤트가 발생하여 애플리케이션 성능에 악영향을 미치게 된다.

    => 서버에 연결될 클라이언트의 수는 매우 가변적이며 예측 불가능하므로 이벤트 기반 프레임워크의 적절한 추상화 단위는 매우 중요하다.

     

    이벤트 기반 네트워크 프로그래밍

    네티를 사용하지 않은 네트워크 프로그램에서 이벤트 발생 주체는 '소켓'이며, 이벤트 종류는 소켓연결, 데이터 송수신이다.

    소켓에 데이터를 기록하고 읽으려면 소켓 채널(NIO) 또는 스트림을 사용한다.

    클라이언트 애플리케이션이 소켓에 연결된 스트림에 데이터를 기록하면 소켓이 해당 데이터를 인터넷으로 연결된 서버로 전송한다. 이때 소켓에 문제가 발생하거나 연결된 스트림에 문제가 발생하면 새로운 소켓을 생성하고 데이터를 전송하는 예외 처리 코드가 작동되어야 할 것이다. 언제 어떠한 문제가 발생할 지 모르기 때문에 수신 대기 상황에서의 오류, 연결 시도 중 오류 등 다양한 상황에 대한 예외처리를 만들어야 한다. 이는 코드의 중복을 만들게 된다.

     

    네티를 사용한다면 데이터를 소켓으로 전송하기 위해서 채널에 직접 기록하는 것이 아니라 데이터 핸들러(=이벤트 핸들러)를 통해서 기록하기 때문에 이벤트에 따라서 로직을 분리하는 장점과 코드를 재사용할 수 있다는 장점이 생긴다. 또한 네티의 이벤트 핸들러로 에러 이벤트도 정의할 수 있다.

     


    친구에게 위 내용들을 설명하면서 아래의 질문을 받았다.

     

    왜 비동기식이 좋다고 하면서 동기식을 사용하는 이유는 무엇일까?

     

    단순히 용도에 따라 필요한 방식을 사용하기 때문이라는 결론이 났다.

     

    예를 들어 엑셀 파일을 비동기식으로 처리한다고 생각해보자.

    한 엑셀 파일을 다수의 작성자가 수정을 한다면?

    한 명의 작성자가 작성을 완료하지 않았는데 다른 작성자가 내용을 고쳐버린다면?

    아마 엑셀 내용들이 뒤죽박죽 될 것이다.

     

    그러니까 프로그램에 따라서 동기나 비동기 방식 중에서 알맞은 방식을 사용하는게 맞는 것 같다. 


    참고

     

    자바 NIO

    feat. 친구의 팩폭 | 자바는 어디서 느릴까? 일단 자바는 C/C++과 달리 직접 메모리를 관리하고 OS 레벨의 시스템 콜을 직접 사용하기는 어렵다. JNI를 사용하는것은 여기서는 배제하도록 하자. 자

    brunch.co.kr

     

     

    Netty의 주요 특징 - 비동기, 이벤트 기반

    Netty는 비동기 이벤트 기반 네트워크 애플리케이션 프레임워크로써 유지보수를 고려한 고성능 프로토콜 서버와 클라이언트를 빠르게 개발할 수 있다. Netty 홈페이지에는 Netty를 위와 같이 정의

    deep-dive-dev.tistory.com

     

     

    [ 네티 인 액션 ] 1. 네티: 비동기식 이벤트 기반 네트워킹 프레임워크

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

    velog.io

     

     

     

    자바 네트워크 소녀 Netty 정리

    1장에서는 본격적으로 네티의 개념에 대해 알아보기 전, 간단한 echo 서버, 클라이언트를 구현해본다.그냥 자바의 소켓 프로그래밍을 통해 구현하는 것에 비해 네티의 추상화로 인해 얼마나 편하

    velog.io

     

Designed by Tistory.