Java tutorial
/* * (C) Copyright 2015-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Contributors: * ohun@live.cn () */ package com.mpush.core.server; import com.mpush.api.protocol.Command; import com.mpush.api.service.Listener; import com.mpush.common.MessageDispatcher; import com.mpush.core.handler.GatewayPushHandler; import com.mpush.netty.server.NettyTCPServer; import com.mpush.tools.config.CC; import com.mpush.tools.config.CC.mp.net.rcv_buf; import com.mpush.tools.config.CC.mp.net.snd_buf; import com.mpush.tools.thread.NamedPoolThreadFactory; import com.mpush.tools.thread.ThreadNames; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.*; import io.netty.channel.sctp.nio.NioSctpServerChannel; import io.netty.channel.udt.nio.NioUdtProvider; import io.netty.handler.traffic.GlobalChannelTrafficShapingHandler; import java.nio.channels.spi.SelectorProvider; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import static com.mpush.tools.config.CC.mp.net.traffic_shaping.gateway_server.*; import static com.mpush.tools.config.CC.mp.net.write_buffer_water_mark.gateway_server_high; import static com.mpush.tools.config.CC.mp.net.write_buffer_water_mark.gateway_server_low; import static com.mpush.tools.thread.ThreadNames.T_TRAFFIC_SHAPING; /** * Created by ohun on 2015/12/30. * * @author ohun@live.cn */ public final class GatewayServer extends NettyTCPServer { private static GatewayServer I; private ServerChannelHandler channelHandler; private ServerConnectionManager connectionManager; private GlobalChannelTrafficShapingHandler trafficShapingHandler; private ScheduledExecutorService trafficShapingExecutor; public static GatewayServer I() { if (I == null) { synchronized (GatewayServer.class) { if (I == null) { I = new GatewayServer(); } } } return I; } private GatewayServer() { super(CC.mp.net.gateway_server_port); } @Override public void init() { super.init(); MessageDispatcher receiver = new MessageDispatcher(); receiver.register(Command.GATEWAY_PUSH, new GatewayPushHandler()); connectionManager = new ServerConnectionManager(false); channelHandler = new ServerChannelHandler(false, connectionManager, receiver); if (CC.mp.net.traffic_shaping.gateway_server.enabled) {//????? trafficShapingExecutor = Executors .newSingleThreadScheduledExecutor(new NamedPoolThreadFactory(T_TRAFFIC_SHAPING)); trafficShapingHandler = new GlobalChannelTrafficShapingHandler(trafficShapingExecutor, write_global_limit, read_global_limit, write_channel_limit, read_channel_limit, check_interval); } } @Override public void stop(Listener listener) { super.stop(listener); if (trafficShapingHandler != null) { trafficShapingHandler.release(); trafficShapingExecutor.shutdown(); } if (connectionManager != null) { connectionManager.destroy(); } } @Override protected String getBossThreadName() { return ThreadNames.T_GATEWAY_BOSS; } @Override protected String getWorkThreadName() { return ThreadNames.T_GATEWAY_WORKER; } @Override protected int getIoRate() { return 100; } @Override protected int getWorkThreadNum() { return CC.mp.thread.pool.gateway_server_work; } @Override protected void initPipeline(ChannelPipeline pipeline) { super.initPipeline(pipeline); if (trafficShapingHandler != null) { pipeline.addLast(trafficShapingHandler); } } @Override protected void initOptions(ServerBootstrap b) { super.initOptions(b); if (snd_buf.gateway_server > 0) b.childOption(ChannelOption.SO_SNDBUF, snd_buf.gateway_server); if (rcv_buf.gateway_server > 0) b.childOption(ChannelOption.SO_RCVBUF, rcv_buf.gateway_server); /** * ?????????? * ??????????????? * ???????? * ???????? * ?????? * ???NettyChannelOutboundBuffer * buffernetty?channel write?buffer???????(?channelbuffer) * ??32(32?)32? * ?(?TCP??) * ??buffer???(?swap?linux killer) * ?channel?channel?active? * * ChannelOutboundBuffer???? * buffer??channelisWritable??false * buffer??isWritable??trueisWritablefalse???? * ???64K?32K??????? */ if (gateway_server_low > 0 && gateway_server_high > 0) { b.childOption(ChannelOption.WRITE_BUFFER_WATER_MARK, new WriteBufferWaterMark(gateway_server_low, gateway_server_high)); } } @Override public ChannelHandler getChannelHandler() { return channelHandler; } @Override public ChannelFactory<? extends ServerChannel> getChannelFactory() { if (CC.mp.net.tcpGateway()) return super.getChannelFactory(); if (CC.mp.net.udtGateway()) return NioUdtProvider.BYTE_ACCEPTOR; if (CC.mp.net.sctpGateway()) return NioSctpServerChannel::new; return super.getChannelFactory(); } @Override public SelectorProvider getSelectorProvider() { if (CC.mp.net.tcpGateway()) return super.getSelectorProvider(); if (CC.mp.net.udtGateway()) return NioUdtProvider.BYTE_PROVIDER; if (CC.mp.net.sctpGateway()) return super.getSelectorProvider(); return super.getSelectorProvider(); } }