package com.alibaba.doris.dataserver.net; import java.net.InetSocketAddress; import java.util.List; import java.util.Properties; import java.util.concurrent.Executors; import org.apache.commons.lang.StringUtils; import org.jboss.netty.bootstrap.ServerBootstrap; import org.jboss.netty.channel.group.ChannelGroup; import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory; import com.alibaba.doris.dataserver.ApplicationContext; import com.alibaba.doris.dataserver.BaseModule; import com.alibaba.doris.dataserver.ModuleContext; import com.alibaba.doris.dataserver.ModuleContextAware; import com.alibaba.doris.dataserver.action.ActionFactory; import com.alibaba.doris.dataserver.action.CatchCommandErrorAction; import com.alibaba.doris.dataserver.action.CheckAction; import com.alibaba.doris.dataserver.action.DeleteAction; import com.alibaba.doris.dataserver.action.ExitServerAction; import com.alibaba.doris.dataserver.action.GetAction; import com.alibaba.doris.dataserver.action.SetAction; import com.alibaba.doris.dataserver.action.ShutdownAction; import com.alibaba.doris.dataserver.action.data.BaseActionType; import com.alibaba.doris.dataserver.config.data.FilterConfigure; import com.alibaba.doris.dataserver.config.data.ModuleConfigure; import com.alibaba.doris.dataserver.core.RequestFilterChainFactory; import com.alibaba.doris.dataserver.core.RequestFilterChian; import com.alibaba.doris.dataserver.net.netty.CollectConnectionInfoHandler; import com.alibaba.doris.dataserver.net.netty.NettyDataServerChannelPipelineFactory; /** * 服务器端网络通信模块,负责对Client发出的请求进行响应,<br> * 并将请求包装成相应的Request和Response对象。 * * @author ajun Email:jack.yuj@alibaba-inc.com */ public class NetworkModule extends BaseModule implements ModuleContextAware { public void load(ModuleConfigure conf) { networkModuleConfigure = conf; initAction(); initFilter(conf); initNetwork(); } protected void initNetwork() { // 看看命令行输入参数是否带有Port端口,如果带有Port端口,则优先使用。 Properties commandLine = networkModuleConfigure.getDataServerConfigure().getCommandLine(); String commandLineOfPort = commandLine.getProperty("port"); if (StringUtils.isBlank(commandLineOfPort)) { port = networkModuleConfigure.getParamAsInt("port", DEFAULT_SERVER_PORT); } else { port = Integer.valueOf(commandLineOfPort); } maxConnections = networkModuleConfigure.getParamAsInt(MAX_ACTIVE_CONNECTIONS, DEFAULT_MAX_ACTIVE_CONNECTIONS); int threads = networkModuleConfigure.getParamAsInt("threads", DEFAULT_SERVER_THREADS); // Configure the server. bootstrap = new ServerBootstrap(new NioServerSocketChannelFactory(Executors.newCachedThreadPool(), Executors.newCachedThreadPool(), threads)); // Set up the event pipeline factory. NettyDataServerChannelPipelineFactory pipelineFactory = new NettyDataServerChannelPipelineFactory(appContext); bootstrap.setPipelineFactory(pipelineFactory); // Bind and start to accept incoming connections. bootstrap.bind(new InetSocketAddress(port)); ModuleContext moduleContext = getModuleContext(); if (null != moduleContext) { moduleContext.setAttribute("serverPort", getPort()); appContext.setAttribute("serverPort", getPort()); } System.out.println("DataServer is listening on port :" + port); } protected void initAction() { // May be we should load these actions from configure file. ActionFactory.registAction(BaseActionType.SET, new SetAction()); ActionFactory.registAction(BaseActionType.CAS, new SetAction()); ActionFactory.registAction(BaseActionType.GET, new GetAction()); ActionFactory.registAction(BaseActionType.DELETE, new DeleteAction()); ActionFactory.registAction(BaseActionType.CAD, new DeleteAction()); ActionFactory.registAction(BaseActionType.ERROR, new CatchCommandErrorAction()); ActionFactory.registAction(BaseActionType.EXIT, new ExitServerAction()); ActionFactory.registAction(BaseActionType.SHUTDOWN, new ShutdownAction()); ActionFactory.registAction(BaseActionType.CHECK, new CheckAction()); } /** * 从配置文件中装载所有的RequestFilter * * @param conf */ protected void initFilter(ModuleConfigure conf) { List<FilterConfigure> filterConfigList = conf.getFilterConfigList(); RequestFilterChainFactory factory = new RequestFilterChainFactory(); factory.loadRequestFiltersFromConfigure(filterConfigList); filterChian = factory.getFilterChian(); } public RequestFilterChian getRequestFilterChain() { return filterChian; } public void unload() { NettyDataServerChannelPipelineFactory factory = (NettyDataServerChannelPipelineFactory) bootstrap.getPipelineFactory(); CollectConnectionInfoHandler handler = factory.getCollectConnectionInfoHandler(); if (null != handler) { ChannelGroup group = handler.getActiveChannels(); group.disconnect().awaitUninterruptibly(); group.close().awaitUninterruptibly(); } bootstrap.releaseExternalResources(); } public void setModuleContext(ModuleContext moduleContext) { super.setModuleContext(moduleContext); this.appContext = moduleContext.getApplicationContext(); } public int getPort() { return port; } public int getMaxConnections() { return maxConnections; } @Override public String toString() { return getName() + " DataServer Listening on port:" + port; } private int port; private int maxConnections; private ServerBootstrap bootstrap; private ModuleConfigure networkModuleConfigure; private ApplicationContext appContext; private RequestFilterChian filterChian; private static final int DEFAULT_SERVER_PORT = 8000; private static final int DEFAULT_SERVER_THREADS = 20; private static final int DEFAULT_MAX_ACTIVE_CONNECTIONS = 10000; public static final String MAX_ACTIVE_CONNECTIONS = "maxConnections"; }