Spring/Spring Framework

[Netty] Netty가 뭐에요? - 7탄 : 공식 문서 - Core 정리 및 Tansport Services 탐방

공대키메라 2025. 12. 1. 23:56

지난 시간에는 Netty에서 제공하는 Echo 예제를 보았다. (지난 글 여기 클릭!)

 

사실 글 길이는 별거 안되어 보이지만 변명(?)을 하자면 이걸 어떻게 구성을 하는게 내가 이해가 더 잘될지 고민했기 때문이다.

 

또 단순히 코드를 탐방하는 경우, 흐름을 주석으로 정리한 것을 접어버리다 보니 상대적으로 양은 적어보였다.

 

현재는 Netty의 모든 것을 한 번에 뜯어볼 수 는 없으니, 현재 차근차근 뜯어보고 있는 상황이다.

 

그러면 다시 ... 핵심 구조를 다시 보고 가자.

출처 : https://netty.io/index.html

 

이미 우리는 Zero-Copy-Capable Rich Byte Buffer에 대해서 공부했다. (Rich Byte Buffer 내용은 여기!)

 

이번에는.. Universal Communication API와 Extensible Event Model이 정확히 뭘 의미하는지 알아가려고 한다.

 

또 이거와 추가해서 그러면 Transport Services는 어떻게 지원을 하는건지 찾아보려고 한다.

 

사실 이것들도 이전 글을 열심히 봐왔으면 무엇을 의미하는건지 알 것이다.(정리한 나도 여태 몰랐음 사실 ㅎ)

 

1. Universal Communication API(범용 통신 API )

이것은 어느 곳에 해당할까?

 

Netty가 말하는 “범용 통신 API”는 우리가 이미 봤는데, Channel인터페이스를 중심으로 통신을 하던 사실을 기억할 수 있다.

 

channel안에 파이프라인이 하나씩 있는데, 이것을 어느 Handler로 관리를 하고 

  • Channel 인터페이스를 중심으로
  • ChannelPipeline
  • ChannelHandler
  • ChannelFuture
  • Bootstrap, ServerBootstrap

이런 것들을 한 세트로 묶은 공통 통신 인터페이스 층이라고 볼 수 있다.

 

우리는 이미 Netty에서 제공하는 기능들을 잘 이용해서 범용 통신을 할 수 있다.

 

TCP/NIO/epoll/UDP/local 등 전송 방식이 뭐가 되든

애플리케이션 코드는 항상 Channel과 핸들러/파이프라인 API만 사용하게 만드는 레이어가 

Core의 Universal Communication API 레이어다.

 

이와 관련된 부분을 이전에 탐방을 했다. (channel 관련 글 클릭!)

 

2. Extensible Event Model(확장 가능한 이벤트 모델)

큰 흐름을 다시 정리해보면 다음과 같다.

 

1. Channel을 통해 통신한다

2. 이를 Event로 등록한다.


Channel은 내부적으로 EventLoop에 등록되어 I/O 이벤트를 받을 준비를 한다.


우리는 그 Channel의 이벤트를 처리할 Handler를 Pipeline에 등록한다.


EventLoop는 Channel을 이벤트 소스로 등록해 두고 I/O 이벤트를 감시하게 된다.

 


이것을 확장 가능한 이벤트 모델로 만들었다는 말이다.

 

 

그러니까, 다양한 Handler 를 쉽게 등록하고 이를 관리하면 "확장 가능한 이벤트 모델" 이지 아니한가?

 

 

이게 글을 범용적으로 정리하게 되면 이것이 위처럼 표현이 된 것이다.

 

근데 여태 학습한 것을 복기해보면 잘 정리된 것이라고 느낄수 있다.

 

3. Transport Services Layer 알아보기

예시를 더 보고 더 익숙해야야 할 테지만 어찌되었든 Core부분은 대충 본 것 같다.

 

그러면 Transport Services는 무엇인지 찾아보려고 한다.

 

Socket & Datagram, HTTP Tunnel, In-VM Pipe가 적혀있다.

 

 

Socket & Datagram

  • OS가 제공하는 TCP/UDP 소켓을 Netty가 감싸서 (NioSocketChannel, NioDatagramChannel 등) 사용

 

HTTP Tunnel

  • HTTP 기반 통신(프록시/CONNECT/WebSocket 등)을 “전송 수단”처럼 써서 그 위에 다른 데이터/프로토콜을 실어 나르는 방식

 

