之前在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");
}
}