1. 程式人生 > >Netty實現簡單的Http伺服器

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