In-VM Pipe

  • 네트워크 안 타고, 같은 JVM 안에서만 쓰는 가상 채널 (LocalChannel, LocalServerChannel)

 

위 설명들은 사실 GTP에게 알려달라했다. 큰 그림을 그리는것은 AI가 잘 하지만, 내부적으로 어떻게 코드가 작성이 되어 있고

 

무슨 기능을 쓰는건지는 사람이 이해를 해서 써야하니 직접 찾는게 맞다고 생각하기에, 

 

차근차근 어느 부분들이, 어떻게 정리가 되어 있는지 알아보려고한다.

 

3.1) Socket & Datagram

우선은 Socket 과 Datagram을 지원한다는데, 용어부터 다시 집고 넘어가겠다.

  • Socket = 보통 TCP 소켓 (스트림, 연결 지향)
  • Datagram = UDP 데이터그램 (패킷, 비연결)

본격적으로 io.netty.channel.socket패키지를 봐보면 다음과 같이 설명이 있다.

 

core 채널 API를 확장한 추상 TCP와 UDP 소켓 인터페이스

 

그리고 내부를 보면 위에서 본 Socket~ 뭐시기 interface, Datagram 뭐시기 interface

그리고 클래스에서는, 그 흔한 Packet관련 이름도 볼 수 있다.

 

말 그대로 뭔가... 네트워크 연결을 도와주는 기능들이 연상이 된다. 

 

여기서 소켓의 의미를 다시 떠올려보자. 소켓은 말 그대로 창구 혹은 출입문으로 생각하면 될 듯 한데, 

 

네트워크망으로 데이터를 내보내거나, 네트워크망에서 데이터를 받기 위한 창구(Endpoint)를 의미한다.

 

 

그렇다면 우리가 지금 사용하려는 Netty의 소켓 기능들을 생각해보면

 

TCP 연결이나 UDP 통신 그 자체를 추상화한 부품들이 모여있는 곳을 io.netty.channel.socket 패키지로 볼 수 있다.

 

여기서 필자는 NioSocketChannel을 주목했다.

 

 

io.netty.channel.socket.nio.NioSocketChannel.class 는 io.netty.channel.socket.SocketChannel.class의 구현체인데, 

 

내부적으로 사용중인 SocketChannel은 또 java의 nio Channel이다.

 

해당 캡쳐본의 출처는 다음과 같다.

출처: Netty 프로젝트
파일: io.netty.channel.socket.nio.NioSocketChannel.java 일부
라이선스: Apache License 2.0
원본: https://netty.io/4.1/api/io/netty/channel/socket/nio/NioSocketChannel.html

 

캡쳐한 부분을 보면 내부가 Socket Channel를 사용하고 있다.

 

필자가 헷갈렸던 부분은 같은 이름인데 왜 Netty 에서 따로 만든것도 사용하면서 java.nio 에서 만든 것을 사용하는가였다.

 

JDK 쪽의 java.nio.channels.SocketChannel를 정라하면 다음과 같다.

  • 추상 클래스(abstract class)
  • OS의 TCP 소켓이랑 붙어 있는 저수준 I/O 채널
  • read(ByteBuffer), write(ByteBuffer) 같은 순수 I/O API 위주
  • Selector에 등록되고, 네이티브 코드까지 이어지는 계층

즉  “커널 소켓이랑 직접 통신하는 JDK 레벨 채널”이라고 보면 된다.

 

Netty 쪽의 io.netty.channel.socket.SocketChannel은 다음과 같다.

  • 인터페이스(interface)
  • Netty 세계에서의 “TCP 소켓 채널” 추상화
  • Channel을 상속해서 이런 것들을 더 가지고 있음:
    • pipeline()
    • eventLoop()
    • config()
    • isActive()
    • writeAndFlush() … 등

NioSocketChannel은 nio의 SocketChannel와 Netty 의 SocketChannel 둘을 이어주는 역할을 한다.

 

Netty에서 정의한 SocketChannel(인터페이스)을 통해 Netty의 Channel 혹은 Pipeline 같은 기능을 공통된 방식으로 사용할 수 있는데,

 

NIO 기반 구현인 NioSocketChannel의 경우, 내부적으로 java.nio.channels.SocketChannel을 이용해 실제 저수준 I/O를 처리한다.

 

