单机 QPS 280W+,从裸写 Netty 到框架封装,我把 Java 路由损耗压到了“纳秒级”

6 阅读3分钟

 在高性能网络编程领域,很多人觉得 Java 框架太重,甚至觉得“框架”这个词本身就代表了性能损耗。

今天,用我的 gzb one 框架做了一次极致压测,带大家看看:当一个 Java 框架把路径缩短到极致,它到底能有多快?

1. 裸写 Netty:探寻物理极限

首先,我们直接在 Netty 的 channelRead0 里硬编码一个静态响应。不走任何路由,不走任何逻辑,这就是这台机器(Kali Linux)的物理天花板:

// 预先构造好的响应对象,消除运行时分配开销
   public static FullHttpResponse response=null;
    static{
         response = new DefaultFullHttpResponse(
                HttpVersion.HTTP_1_1,
                HttpResponseStatus.OK,
                Unpooled.wrappedBuffer(NettyTools.HELLO_WORD),
                false
        );
        HttpHeaders headers = response.headers();
        headers.set(HttpHeaderNames.CONTENT_TYPE, NettyTools.CONTENT_TYPE);
        headers.set(HttpHeaderNames.CONTENT_LENGTH, NettyTools.CONTENT_LENGTH);
        headers.set(HttpHeaderNames.SERVER, NettyTools.SERVER_NAME);
        headers.set(HttpHeaderNames.DATE, NettyTools.THIS_TIME);
    }        
    protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest req) throws             Exception {
        if (req.uri().equals("/text")) {
            // 直接复用
            ctx.write(response.retainedDuplicate());
        } 
        ctx.flush();
    }

压测结果 (wrk pipeline):

  • Requests/sec: 283.8W

这基本就是 Netty 在这台机器上的性能底色了。

2. 框架接入:优雅与性能的博弈

在实际开发中,我们不可能满篇都是 if-else 去判断 URI。我们需要注解,需要路由映射,需要方便的 Controller

但在 gzb one 框架里,我实现了一套“零损耗”的路由调度。看看通过框架封装后的代码:

public static final byte[] HELLO_WORD = "Hello, World!".getBytes(Config.encoding);
@EventLoop //避免线程切换
@RequestMapping("hello")
@Header(item = {@HeaderItem(key = "Content-Type", val = "text/html")})
public Object hello() {
    return HELLO_WORD; // 业务只需关心返回什么
}

压测结果 (wrk pipeline):

  • Requests/sec: 226.9W

3. 数学题:框架到底损耗了多少?

让我们来算一笔硬账:

  1. 物理天花板 (裸写) :2,838,303 次请求/秒。每个请求耗时约 352.3 纳秒。
  2. 框架封装后:2,269,941 次请求/秒。每个请求耗时约 440.5 纳秒。
  3. 440.5ns - 352.3ns = 88.2ns

结论: 从原始数据包进入网卡,到经过 gzb one 框架的路径映射、权限校验(如有)、注解解析、反射调用(已优化)、再到最终响应,整个框架层的纯调度损耗仅为 88 纳秒 左右。

在这个量级下,你甚至可以认为框架是“透明”的。

压测详情 请移步 开源项目 : gitee.com/gzb001001/g…

4. 为什么能这么快?

很多 Java 框架慢,是因为它们把简单的事情搞复杂了。gzb one 坚持以下几点:

  • @EventLoop 机制:大多数框架会把请求丢进业务线程池。但对于极速响应,线程切换(Context Switch)就是性能杀手。我们让代码直接在 IO 线程飞驰。
  • 对象池化与复用:减少 GC 的压力。
  • 编译期参数感知:利用 -parameters 等技术,在启动时就完成路由闭环,运行时不走弯路。
  • Fat JAR 部署:没有任何多余的依赖包扫描,每一行被加载的代码都是为了性能而生。

总结

很多时候,不是 Java 慢,而是我们习惯了臃肿的封装。

gzb one 的设计初衷就是:不希望开发者为了性能去裸写 Netty。 我们提供最舒适的注解开发体验,同时把损耗控制在几十纳秒以内。

这不仅仅是一个“小玩具”,这是为未来高频并发场景准备的 Java 性能引擎


项目环境: Kali Linux / JDK 25 / 24 Threads / 120 Connections

github:github.com/qq129736888…

gitee:gitee.com/gzb001001/g…