|
|
@@ -36,26 +36,32 @@ public class ClusterMasterService extends AbstractClusterMasterService {
|
|
|
* 센터를 운영할 클러스터 정보를 재 분배한다.
|
|
|
*/
|
|
|
private void rebalanceRunClusterId() {
|
|
|
+
|
|
|
+ // Master 여부에 따라 할당 클러스터 노드를 확인한다.
|
|
|
+ // ActiveClusterId 에 대해서는 처리하지 않는다(이건 순수하게 통신 담당 클러스터 정보를 저장한다.)
|
|
|
+ // RealClusterId 를 설정해 주어야 스케쥴러에서 네트워크 연결을 시도하거나 처리하지 않는다.
|
|
|
ApplicationRepository.CENTER_MAP.forEach((regionId, center) -> {
|
|
|
if (this.clusterConfig.getId() == center.getClusterId()) {
|
|
|
center.setRealClusterId(this.clusterConfig.getId());
|
|
|
// 클러스터가 동일하면 추가
|
|
|
return;
|
|
|
}
|
|
|
- if (!this.clusterConfig.isMaster()) {
|
|
|
- // 마스터가 아니면 리턴
|
|
|
+
|
|
|
+ if (this.clusterConfig.isMaster()) {
|
|
|
+ // 내가 마스터로 운영중일 경우 센터담당 클러스터가 통신이상이면 마스터가 담당한다.
|
|
|
+ int clusterId = center.getClusterId();
|
|
|
+ ClusterNode clusterNode = this.clusterConfig.getClusterNode(clusterId);
|
|
|
+ if (clusterNode != null && !clusterNode.getElectionState().isAlive()) {
|
|
|
+ // 통신이 이상이면 추가
|
|
|
+ center.setRealClusterId(this.clusterConfig.getId());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ // 마스터가 아닌데 실재 할당 클러스터가 나로 되어 있으면 이전에 내가 수행하던 센터이므로 원복 시킨다.
|
|
|
if (this.clusterConfig.getId() == center.getRealClusterId()) {
|
|
|
// 원복(내가 마스터일때 처리하던것)
|
|
|
center.setRealClusterId(center.getClusterId());
|
|
|
}
|
|
|
- return;
|
|
|
- }
|
|
|
- // 내가 마스터로 운영중일 경우 센터담당 클러스터가 통신이상이면 마스터가 담당한다.
|
|
|
- int clusterId = center.getClusterId();
|
|
|
- ClusterNode clusterNode = this.clusterConfig.getClusterNode(clusterId);
|
|
|
- if (clusterNode != null && !clusterNode.getElectionState().isAlive()) {
|
|
|
- // 통신이 이상이면 추가
|
|
|
- center.setRealClusterId(this.clusterConfig.getId());
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
@@ -97,24 +103,24 @@ public class ClusterMasterService extends AbstractClusterMasterService {
|
|
|
this.clusterConfig.getId(), message.getClusterId(), rcvCenter.getCenterId());
|
|
|
continue;
|
|
|
}
|
|
|
- if (center.getRealClusterId() == 0) {
|
|
|
+
|
|
|
+ if (center.getRealClusterId() == 0 || center.getActiveClusterId() == 0) {
|
|
|
// 최초 정보 수신한 경우에 해당함
|
|
|
- rcvCenter.toCopyInfo(center);
|
|
|
+ rcvCenter.toCopyInfo(this.clusterConfig.getId(), center);
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
- if (center.getRealClusterId() == message.getClusterId()) {
|
|
|
- // 기존에 연결된 클러스터의 정보임
|
|
|
- rcvCenter.toCopyInfo(center);
|
|
|
+ if (center.getActiveClusterId() == message.getClusterId()) {
|
|
|
+ // 기존에 연결된 클러스터의 정보임(즉, 다른 노드에서 통신이 연결된 상태인 경우)
|
|
|
+ rcvCenter.toCopyInfo(this.clusterConfig.getId(), center);
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
- // 기타, 클러스터가 현재 서버인경우와 그렇치 않은경우(클러스터가 3개이상인 경우)
|
|
|
if (this.clusterConfig.getId() == center.getRealClusterId()) {
|
|
|
// 현재 서버에 할당된 센터의 정보를 클러스터로 부터 수신한 경우
|
|
|
if (rcvCenter.getNetState().isAlive() &&
|
|
|
center.getNetState().isAlive()) {
|
|
|
- // 현재 서버의 연결을 종료하고 원격서버 정보를 수용한다.
|
|
|
+ // 수신한 네트워크 정보와 서버의 메모리상 네트워크 상태가 모두 연결된 상태인 경우
|
|
|
log.warn("ClusterNodeId: {}, ClusterMasterService.onClusterMessage: fromClusterNodeId: {}, realClusterNodeId: {}, center {} dup cluster connected.",
|
|
|
this.clusterConfig.getId(), center.getRealClusterId(), message.getClusterId(), rcvCenter.getCenterId());
|
|
|
|
|
|
@@ -127,15 +133,14 @@ public class ClusterMasterService extends AbstractClusterMasterService {
|
|
|
center.getNetState().disConnect();
|
|
|
}
|
|
|
}
|
|
|
- rcvCenter.toCopyInfo(center);
|
|
|
+ rcvCenter.toCopyInfo(this.clusterConfig.getId(), center);
|
|
|
}
|
|
|
else {
|
|
|
- // 클러스터가 2대 이상인 경우 해당
|
|
|
// 수신한 클러스터의 정보에서 네트워크가 정상인 경우에만 업데이트 한다.
|
|
|
log.warn("ClusterNodeId: {}, ClusterMasterService.onClusterMessage: fromClusterNodeId: {}, realClusterNodeId: {}, other cluster not working.",
|
|
|
this.clusterConfig.getId(), center.getRealClusterId(), message.getClusterId());
|
|
|
if (rcvCenter.getNetState().isAlive()) {
|
|
|
- rcvCenter.toCopyInfo(center);
|
|
|
+ rcvCenter.toCopyInfo(this.clusterConfig.getId(), center);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -145,6 +150,34 @@ public class ClusterMasterService extends AbstractClusterMasterService {
|
|
|
@Override
|
|
|
public void onClusterChannelActive(ClusterNode clusterNode) {
|
|
|
rebalanceRunClusterId();
|
|
|
+
|
|
|
+ if (this.clusterConfig.isAutoFailbackEnabled()) {
|
|
|
+ // 자동으로 Failback 을 해야 하는 경우 나한테 연결된 다른 노드의 센터 통신연결을 종료한다.
|
|
|
+ int activeClusterId = clusterNode.getId();
|
|
|
+ disconnectClusterNodeAll(activeClusterId);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void disconnectClusterNodeAll(int clusterNodeId) {
|
|
|
+ // 할당된 클러스터 노드에 속하고 실재 통신 연결을 나하고 하고 있는 센터의 통신 연결을 종료한다.
|
|
|
+ ApplicationRepository.CENTER_MAP.forEach((regionId, center) -> {
|
|
|
+ if (clusterNodeId == center.getRealClusterId() &&
|
|
|
+ this.clusterConfig.getId() == center.getActiveClusterId() &&
|
|
|
+ center.getNetState().isAlive()) {
|
|
|
+ // 다시 살아난 노드에 속하는 센터 중에 현재 나하고 통신 중인 센터의 통신연결을 종료한다.
|
|
|
+ Channel channel = center.getNetState().getChannel();
|
|
|
+ try {
|
|
|
+ if (channel != null) {
|
|
|
+ channel.disconnect();
|
|
|
+ channel.close();
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ // no logging
|
|
|
+ }
|
|
|
+ center.getNetState().disConnect();
|
|
|
+ center.setActiveClusterId(0);
|
|
|
+ }
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -154,6 +187,11 @@ public class ClusterMasterService extends AbstractClusterMasterService {
|
|
|
@Override
|
|
|
public void onClusterChannelInactive(ClusterNode clusterNode) {
|
|
|
rebalanceRunClusterId();
|
|
|
+
|
|
|
+ if (this.clusterConfig.isAutoFailbackEnabled()) {
|
|
|
+ int inactiveClusterId = clusterNode.getId();
|
|
|
+ disconnectClusterNodeAll(inactiveClusterId);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
}
|