You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Netty JVM内本地传输使用示例及基于其实现反向代理的咨询

Netty 本地传输反向代理实现方案

Netty 本地传输的核心是通过LocalAddress作为唯一标识,使用JVM内部内存交换数据,跳过操作系统网络栈,性能远高于loopback网卡的环回请求,完全适配你描述的同JVM进程内请求转发场景。

核心架构对应关系

  • 对外Web服务端:基于NIO传输监听公网端口,接收用户的HTTP请求
  • 本地传输服务端:绑定自定义LocalAddress,接收Web服务端转发的内部请求
  • 本地传输客户端:连接到上述LocalAddress,拿到请求后向外部目标主机发起调用,收到响应后原路回传给Web服务端

实现示例

1. 基础依赖(Maven)

<dependency>
    <groupId>io.netty</groupId>
    <artifactId>netty-all</artifactId>
    <version>4.1.97.Final</version>
</dependency>

2. 本地传输服务端启动逻辑

// 可复用Web服务端的EventLoop,减少线程开销
EventLoopGroup eventLoopGroup = new NioEventLoopGroup();
// 自定义本地地址标识,同JVM内唯一即可
LocalAddress localAddress = new LocalAddress("internal-proxy");

ServerBootstrap localServer = new ServerBootstrap()
        .group(eventLoopGroup)
        // 核心:指定本地传输服务端Channel实现
        .channel(LocalServerChannel.class)
        .childHandler(new ChannelInitializer<LocalChannel>() {
            @Override
            protected void initChannel(LocalChannel ch) {
                ChannelPipeline p = ch.pipeline();
                // 按需添加HTTP编解码器、聚合器
                p.addLast(new HttpClientCodec());
                p.addLast(new HttpObjectAggregator(1024 * 1024));
                // 自定义处理器:把本地传输收到的响应回写给公网用户的Channel
                p.addLast(new LocalRespForwardHandler());
            }
        });
// 绑定本地地址
localServer.bind(localAddress).syncUninterruptibly();

3. 公网Web服务端请求转发逻辑

// 公网请求处理器的channelRead方法里,拿到完整HTTP请求后转发
@Override
protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest req) {
    // 提前创建好本地传输客户端的Channel池,避免每次请求新建连接
    Channel localClientChannel = getLocalClientChannelFromPool();
    // 保留ByteBuf引用,直接转发避免拷贝
    localClientChannel.writeAndFlush(req.retain()).addListener((ChannelFutureListener) future -> {
        if (!future.isSuccess()) {
            ctx.writeAndFlush(new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.INTERNAL_SERVER_ERROR));
        }
    });
}

4. 本地传输客户端启动逻辑

Bootstrap localClient = new Bootstrap()
        .group(eventLoopGroup)
        // 核心:指定本地传输客户端Channel实现
        .channel(LocalChannel.class)
        .handler(new ChannelInitializer<LocalChannel>() {
            @Override
            protected void initChannel(LocalChannel ch) {
                ChannelPipeline p = ch.pipeline();
                p.addLast(new HttpClientCodec());
                p.addLast(new HttpObjectAggregator(1024 * 1024));
                // 自定义处理器:拿到本地传输的请求后,发往外部目标主机
                p.addLast(new ExternalReqForwardHandler());
            }
        });
// 连接到之前绑定的本地地址
localClient.connect(localAddress).syncUninterruptibly();

注意事项

  • LocalAddress不需要对应实际端口,只要保证同一JVM内的服务端和客户端使用相同的字符串标识即可
  • 转发过程中注意ByteBuf的引用计数,调用retain()后直接传递,避免内存拷贝和泄漏
  • 本地传输不支持TCP相关的参数配置,比如SO_KEEPALIVE、TCP_NODELAY等,启动时不要添加不支持的选项
  • 如果需要处理并发请求,建议为本地传输连接实现Channel池,减少连接创建开销

内容的提问来源于stack exchange,提问作者jascadev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 05:36:08