|
@@ -1,17 +1,16 @@
|
|
|
package com.its.moct.utic.server.xnet.cluster.master;
|
|
|
|
|
|
+import com.its.beanit.utils.ItsAsn;
|
|
|
+import com.its.common.network.NettyUtils;
|
|
|
+import com.its.common.utils.OsPlatform;
|
|
|
import com.its.moct.utic.server.config.HaClusterConfig;
|
|
|
import com.its.moct.utic.server.repository.ApplicationRepository;
|
|
|
-import com.its.moct.utic.server.xnet.cluster.utils.ClusterMessageDecoder;
|
|
|
-import com.its.moct.utic.server.xnet.cluster.utils.ClusterMessageEncoder;
|
|
|
import io.netty.bootstrap.ServerBootstrap;
|
|
|
import io.netty.channel.ChannelFuture;
|
|
|
-import io.netty.channel.ChannelInitializer;
|
|
|
-import io.netty.channel.ChannelPipeline;
|
|
|
+import io.netty.channel.ChannelOption;
|
|
|
import io.netty.channel.EventLoopGroup;
|
|
|
+import io.netty.channel.epoll.Epoll;
|
|
|
import io.netty.channel.nio.NioEventLoopGroup;
|
|
|
-import io.netty.channel.socket.SocketChannel;
|
|
|
-import io.netty.channel.socket.nio.NioServerSocketChannel;
|
|
|
import lombok.RequiredArgsConstructor;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.springframework.stereotype.Service;
|
|
@@ -23,25 +22,38 @@ public class ClusterMasterService {
|
|
|
|
|
|
private final ApplicationRepository repo;
|
|
|
private final HaClusterConfig cluster;
|
|
|
- private EventLoopGroup bossGroup;
|
|
|
+
|
|
|
+ private EventLoopGroup acceptGroup;
|
|
|
private EventLoopGroup workerGroup;
|
|
|
private ChannelFuture channelFuture;
|
|
|
|
|
|
public void start() {
|
|
|
- this.bossGroup = new NioEventLoopGroup();
|
|
|
+ if (!OsPlatform.isWindows()) {
|
|
|
+ if (!Epoll.isAvailable()) {
|
|
|
+ Epoll.unavailabilityCause().printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (NettyUtils.isEpollAvailable()) {
|
|
|
+ log.info("클러스터 마스터가 리눅스 EPOLL 모드에서 실행됩니다.");
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ log.info("클러스터 마스터가 윈도우 NIO 모드에서 실행됩니다.");
|
|
|
+ }
|
|
|
+
|
|
|
+ this.acceptGroup = new NioEventLoopGroup();
|
|
|
this.workerGroup = new NioEventLoopGroup();
|
|
|
- ServerBootstrap b = new ServerBootstrap();
|
|
|
- b.group(this.bossGroup, this.workerGroup)
|
|
|
- .channel(NioServerSocketChannel.class)
|
|
|
- .childHandler(new ChannelInitializer<SocketChannel>() {
|
|
|
- @Override
|
|
|
- public void initChannel(SocketChannel ch) throws Exception {
|
|
|
- ChannelPipeline p = ch.pipeline();
|
|
|
- p.addLast(new ClusterMessageDecoder());
|
|
|
- p.addLast(new ClusterMessageEncoder());
|
|
|
- p.addLast(new ClusterMasterHandler(repo, cluster));
|
|
|
- }
|
|
|
- });
|
|
|
+ ServerBootstrap serverBootstrap = createBootstrap();
|
|
|
+// b.group(this.acceptGroup, this.workerGroup)
|
|
|
+// .channel(NioServerSocketChannel.class)
|
|
|
+// .childHandler(new ChannelInitializer<SocketChannel>() {
|
|
|
+// @Override
|
|
|
+// public void initChannel(SocketChannel ch) throws Exception {
|
|
|
+// ChannelPipeline p = ch.pipeline();
|
|
|
+// p.addLast(new ClusterMessageDecoder());
|
|
|
+// p.addLast(new ClusterMessageEncoder());
|
|
|
+// p.addLast(new ClusterMasterHandler(repo, cluster));
|
|
|
+// }
|
|
|
+// });
|
|
|
|
|
|
log.info("*********************************************************************************");
|
|
|
log.info("** UTIC MOCT HA Cluster Master Server Information **");
|
|
@@ -52,10 +64,10 @@ public class ClusterMasterService {
|
|
|
|
|
|
try {
|
|
|
if (this.cluster.getIpAddress().equals("0.0.0.0")) {
|
|
|
- this.channelFuture = b.bind(this.cluster.getSyncPort());
|
|
|
+ this.channelFuture = serverBootstrap.bind(this.cluster.getSyncPort());
|
|
|
}
|
|
|
else {
|
|
|
- this.channelFuture = b.bind(this.cluster.getIpAddress(), this.cluster.getSyncPort());
|
|
|
+ this.channelFuture = serverBootstrap.bind(this.cluster.getIpAddress(), this.cluster.getSyncPort());
|
|
|
}
|
|
|
}
|
|
|
catch (Exception e) {
|
|
@@ -63,16 +75,60 @@ public class ClusterMasterService {
|
|
|
shutdown();
|
|
|
}
|
|
|
}
|
|
|
+ public ServerBootstrap createBootstrap() {
|
|
|
+ ServerBootstrap serverBootstrap = new ServerBootstrap();
|
|
|
+ EventLoopGroup acceptGroups;
|
|
|
+ EventLoopGroup workerGroups;
|
|
|
+
|
|
|
+ acceptGroups = NettyUtils.newEventLoopGroup(1, "Accept");
|
|
|
+ workerGroups = NettyUtils.newEventLoopGroup(1, "Worker");
|
|
|
+ serverBootstrap.channel(NettyUtils.getServerSocketChannel());
|
|
|
+ serverBootstrap.group(acceptGroups, workerGroups);
|
|
|
+
|
|
|
+ serverBootstrap.option(ChannelOption.AUTO_READ, true);
|
|
|
+ serverBootstrap.option(ChannelOption.SO_BACKLOG, 2);
|
|
|
+ serverBootstrap.option(ChannelOption.SO_RCVBUF, ItsAsn.ITS_ASN_PACKET_MAX_SIZE);//config.getRcvBuf());
|
|
|
+ serverBootstrap.option(ChannelOption.SO_REUSEADDR, true);
|
|
|
+ serverBootstrap.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5*1000);
|
|
|
+
|
|
|
+ serverBootstrap.childOption(ChannelOption.SO_LINGER, 0); // 4way-handshake 비활성
|
|
|
+ serverBootstrap.childOption(ChannelOption.SO_KEEPALIVE, false); // KEEPALIVE 비활성(활성: true)
|
|
|
+ serverBootstrap.childOption(ChannelOption.SO_REUSEADDR, true); // 소켓 재사용
|
|
|
+ serverBootstrap.childOption(ChannelOption.TCP_NODELAY, true); // Nagle 알고리즘 비활성화
|
|
|
+
|
|
|
+ ClusterMasterInitializer clusterMasterInitializer = new ClusterMasterInitializer(
|
|
|
+ this.repo,
|
|
|
+ this.cluster
|
|
|
+ );
|
|
|
+ serverBootstrap.childHandler(clusterMasterInitializer);
|
|
|
+
|
|
|
+ return serverBootstrap;
|
|
|
+ }
|
|
|
|
|
|
public void shutdown() {
|
|
|
- if (this.channelFuture != null) {
|
|
|
- this.channelFuture.channel().close();
|
|
|
+ try {
|
|
|
+ if (this.acceptGroup != null) {
|
|
|
+ this.acceptGroup.shutdownGracefully();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ catch (Exception e) {
|
|
|
+ log.info("ClusterMasterService.acceptGroup.shutdownGracefully");
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ if (this.workerGroup != null) {
|
|
|
+ this.workerGroup.shutdownGracefully();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ catch (Exception e) {
|
|
|
+ log.info("ClusterMasterService.workerGroup.shutdownGracefully");
|
|
|
}
|
|
|
- if (this.bossGroup != null) {
|
|
|
- this.bossGroup.shutdownGracefully();
|
|
|
+ try {
|
|
|
+ if (this.channelFuture != null && this.channelFuture.channel() != null) {
|
|
|
+ this.channelFuture.channel().closeFuture();
|
|
|
+ }
|
|
|
}
|
|
|
- if (this.workerGroup != null) {
|
|
|
- this.workerGroup.shutdownGracefully();
|
|
|
+ catch (Exception e) {
|
|
|
+ log.info("ClusterMasterService.closeFuture");
|
|
|
}
|
|
|
}
|
|
|
}
|