어찌보면 Adapter패턴과 가까운데, “내가 쓰고 싶은 인터페이스이미 존재하는 구현체의 인터페이스가 다를 때, 중간에 어댑터를 하나 둬서 내가 원하는 모양으로 감싸는 것" 이기 때문이다.

 

 

그런데 Adapter 패턴의 장점은 뭘까?

 

아무래도 원본의 코드를 건드리지 않고 확장할 수 있겠지? 

 

본좌(?)는 이것밖에 생각할 수 없었지만... 이럴때를 위해 AI를 사용하는거 아니겟는데? 다음과 같이 정리가 된다.

 

잼민이! 가 아니 제미나이! 너만 믿는다!

 

  • 유연한 교체 (Pluggability) 코드는 그대로 두고, 설정만 바꾸면 일반 소켓(NIO)에서 고성능 리눅스 전용 소켓(Epoll)으로 엔진을 즉시 갈아끼울 수 있습니다.
  • 안정성 확보 (Stability) JDK 자체의 치명적인 버그나 복잡한 사용법을 Netty가 내부에서 다 처리해 줘서, 개발자는 안전하게 쓸 수 있습니다.
  • 기능 확장 (Extensibility) 단순 입출력만 되는 JDK 소켓과 달리, Pipeline(로직 연결), Future(비동기 결과), Attribute(데이터 저장) 같은 강력한 부가 기능을 바로 쓸 수 있습니다.
  • 테스트 편의성 (Testability) 실제 네트워크 연결 없이도 가짜 소켓(EmbeddedChannel)을 껴서 내 로직만 따로 테스트하기 쉽습니다.

 

라고~ 한다.

 

3.2)  HTTP Tunnel

해당 정보를 이해하기 위해서 리버스 프록시, 포워드 프록시를 이해하면 좋다.

 

기본적으로 프록시란 '대리자' 라는 의미를 가지고 있으며, 김영한씨 강의를 보면 어머니와 라면 이야기로 예시를 든다.

 

어머니가 나대신 라면을 끓여준다면, 어머니는 프록시 역할을 하는 것이다. (엄마 미안해! 쌉하남자라서 ㅠㅠ)

 

여기서 프록시 서버는 그럼 뭔가? 나 대신에 일을 처리해주는 서버이다.

 

이를 클라이언트와 인터넷 사이에 두면 포워드 프록시로 특정 사이트를 접근 제한한다.

 

다르게 인터넷과 서버 사이에 두면 리버스 프록시로 로드밸런싱, 서버 보안 그리고 캐싱같은 부가 작업을 추가할 수 있다.

 

 

원래는 그냥 TCP 같은 소켓으로 통신하고 싶지만, 방화벽·프록시·네트워크 정책 때문에 직접 소켓 통신이 막혀 있을 때,
HTTP(혹은 HTTP처럼 보이는 트래픽)를 “통로(터널)”로 삼아서 그 안에 다른 데이터나 프로토콜을 실어 보내는 방식을 말한다.

 

터널은 중간에 뭐가 있든 간에 양 끝단 A ↔ B 를 직선으로 이어주는 “관(管)” 하나를 뚫어 놓은 것으로 볼 수 있는데,
그 안에 뭐가 흐르는지는 중간에 있는 애들이 뭐가 있는지는 확인이 불가능하다.

 

Netty에서는 HTTP 터널을 만들기 위해 HttpProxyHandler를 지원한다.

 

이 핸들러는 HTTP/1.1 CONNECT 요청을 사용하여 블라인드 포워딩 프록시 터널(Blind Forwarding Proxy Tunnel)을 생성한다. 이를 통해 평문(plaintext) 또는 보안 터널을 연결할 수 있다.

터널링 프록시 대신에 메시지 포워딩 HTTP 프록시 에이전트를 연결해야하는 HTTP 사용자들은 이 핸들러를 사용하면 안된다.

출처 : https://netty.io/4.1/api/io/netty/handler/proxy/HttpProxyHandler.html

 

 

공식 문서의 설명을 보면, 포워딩 프록시 터널을 생성한다고 한다.

 

Blind Forwarding Proxy Tunnel?? 이게 뭔데? 그리고 자세히 보면 HTTP/1.1 CONNECT 가 바로가기가 되어 있는데 눌러보면 

 

https://datatracker.ietf.org/doc/html/rfc7231#section-4.3.6이 주소의 4.3.6. CONNECT 로 이동하게 된다. 

 

아니 이게 뭔상관인데 갑자기;;

 

