上一篇【第40篇】Netty内存管理深度解析——PoolChunk/PoolArena源码全剖析
下一篇【第42篇】Netty开发HTTP客户端——高并发请求轻松搞定


一、HTTP协议处理Pipeline

// 标准HTTP Pipeline
pipeline.addLast(new HttpServerCodec());         // HTTP编解码
pipeline.addLast(new HttpObjectAggregator(65536)); // 聚合请求/响应
pipeline.addLast(new HttpServerExpectContinueHandler());
pipeline.addLast(new HttpServerHandler());       // 业务处理

二、完整的HTTP服务器

public class NettyHttpServer {
    public static void main(String[] args) throws Exception {
        EventLoopGroup boss = new NioEventLoopGroup(1);
        EventLoopGroup worker = new NioEventLoopGroup();
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(boss, worker).channel(NioServerSocketChannel.class)
             .childHandler(new ChannelInitializer<SocketChannel>() {
                 protected void initChannel(SocketChannel ch) {
                     ch.pipeline().addLast(new HttpServerCodec());
                     ch.pipeline().addLast(new HttpObjectAggregator(65536));
                     ch.pipeline().addLast(new SimpleRouter());
                 }
             });
            b.bind(8080).sync().channel().closeFuture().sync();
        } finally { boss.shutdownGracefully(); worker.shutdownGracefully(); }
    }
}

class SimpleRouter extends SimpleChannelInboundHandler<FullHttpRequest> {
    protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest req) {
        String uri = req.uri();
        String method = req.method().name();
        
        // 路由分发
        String result;
        if ("/api/user".equals(uri) && "GET".equals(method)) {
            result = "{\"name\":\"Alice\",\"age\":25}";
            sendJson(ctx, result);
        } else if ("/api/order".equals(uri) && "POST".equals(method)) {
            String body = req.content().toString(CharsetUtil.UTF_8);
            result = "{\"status\":\"created\",\"body\":\"" + body + "\"}";
            sendJson(ctx, result);
        } else if ("/".equals(uri)) {
            sendHtml(ctx, "<h1>Hello Netty HTTP Server!</h1>");
        } else {
            sendError(ctx, NOT_FOUND, "Not Found");
        }
    }
    
    private void sendJson(ChannelHandlerContext ctx, String json) {
        FullHttpResponse resp = new DefaultFullHttpResponse(HTTP_1_1, OK,
            ctx.alloc().buffer().writeBytes(json.getBytes()));
        resp.headers().set(CONTENT_TYPE, "application/json");
        resp.headers().set(CONTENT_LENGTH, resp.content().readableBytes());
        ctx.writeAndFlush(resp);
    }
}

三、Chunked分块传输

大文件使用Chunked编码,避免内存中缓存整个文件:

public class FileSender extends SimpleChannelInboundHandler<FullHttpRequest> {
    protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest req) {
        try {
            RandomAccessFile file = new RandomAccessFile("largefile.mp4", "r");
            HttpResponse resp = new DefaultHttpResponse(HTTP_1_1, OK);
            resp.headers().set(CONTENT_TYPE, "video/mp4");
            ctx.write(resp);
            // Chunked分块写入
            ctx.write(new ChunkedFile(file, 0, file.length(), 8192));
            ctx.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT);
        } catch (Exception e) { ctx.close(); }
    }
}

四、性能对比

服务器 静态QPS 动态QPS
Netty HTTP 150,000 80,000
Tomcat 30,000 25,000
Undertow 120,000 65,000

五、总结

组件 功能
HttpServerCodec HTTP请求/响应编解码
HttpObjectAggregator 聚合分块请求
FullHttpRequest/Response 完整HTTP消息
ChunkedFile 大文件分块传输

上一篇【第40篇】Netty内存管理深度解析——PoolChunk/PoolArena源码全剖析
下一篇【第42篇】Netty开发HTTP客户端——高并发请求轻松搞定


Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