Netty实现简单的Http服务器

之前在upload服务器的时候,由于tomcat性能瓶颈的的问题,qps无法达到要求,了解到Netty.io的高性能,觉得自己写一个Http接受数据的服务器来处理客户段上报的数据,比较简单,直接贴代码了:

package com.bonree.browser.httpServer.server;

import com.bonree.browser.httpServer.handler.HttpServerHandler;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.channel.*;
import io.netty.channel.epoll.EpollEventLoopGroup;
import io.netty.channel.epoll.EpollServerSocketChannel;
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.HttpContentCompressor;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpRequestDecoder;
import io.netty.handler.codec.http.HttpResponseEncoder;
import io.netty.util.concurrent.DefaultThreadFactory;
import org.apache.log4j.Logger;

import java.nio.channels.spi.SelectorProvider;
import java.util.concurrent.ThreadFactory;

/*******************************************************************************
 * 版权信息:博睿宏远科技发展有限公司
 * Copyright: Copyright (c) 2007博睿宏远科技发展有限公司,Inc.All Rights Reserved.
 * @author  <a href=mailto:[email protected]>徐昌</a>
 * Description: 服务端程序
 ******************************************************************************/
public class NettyServer {
    private Logger log = Logger.getLogger(NettyServer.class);
    private int port;
    private int bossGroupThreadNum = 1;
    private int workGroupThreadNum = 0;
    private boolean userEPoll = true;
    private EventLoopGroup bossGroup = null;
    private EventLoopGroup workerGroup = null;
    ServerBootstrap server = null;

    public NettyServer(int port, int bossGroupThreadNum, int workGroupThreadNum, boolean userEPoll) {
        this.port = port;
        this.bossGroupThreadNum = bossGroupThreadNum;
        this.workGroupThreadNum = workGroupThreadNum;
        this.userEPoll = userEPoll;
    }

    public NettyServer(int port) {
        this.port = port;
    }

    private void init() {
        if (userEPoll) {
            createEPollServer();
        } else {
            createNIOServer();
        }
    }

    public void start() {
        init();
        //server启动
        try {
            server = new ServerBootstrap();
            server.group(bossGroup, workerGroup)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            ChannelPipeline pipeline = ch.pipeline();
                            // request解密
                            pipeline.addLast(new HttpRequestDecoder());
                            //将多个http对象聚合成单一的FullHttpRequest
                            pipeline.addLast(new HttpObjectAggregator(1024 * 1024));
                            // response 加密
                            pipeline.addLast(new HttpResponseEncoder());
                            //数据压缩
                            pipeline.addLast(new HttpContentCompressor());
                            // 调用我们的方法
                            pipeline.addLast(new HttpServerHandler());
                        }
                    });
            initChannelOption();
            ChannelFuture future = server.bind(port).sync();
            log.info("HTTP服务启动,网址为 http://localhost:" + port);
            future.channel().closeFuture().sync();
        } catch (Exception e) {
            log.error("Server start fail!", e);
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }

    private void initChannelOption() {
        if (userEPoll) {
            server.channel(EpollServerSocketChannel.class)
                    .option(ChannelOption.TCP_NODELAY, false)
                    .option(ChannelOption.SO_BACKLOG, 511)
                    .option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
                    .childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
        } else {
            server.channel(NioServerSocketChannel.class)
                    .option(ChannelOption.TCP_NODELAY, false)
                    .option(ChannelOption.SO_BACKLOG, 511)
                    .option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
                    .childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
        }
    }

    private void createEPollServer() {
        if (bossGroup == null) {
            EpollEventLoopGroup epollEventLoopGroup = new EpollEventLoopGroup(getBossGoupThreadNum(), getBossGroupThreadFactory());
            epollEventLoopGroup.setIoRatio(100);
            bossGroup = epollEventLoopGroup;
        }
        if (workerGroup == null) {
            EpollEventLoopGroup epollEventLoopGroup = new EpollEventLoopGroup(getWorkGroupThreadNum(), getWorkGroupThreadFactory());
            epollEventLoopGroup.setIoRatio(80);
            workerGroup = epollEventLoopGroup;
        }
    }

    private void createNIOServer() {
        if (bossGroup == null) {
            NioEventLoopGroup nioEventLoopGroup = new NioEventLoopGroup(getBossGoupThreadNum(), getBossGroupThreadFactory());
            nioEventLoopGroup.setIoRatio(100);
            bossGroup = nioEventLoopGroup;
        }
        if (workerGroup == null) {
            NioEventLoopGroup nioEventLoopGroup = new NioEventLoopGroup(getWorkGroupThreadNum(), getWorkGroupThreadFactory(), getSelectorProvider());
            nioEventLoopGroup.setIoRatio(80);
            workerGroup = nioEventLoopGroup;
        }
    }

    private SelectorProvider getSelectorProvider() {
        return SelectorProvider.provider();
    }

    private int getBossGoupThreadNum() {
        //做成可以配置的
        return bossGroupThreadNum;
    }

    private int getWorkGroupThreadNum() {
        //做成可以配置的
        return workGroupThreadNum;
    }

    private ThreadFactory getBossGroupThreadFactory() {
        return new DefaultThreadFactory("T_BOSS_GROUP");
    }

    private ThreadFactory getWorkGroupThreadFactory() {
        return new DefaultThreadFactory("T_BOSS_GROUP");
    }
}

猜你喜欢

转载自blog.csdn.net/u012164361/article/details/81975497