해당 글의 번역을 여기 넣어놓겠다. 번역은 제미나이가 해줬다.

더보기

[RFC 7231] 4.3.6. CONNECT

CONNECT 메서드는 수신자(프록시)에게 요청 타겟(request-target)으로 식별된 목적지 원본 서버로 향하는 터널을 수립할 것을 요청합니다.

 

그리고 연결이 성공하면, 그 이후부터는 터널이 닫힐 때까지 양방향으로 패킷을 맹목적으로 전달(blind forwarding)하는 것으로 자신의 행동을 제한할 것을 요청합니다.

 

터널은 일반적으로 하나 이상의 프록시를 거쳐 종단 간(end-to-end) 가상 연결을 생성하는 데 사용되며, 이 연결은 이후 TLS(전송 계층 보안, [RFC5246])를 사용하여 보안될 수 있습니다.

 

CONNECT는 오직 프록시에 대한 요청에 사용하도록 의도되었습니다. 자신에 대한 CONNECT 요청을 받은 원본 서버는 연결이 수립되었음을 알리기 위해 2xx (성공) 상태 코드로 응답할 수는 있습니다(MAY). 그러나 대부분의 원본 서버는 CONNECT를 구현하지 않습니다.

 

CONNECT 요청을 보내는 클라이언트는 반드시 authority 형식의 요청 타겟을 보내야 합니다 (RFC7230의 5.3절 참조). 즉, 요청 타겟은 콜론으로 구분된 터널 목적지의 호스트 이름과 포트 번호로만 구성됩니다. 예를 들면 다음과 같습니다:

 

HTTP
 
CONNECT server.example.com:80 HTTP/1.1
Host: server.example.com:80

수신 프록시는 요청 타겟에 직접 연결하거나, 만약 다른 프록시를 사용하도록 설정된 경우 CONNECT 요청을 다음 인바운드 프록시로 전달함으로써 터널을 수립할 수 있습니다.

 

모든 2xx (성공) 응답은 발신자(및 경로 상의 모든 인바운드 프록시들)가 성공 응답의 헤더 섹션을 끝내는 빈 줄(blank line) 직후에 즉시 터널 모드로 전환될 것임을 나타냅니다. 그 빈 줄 이후에 수신된 데이터는 요청 타겟에 의해 식별된 서버(목적지)로부터 온 것입니다.

 

성공 응답 이외의 모든 응답은 터널이 아직 형성되지 않았으며, 연결이 여전히 HTTP에 의해 제어됨을 나타냅니다.

 

터널의 중개자(intermediary)가 양쪽 중 어느 한쪽이 연결을 닫은 것을 감지하면 터널은 닫힙니다. 이때 중개자는 닫힌 쪽에서 온 미전송 데이터(outstanding data)를 반대쪽으로 보내려고 시도해야 하며(MUST), 그 후 양쪽 연결을 모두 닫고, 전달되지 않고 남은 데이터는 폐기해야 합니다.

 

터널 생성 권한을 확립하기 위해 프록시 인증이 사용될 수 있습니다. 예를 들면 다음과 같습니다:

 

HTTP
 
CONNECT server.example.com:80 HTTP/1.1
Host: server.example.com:80
Proxy-Authorization: basic aGVsbG86d29ybGQ=

임의의 서버로 터널을 수립하는 데는 상당한 위험이 있습니다. 특히 목적지가 웹 트래픽용이 아닌 잘 알려진 포트나 예약된 TCP 포트일 때 더욱 그렇습니다.

 

예를 들어, "example.com:25"라는 요청 타겟으로 CONNECT를 보내는 것은 프록시가 SMTP 트래픽용 예약 포트에 연결하도록 제안하는 것입니다. 만약 이것이 허용된다면, 프록시를 속여 **스팸 메일을 릴레이(중계)**하게 만들 수 있습니다.

 

따라서 CONNECT를 지원하는 프록시는 알려진 포트의 제한된 집합이나, 안전한 요청 타겟으로 구성된 설정 가능한 화이트리스트로 그 사용을 제한해야 합니다(SHOULD).

 

서버는 CONNECT에 대한 2xx (성공) 응답에 Transfer-Encoding이나 Content-Length 헤더 필드를 보내면 안 됩니다(MUST NOT). 클라이언트는 CONNECT에 대한 성공 응답에서 받은 Content-Length나 Transfer-Encoding 헤더 필드를 무시해야 합니다(MUST).

 

CONNECT 요청 메시지 내의 페이로드(본문)는 정의된 의미(semantics)가 없습니다. CONNECT 요청에 페이로드 바디를 보내면 일부 기존 구현체들이 요청을 거부할 수 있습니다.

 

CONNECT 메서드에 대한 응답은 캐시할 수 없습니다(not cacheable).


도통 왜 이러한 설명을 한건지...

 

결국 Netty 내부에서 외부 API 요청을 할 때, HTTP 연결을 위해서 해당 클래스를 사용하는 것으로 보인다.

 

이해를 못하겠으니 HttpProxyHandler의 사용법을 알아보겠다.

 

NettyProxyExample.java

package com.example.study.netty.httpproxyhandler;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.http.*;
import io.netty.handler.proxy.HttpProxyHandler;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;

import java.net.InetSocketAddress;

public class NettyProxyExample {

    // 1. 목적지: 무료 에코 서버 (HTTPS)
    static final String DEST_HOST = "postman-echo.com";
    static final int DEST_PORT = 443;

    // 2. 경유지: 프록시 서버 정보 (★ 본인 환경에 맞게 수정 필요)
    // 테스트하려면 Fiddler, Charles 같은 로컬 프록시를 켜두거나 실제 사내 프록시 IP 입력
    static final String PROXY_HOST = "127.0.0.1";
    static final int PROXY_PORT = 8888;

    public static void main(String[] args) throws Exception {
        // HTTPS 통신을 위한 SSL 컨텍스트 (테스트용으로 인증서 검증 무시)
        SslContext sslCtx = SslContextBuilder.forClient()
                .trustManager(InsecureTrustManagerFactory.INSTANCE)
                .build();

        EventLoopGroup group = new NioEventLoopGroup();

        try {
            Bootstrap b = new Bootstrap();
            b.group(group)
                    .channel(NioSocketChannel.class)
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) {
                            ChannelPipeline p = ch.pipeline();

                            // ========================================================
                            // [핵심] 1. 프록시 핸들러 추가 (가장 먼저!)
                            // 이 핸들러가 CONNECT 요청을 날리고 터널을 뚫어줍니다.
                            // ========================================================
                            p.addLast(new HttpProxyHandler(new InetSocketAddress(PROXY_HOST, PROXY_PORT)));

                            // 2. SSL 핸들러 (프록시가 뚫어준 터널 위에서 암호화 통신)
                            p.addLast(sslCtx.newHandler(ch.alloc(), DEST_HOST, DEST_PORT));

                            // 3. HTTP 코덱 (요청/응답 인코딩 & 디코딩)
                            p.addLast(new HttpClientCodec());

                            // 4. 데이터 조립기 (Chunk된 데이터를 하나의 FullHttpResponse로 합침)
                            p.addLast(new HttpObjectAggregator(1024 * 1024));

                            // 5. 비즈니스 로직 (응답 출력)
                            p.addLast(new SimpleChannelInboundHandler<FullHttpResponse>() {
                                @Override
                                protected void channelRead0(ChannelHandlerContext ctx, FullHttpResponse msg) {
                                    System.out.println("=== 응답 도착 ===");
                                    System.out.println("상태 코드: " + msg.status());
                                    System.out.println("본문 내용: " + msg.content().toString(io.netty.util.CharsetUtil.UTF_8));
                                }

                                @Override
                                public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
                                    cause.printStackTrace();
                                    ctx.close();
                                }
                            });
                        }
                    });

            // 접속 시도 (주의: 목적지가 아닌 '프록시'를 거쳐 연결되지만, 코드는 목적지를 적는 느낌으로)
            // Netty 내부적으로 HttpProxyHandler가 있으면 프록시로 먼저 붙습니다.
            ChannelFuture f = b.connect(DEST_HOST, DEST_PORT).sync();

            // HTTP GET 요청 생성
            FullHttpRequest request = new DefaultFullHttpRequest(
                    HttpVersion.HTTP_1_1,
                    HttpMethod.GET,
                    "/get?msg=HelloNettyProxy"); // 에코 URL

            request.headers().set(HttpHeaderNames.HOST, DEST_HOST);
            request.headers().set(HttpHeaderNames.CONNECTION, HttpHeaderValues.CLOSE);

            // 요청 전송
            f.channel().writeAndFlush(request);

            // 연결이 닫힐 때까지 대기
            f.channel().closeFuture().sync();

        } finally {
            group.shutdownGracefully();
        }
    }
}

 

그런데 어딘가 요청을 찌르려면... 실제로 서버가 있어야 하지 않겠나?

 

그래서 가짜 서버를 하나 만들었다. (고마워 제미나이!)

 

FakeProxyServer.java

package com.example.study.netty.httpproxyhandler;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.*;

public class FakeProxyServer {
    public static void main(String[] args) throws Exception {
        EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) {
                            ch.pipeline().addLast(new HttpServerCodec());
                            ch.pipeline().addLast(new SimpleChannelInboundHandler<HttpRequest>() {
                                @Override
                                protected void channelRead0(ChannelHandlerContext ctx, HttpRequest req) {
                                    System.out.println("요청 받음: " + req.method() + " " + req.uri());

                                    // CONNECT 요청이 오면 무조건 200 OK를 날려줌 (가짜 터널 성립)
                                    if (HttpMethod.CONNECT.equals(req.method())) {
                                        ctx.writeAndFlush(new DefaultFullHttpResponse(
                                                HttpVersion.HTTP_1_1,
                                                new HttpResponseStatus(200, "Connection Established")
                                        ));
                                        // 이후 데이터는 그냥 무시하거나 끊김 (단순 테스트용)
                                    }
                                }
                            });
                        }
                    });

            System.out.println("가짜 프록시 서버가 8888 포트에서 시작됨...");
            b.bind(8888).sync().channel().closeFuture().sync();
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
}

 


NettyProxyExample을 실행하고 나서 FakeProxyServer를 실행하면 다음과 같이 보인다.

 

 

 

위를 다시 정리해보자.

 

현재 HttpProxyHandler가 있는데, 이것을 통해서 우리가 블라인드 포워딩 프록시 터널을 생성할 수 있다.

 

요즘 웹사이트에서 HTTPS가 아닌가 없을텐데, 그것에 이제 직접 요청을 할 수 있게끔 해당 기능을 지원하는거 같다.

 

공식문서는 늘 어렵고 사실 아직 이해를 못했지만 그러려니 하려고 한다.

 

3.3) In-VM Pipe

다음 정의는 https://netty.io/4.0/api/io/netty/channel/local/package-summary.html 에 있다.

A virtual transport that enables the communication between the two parties in the same virtual machine.

같은 가상머신 안에 있는 두 주체가 서로 통신할 수 있게 해 주는 가상의 전송(transport)

 

"하나의 JVM(자바 프로그램) 안에서" 네트워크 통신처럼 메시지를 주고받기 위한 도구 라는데...

 

위의 url 에 들어가면 볼 수 있는 구현 클래스들은 다음과 같다.

 

LocalAddress, LocalChannel, LocalEventrLoopGroup, LocalServerChannel

 

이름부터 벌써 로~컬 용이다. 내부용인데? 지금 실행중인 JVM내부에서만 돌아가는 것이다. 

 

이게 사실 왜 필요한건지... 글이 너무 길어지니 필자가 피곤한 관계(????)로 예시 주소만 소개하고 다시 정리할 예정이다.

(참고 예시 주소)

 


 

이렇게 Core부분과 Transport Service부분을 대강 훓어보았다. 

 

사실 잘 모르겟는데, 억지로 AI 를 써가며 검색해서 알아보고 한 느낌이다.

 

다음에는 이번 글에서 못했던 LocalEcho의 코드를 탐방하고, 이어서 Protocol Support 부분들을 찾아볼 예정이다.

 

최근에 공부할 것이 너무 많기도 하고 또... 중간에 자꾸 다른길로 새다보니... Netty탐방 시리즈가 늦어지고 있다. 

 

별로 보는 사람은 없지만 나 자신과의 약속을 위해 다시 글들을 복기하고 좋은 퀄리티의 학습내용을 정리하겠다. ㅠㅠ..

 

출처

https://netty.io/index.html

https://netty.io/4.1/api/io/netty/channel/socket/nio/NioSocketChannel.html

https://netty.io/4.1/api/io/netty/handler/proxy/HttpProxyHandler.html

https://netty.io/4.0/api/io/netty/channel/local/package-summary.html

https://www.atmosi.com/us/news-events/news/benefits-of-using-a-virtualized-environment-in-pipeline-applications/

https://github.com/netty/netty/blob/4.1/example/src/main/java/io/netty/example/localecho/LocalEcho.java