作者 crossoverJie
提交者 GitHub

Merge pull request #88 from crossoverJie/fix-issue-70

Fix issue 70
@@ -4,8 +4,10 @@ import com.crossoverjie.cim.client.config.AppConfiguration; @@ -4,8 +4,10 @@ import com.crossoverjie.cim.client.config.AppConfiguration;
4 import com.crossoverjie.cim.client.init.CIMClientHandleInitializer; 4 import com.crossoverjie.cim.client.init.CIMClientHandleInitializer;
5 import com.crossoverjie.cim.client.service.EchoService; 5 import com.crossoverjie.cim.client.service.EchoService;
6 import com.crossoverjie.cim.client.service.MsgHandle; 6 import com.crossoverjie.cim.client.service.MsgHandle;
  7 +import com.crossoverjie.cim.client.service.ReConnectManager;
7 import com.crossoverjie.cim.client.service.RouteRequest; 8 import com.crossoverjie.cim.client.service.RouteRequest;
8 import com.crossoverjie.cim.client.service.impl.ClientInfo; 9 import com.crossoverjie.cim.client.service.impl.ClientInfo;
  10 +import com.crossoverjie.cim.client.thread.ContextHolder;
9 import com.crossoverjie.cim.client.vo.req.GoogleProtocolVO; 11 import com.crossoverjie.cim.client.vo.req.GoogleProtocolVO;
10 import com.crossoverjie.cim.client.vo.req.LoginReqVO; 12 import com.crossoverjie.cim.client.vo.req.LoginReqVO;
11 import com.crossoverjie.cim.client.vo.res.CIMServerResVO; 13 import com.crossoverjie.cim.client.vo.res.CIMServerResVO;
@@ -66,6 +68,9 @@ public class CIMClient { @@ -66,6 +68,9 @@ public class CIMClient {
66 @Autowired 68 @Autowired
67 private ClientInfo clientInfo; 69 private ClientInfo clientInfo;
68 70
  71 + @Autowired
  72 + private ReConnectManager reConnectManager ;
  73 +
69 /** 74 /**
70 * 重试次数 75 * 重试次数
71 */ 76 */
@@ -90,7 +95,7 @@ public class CIMClient { @@ -90,7 +95,7 @@ public class CIMClient {
90 * 启动客户端 95 * 启动客户端
91 * 96 *
92 * @param cimServer 97 * @param cimServer
93 - * @throws InterruptedException 98 + * @throws Exception
94 */ 99 */
95 private void startClient(CIMServerResVO.ServerInfo cimServer) { 100 private void startClient(CIMServerResVO.ServerInfo cimServer) {
96 Bootstrap bootstrap = new Bootstrap(); 101 Bootstrap bootstrap = new Bootstrap();
@@ -102,14 +107,14 @@ public class CIMClient { @@ -102,14 +107,14 @@ public class CIMClient {
102 ChannelFuture future = null; 107 ChannelFuture future = null;
103 try { 108 try {
104 future = bootstrap.connect(cimServer.getIp(), cimServer.getCimServerPort()).sync(); 109 future = bootstrap.connect(cimServer.getIp(), cimServer.getCimServerPort()).sync();
105 - } catch (InterruptedException e) { 110 + } catch (Exception e) {
106 errorCount++; 111 errorCount++;
107 112
108 if (errorCount >= configuration.getErrorCount()) { 113 if (errorCount >= configuration.getErrorCount()) {
109 LOGGER.error("连接失败次数达到上限[{}]次", errorCount); 114 LOGGER.error("连接失败次数达到上限[{}]次", errorCount);
110 msgHandle.shutdown(); 115 msgHandle.shutdown();
111 } 116 }
112 - LOGGER.error("连接失败", e); 117 + LOGGER.error("Connect fail!", e);
113 } 118 }
114 if (future.isSuccess()) { 119 if (future.isSuccess()) {
115 echoService.echo("Start cim client success!"); 120 echoService.echo("Start cim client success!");
@@ -139,7 +144,7 @@ public class CIMClient { @@ -139,7 +144,7 @@ public class CIMClient {
139 errorCount++; 144 errorCount++;
140 145
141 if (errorCount >= configuration.getErrorCount()) { 146 if (errorCount >= configuration.getErrorCount()) {
142 - LOGGER.error("重连次数达到上限[{}]次", errorCount); 147 + echoService.echo("The maximum number of reconnections has been reached[{}]times, close cim client!", errorCount);
143 msgHandle.shutdown(); 148 msgHandle.shutdown();
144 } 149 }
145 LOGGER.error("login fail", e); 150 LOGGER.error("login fail", e);
@@ -197,6 +202,13 @@ public class CIMClient { @@ -197,6 +202,13 @@ public class CIMClient {
197 } 202 }
198 203
199 204
  205 + /**
  206 + * 1. clear route information.
  207 + * 2. reconnect.
  208 + * 3. shutdown reconnect job.
  209 + * 4. reset reconnect state.
  210 + * @throws Exception
  211 + */
200 public void reconnect() throws Exception { 212 public void reconnect() throws Exception {
201 if (channel != null && channel.isActive()) { 213 if (channel != null && channel.isActive()) {
202 return; 214 return;
@@ -204,9 +216,11 @@ public class CIMClient { @@ -204,9 +216,11 @@ public class CIMClient {
204 //首先清除路由信息,下线 216 //首先清除路由信息,下线
205 routeRequest.offLine(); 217 routeRequest.offLine();
206 218
207 - LOGGER.info("reconnect...."); 219 + echoService.echo("cim server shutdown, reconnecting....");
208 start(); 220 start();
209 - LOGGER.info("reconnect success"); 221 + echoService.echo("Great! reConnect success!!!");
  222 + reConnectManager.reConnectSuccess();
  223 + ContextHolder.clear();
210 } 224 }
211 225
212 /** 226 /**
@@ -87,7 +87,7 @@ public class BeanConfig { @@ -87,7 +87,7 @@ public class BeanConfig {
87 @Bean("scheduledTask") 87 @Bean("scheduledTask")
88 public ScheduledExecutorService buildSchedule(){ 88 public ScheduledExecutorService buildSchedule(){
89 ThreadFactory sche = new ThreadFactoryBuilder() 89 ThreadFactory sche = new ThreadFactoryBuilder()
90 - .setNameFormat("scheduled-%d") 90 + .setNameFormat("reConnect-job-%d")
91 .setDaemon(true) 91 .setDaemon(true)
92 .build(); 92 .build();
93 ScheduledExecutorService scheduledExecutorService = new ScheduledThreadPoolExecutor(1,sche) ; 93 ScheduledExecutorService scheduledExecutorService = new ScheduledThreadPoolExecutor(1,sche) ;
1 package com.crossoverjie.cim.client.handle; 1 package com.crossoverjie.cim.client.handle;
2 2
3 import com.crossoverjie.cim.client.service.EchoService; 3 import com.crossoverjie.cim.client.service.EchoService;
  4 +import com.crossoverjie.cim.client.service.ReConnectManager;
4 import com.crossoverjie.cim.client.service.ShutDownMsg; 5 import com.crossoverjie.cim.client.service.ShutDownMsg;
5 import com.crossoverjie.cim.client.service.impl.EchoServiceImpl; 6 import com.crossoverjie.cim.client.service.impl.EchoServiceImpl;
6 -import com.crossoverjie.cim.client.thread.ReConnectJob;  
7 import com.crossoverjie.cim.client.util.SpringBeanFactory; 7 import com.crossoverjie.cim.client.util.SpringBeanFactory;
8 import com.crossoverjie.cim.common.constant.Constants; 8 import com.crossoverjie.cim.common.constant.Constants;
9 import com.crossoverjie.cim.common.protocol.CIMRequestProto; 9 import com.crossoverjie.cim.common.protocol.CIMRequestProto;
@@ -21,7 +21,6 @@ import org.slf4j.LoggerFactory; @@ -21,7 +21,6 @@ import org.slf4j.LoggerFactory;
21 21
22 import java.util.concurrent.ScheduledExecutorService; 22 import java.util.concurrent.ScheduledExecutorService;
23 import java.util.concurrent.ThreadPoolExecutor; 23 import java.util.concurrent.ThreadPoolExecutor;
24 -import java.util.concurrent.TimeUnit;  
25 24
26 /** 25 /**
27 * Function: 26 * Function:
@@ -41,6 +40,8 @@ public class CIMClientHandle extends SimpleChannelInboundHandler<CIMResponseProt @@ -41,6 +40,8 @@ public class CIMClientHandle extends SimpleChannelInboundHandler<CIMResponseProt
41 40
42 private ScheduledExecutorService scheduledExecutorService ; 41 private ScheduledExecutorService scheduledExecutorService ;
43 42
  43 + private ReConnectManager reConnectManager ;
  44 +
44 private ShutDownMsg shutDownMsg ; 45 private ShutDownMsg shutDownMsg ;
45 46
46 private EchoService echoService ; 47 private EchoService echoService ;
@@ -52,8 +53,6 @@ public class CIMClientHandle extends SimpleChannelInboundHandler<CIMResponseProt @@ -52,8 +53,6 @@ public class CIMClientHandle extends SimpleChannelInboundHandler<CIMResponseProt
52 if (evt instanceof IdleStateEvent){ 53 if (evt instanceof IdleStateEvent){
53 IdleStateEvent idleStateEvent = (IdleStateEvent) evt ; 54 IdleStateEvent idleStateEvent = (IdleStateEvent) evt ;
54 55
55 - //LOGGER.info("定时检测服务端是否存活");  
56 -  
57 if (idleStateEvent.state() == IdleState.WRITER_IDLE){ 56 if (idleStateEvent.state() == IdleState.WRITER_IDLE){
58 CIMRequestProto.CIMReqProtocol heartBeat = SpringBeanFactory.getBean("heartBeat", 57 CIMRequestProto.CIMReqProtocol heartBeat = SpringBeanFactory.getBean("heartBeat",
59 CIMRequestProto.CIMReqProtocol.class); 58 CIMRequestProto.CIMReqProtocol.class);
@@ -90,10 +89,11 @@ public class CIMClientHandle extends SimpleChannelInboundHandler<CIMResponseProt @@ -90,10 +89,11 @@ public class CIMClientHandle extends SimpleChannelInboundHandler<CIMResponseProt
90 89
91 if (scheduledExecutorService == null){ 90 if (scheduledExecutorService == null){
92 scheduledExecutorService = SpringBeanFactory.getBean("scheduledTask",ScheduledExecutorService.class) ; 91 scheduledExecutorService = SpringBeanFactory.getBean("scheduledTask",ScheduledExecutorService.class) ;
  92 + reConnectManager = SpringBeanFactory.getBean(ReConnectManager.class) ;
93 } 93 }
94 LOGGER.info("客户端断开了,重新连接!"); 94 LOGGER.info("客户端断开了,重新连接!");
95 // TODO: 2019-01-22 后期可以改为不用定时任务,连上后就关闭任务 节省性能。 95 // TODO: 2019-01-22 后期可以改为不用定时任务,连上后就关闭任务 节省性能。
96 - scheduledExecutorService.scheduleAtFixedRate(new ReConnectJob(ctx),0,10, TimeUnit.SECONDS) ; 96 + reConnectManager.reConnect(ctx);
97 } 97 }
98 98
99 @Override 99 @Override
  1 +package com.crossoverjie.cim.client.service;
  2 +
  3 +import com.crossoverjie.cim.client.thread.ReConnectJob;
  4 +import com.google.common.util.concurrent.ThreadFactoryBuilder;
  5 +import io.netty.channel.ChannelHandlerContext;
  6 +import org.springframework.stereotype.Component;
  7 +
  8 +import java.util.concurrent.ScheduledExecutorService;
  9 +import java.util.concurrent.ScheduledThreadPoolExecutor;
  10 +import java.util.concurrent.ThreadFactory;
  11 +import java.util.concurrent.TimeUnit;
  12 +
  13 +/**
  14 + * Function:
  15 + *
  16 + * @author crossoverJie
  17 + * Date: 2020-04-15 00:26
  18 + * @since JDK 1.8
  19 + */
  20 +@Component
  21 +public final class ReConnectManager {
  22 +
  23 + private ScheduledExecutorService scheduledExecutorService;
  24 +
  25 + /**
  26 + * Trigger reconnect job
  27 + * @param ctx
  28 + */
  29 + public void reConnect(ChannelHandlerContext ctx) {
  30 + buildExecutor() ;
  31 + scheduledExecutorService.scheduleAtFixedRate(new ReConnectJob(ctx),0,10, TimeUnit.SECONDS) ;
  32 + }
  33 +
  34 + /**
  35 + * Close reconnect job if reconnect success.
  36 + */
  37 + public void reConnectSuccess(){
  38 + scheduledExecutorService.shutdown();
  39 + }
  40 +
  41 +
  42 + /***
  43 + * build an thread executor
  44 + * @return
  45 + */
  46 + private ScheduledExecutorService buildExecutor() {
  47 + if (scheduledExecutorService == null || scheduledExecutorService.isShutdown()) {
  48 + ThreadFactory sche = new ThreadFactoryBuilder()
  49 + .setNameFormat("reConnect-job-%d")
  50 + .setDaemon(true)
  51 + .build();
  52 + scheduledExecutorService = new ScheduledThreadPoolExecutor(1, sche);
  53 + return scheduledExecutorService;
  54 + } else {
  55 + return scheduledExecutorService;
  56 + }
  57 + }
  58 +}
1 package com.crossoverjie.cim.client.service.impl; 1 package com.crossoverjie.cim.client.service.impl;
2 2
3 import com.crossoverjie.cim.client.client.CIMClient; 3 import com.crossoverjie.cim.client.client.CIMClient;
  4 +import com.crossoverjie.cim.client.thread.ContextHolder;
4 import com.crossoverjie.cim.common.kit.HeartBeatHandler; 5 import com.crossoverjie.cim.common.kit.HeartBeatHandler;
5 import io.netty.channel.ChannelHandlerContext; 6 import io.netty.channel.ChannelHandlerContext;
6 import org.slf4j.Logger; 7 import org.slf4j.Logger;
@@ -28,6 +29,7 @@ public class ClientHeartBeatHandlerImpl implements HeartBeatHandler { @@ -28,6 +29,7 @@ public class ClientHeartBeatHandlerImpl implements HeartBeatHandler {
28 public void process(ChannelHandlerContext ctx) throws Exception { 29 public void process(ChannelHandlerContext ctx) throws Exception {
29 30
30 //重连 31 //重连
  32 + ContextHolder.setReconnect(true);
31 cimClient.reconnect(); 33 cimClient.reconnect();
32 34
33 } 35 }
@@ -5,12 +5,14 @@ import com.alibaba.fastjson.JSONObject; @@ -5,12 +5,14 @@ import com.alibaba.fastjson.JSONObject;
5 import com.crossoverjie.cim.client.config.AppConfiguration; 5 import com.crossoverjie.cim.client.config.AppConfiguration;
6 import com.crossoverjie.cim.client.service.EchoService; 6 import com.crossoverjie.cim.client.service.EchoService;
7 import com.crossoverjie.cim.client.service.RouteRequest; 7 import com.crossoverjie.cim.client.service.RouteRequest;
  8 +import com.crossoverjie.cim.client.thread.ContextHolder;
8 import com.crossoverjie.cim.client.vo.req.GroupReqVO; 9 import com.crossoverjie.cim.client.vo.req.GroupReqVO;
9 import com.crossoverjie.cim.client.vo.req.LoginReqVO; 10 import com.crossoverjie.cim.client.vo.req.LoginReqVO;
10 import com.crossoverjie.cim.client.vo.req.P2PReqVO; 11 import com.crossoverjie.cim.client.vo.req.P2PReqVO;
11 import com.crossoverjie.cim.client.vo.res.CIMServerResVO; 12 import com.crossoverjie.cim.client.vo.res.CIMServerResVO;
12 import com.crossoverjie.cim.client.vo.res.OnlineUsersResVO; 13 import com.crossoverjie.cim.client.vo.res.OnlineUsersResVO;
13 import com.crossoverjie.cim.common.enums.StatusEnum; 14 import com.crossoverjie.cim.common.enums.StatusEnum;
  15 +import com.crossoverjie.cim.common.exception.CIMException;
14 import com.crossoverjie.cim.common.res.BaseResponse; 16 import com.crossoverjie.cim.common.res.BaseResponse;
15 import okhttp3.*; 17 import okhttp3.*;
16 import org.slf4j.Logger; 18 import org.slf4j.Logger;
@@ -140,6 +142,13 @@ public class RouteRequestImpl implements RouteRequest { @@ -140,6 +142,13 @@ public class RouteRequestImpl implements RouteRequest {
140 //重复失败 142 //重复失败
141 if (!cimServerResVO.getCode().equals(StatusEnum.SUCCESS.getCode())){ 143 if (!cimServerResVO.getCode().equals(StatusEnum.SUCCESS.getCode())){
142 echoService.echo(cimServerResVO.getMessage()); 144 echoService.echo(cimServerResVO.getMessage());
  145 +
  146 + // when client in reConnect state, could not exit.
  147 + if (ContextHolder.getReconnect()){
  148 + echoService.echo("###{}###", StatusEnum.RECONNECT_FAIL.getMessage());
  149 + throw new CIMException(StatusEnum.RECONNECT_FAIL);
  150 + }
  151 +
143 System.exit(-1); 152 System.exit(-1);
144 } 153 }
145 154
@@ -37,7 +37,7 @@ public class ShutDownCommand implements InnerCommand { @@ -37,7 +37,7 @@ public class ShutDownCommand implements InnerCommand {
37 private MsgLogger msgLogger; 37 private MsgLogger msgLogger;
38 38
39 @Resource(name = "callBackThreadPool") 39 @Resource(name = "callBackThreadPool")
40 - private ThreadPoolExecutor executor; 40 + private ThreadPoolExecutor callBackExecutor;
41 41
42 @Autowired 42 @Autowired
43 private EchoService echoService ; 43 private EchoService echoService ;
@@ -55,10 +55,10 @@ public class ShutDownCommand implements InnerCommand { @@ -55,10 +55,10 @@ public class ShutDownCommand implements InnerCommand {
55 shutDownMsg.shutdown(); 55 shutDownMsg.shutdown();
56 routeRequest.offLine(); 56 routeRequest.offLine();
57 msgLogger.stop(); 57 msgLogger.stop();
58 - executor.shutdown(); 58 + callBackExecutor.shutdown();
59 ringBufferWheel.stop(false); 59 ringBufferWheel.stop(false);
60 try { 60 try {
61 - while (!executor.awaitTermination(1, TimeUnit.SECONDS)) { 61 + while (!callBackExecutor.awaitTermination(1, TimeUnit.SECONDS)) {
62 echoService.echo("thread pool closing"); 62 echoService.echo("thread pool closing");
63 } 63 }
64 cimClient.close(); 64 cimClient.close();
  1 +package com.crossoverjie.cim.client.thread;
  2 +
  3 +/**
  4 + * Function: Something about of client runtime sign.
  5 + *
  6 + * @author crossoverJie
  7 + * Date: 2020-04-13 02:10
  8 + * @since JDK 1.8
  9 + */
  10 +public class ContextHolder {
  11 + private static final ThreadLocal<Boolean> IS_RECONNECT = new ThreadLocal<>() ;
  12 +
  13 + public static void setReconnect(boolean reconnect){
  14 + IS_RECONNECT.set(reconnect);
  15 + }
  16 +
  17 + public static Boolean getReconnect(){
  18 + return IS_RECONNECT.get() ;
  19 + }
  20 +
  21 + public static void clear(){
  22 + IS_RECONNECT.remove();
  23 + }
  24 +}
@@ -27,7 +27,9 @@ public enum StatusEnum { @@ -27,7 +27,9 @@ public enum StatusEnum {
27 /** 账号不在线 */ 27 /** 账号不在线 */
28 OFF_LINE("7000", "你选择的账号不在线,请重新选择!"), 28 OFF_LINE("7000", "你选择的账号不在线,请重新选择!"),
29 29
30 - SERVER_NOT_AVAILABLE("7100", "CIM server is not available, please try again later!"), 30 + SERVER_NOT_AVAILABLE("7100", "cim server is not available, please try again later!"),
  31 +
  32 + RECONNECT_FAIL("7200", "reconnect fail, continue to retry!"),
31 33
32 /** 登录信息不匹配 */ 34 /** 登录信息不匹配 */
33 ACCOUNT_NOT_MATCH("9100", "The User information you have used is incorrect!"), 35 ACCOUNT_NOT_MATCH("9100", "The User information you have used is incorrect!"),
@@ -2,6 +2,8 @@ package com.crossoverjie.cim.route.cache; @@ -2,6 +2,8 @@ package com.crossoverjie.cim.route.cache;
2 2
3 import com.crossoverjie.cim.route.kit.ZKit; 3 import com.crossoverjie.cim.route.kit.ZKit;
4 import com.google.common.cache.LoadingCache; 4 import com.google.common.cache.LoadingCache;
  5 +import org.slf4j.Logger;
  6 +import org.slf4j.LoggerFactory;
5 import org.springframework.beans.factory.annotation.Autowired; 7 import org.springframework.beans.factory.annotation.Autowired;
6 import org.springframework.stereotype.Component; 8 import org.springframework.stereotype.Component;
7 9
@@ -20,6 +22,7 @@ import java.util.concurrent.atomic.AtomicLong; @@ -20,6 +22,7 @@ import java.util.concurrent.atomic.AtomicLong;
20 @Component 22 @Component
21 public class ServerCache { 23 public class ServerCache {
22 24
  25 + private static Logger logger = LoggerFactory.getLogger(ServerCache.class) ;
23 26
24 @Autowired 27 @Autowired
25 private LoadingCache<String, String> cache; 28 private LoadingCache<String, String> cache;
@@ -43,7 +46,13 @@ public class ServerCache { @@ -43,7 +46,13 @@ public class ServerCache {
43 public void updateCache(List<String> currentChilds) { 46 public void updateCache(List<String> currentChilds) {
44 cache.invalidateAll(); 47 cache.invalidateAll();
45 for (String currentChild : currentChilds) { 48 for (String currentChild : currentChilds) {
46 - String key = currentChild.split("-")[1]; 49 + // currentChild=ip-127.0.0.1:11212:9082 or 127.0.0.1:11212:9082
  50 + String key ;
  51 + if (currentChild.split("-").length == 2){
  52 + key = currentChild.split("-")[1];
  53 + }else {
  54 + key = currentChild ;
  55 + }
47 addCache(key); 56 addCache(key);
48 } 57 }
49 } 58 }
@@ -54,7 +63,7 @@ public class ServerCache { @@ -54,7 +63,7 @@ public class ServerCache {
54 * 63 *
55 * @return 64 * @return
56 */ 65 */
57 - public List<String> getAll() { 66 + public List<String> getServerList() {
58 67
59 List<String> list = new ArrayList<>(); 68 List<String> list = new ArrayList<>();
60 69
@@ -72,4 +81,11 @@ public class ServerCache { @@ -72,4 +81,11 @@ public class ServerCache {
72 81
73 } 82 }
74 83
  84 + /**
  85 + * rebuild cache list
  86 + */
  87 + public void rebuildCacheList(){
  88 + updateCache(getServerList()) ;
  89 + }
  90 +
75 } 91 }
@@ -153,7 +153,7 @@ public class RouteController { @@ -153,7 +153,7 @@ public class RouteController {
153 BaseResponse<CIMServerResVO> res = new BaseResponse(); 153 BaseResponse<CIMServerResVO> res = new BaseResponse();
154 154
155 // check server available 155 // check server available
156 - String server = routeHandle.routeServer(serverCache.getAll(),String.valueOf(loginReqVO.getUserId())); 156 + String server = routeHandle.routeServer(serverCache.getServerList(),String.valueOf(loginReqVO.getUserId()));
157 RouteInfo routeInfo = RouteInfoParseUtil.parse(server); 157 RouteInfo routeInfo = RouteInfoParseUtil.parse(server);
158 commonBizService.checkServerAvailable(routeInfo); 158 commonBizService.checkServerAvailable(routeInfo);
159 159
@@ -3,7 +3,11 @@ package com.crossoverjie.cim.route.service; @@ -3,7 +3,11 @@ package com.crossoverjie.cim.route.service;
3 import com.crossoverjie.cim.common.enums.StatusEnum; 3 import com.crossoverjie.cim.common.enums.StatusEnum;
4 import com.crossoverjie.cim.common.exception.CIMException; 4 import com.crossoverjie.cim.common.exception.CIMException;
5 import com.crossoverjie.cim.common.pojo.RouteInfo; 5 import com.crossoverjie.cim.common.pojo.RouteInfo;
  6 +import com.crossoverjie.cim.route.cache.ServerCache;
6 import com.crossoverjie.cim.route.kit.NetAddressIsReachable; 7 import com.crossoverjie.cim.route.kit.NetAddressIsReachable;
  8 +import org.slf4j.Logger;
  9 +import org.slf4j.LoggerFactory;
  10 +import org.springframework.beans.factory.annotation.Autowired;
7 import org.springframework.stereotype.Component; 11 import org.springframework.stereotype.Component;
8 12
9 /** 13 /**
@@ -15,6 +19,11 @@ import org.springframework.stereotype.Component; @@ -15,6 +19,11 @@ import org.springframework.stereotype.Component;
15 */ 19 */
16 @Component 20 @Component
17 public class CommonBizService { 21 public class CommonBizService {
  22 + private static Logger logger = LoggerFactory.getLogger(CommonBizService.class) ;
  23 +
  24 +
  25 + @Autowired
  26 + private ServerCache serverCache ;
18 27
19 /** 28 /**
20 * check ip and port 29 * check ip and port
@@ -23,6 +32,11 @@ public class CommonBizService { @@ -23,6 +32,11 @@ public class CommonBizService {
23 public void checkServerAvailable(RouteInfo routeInfo){ 32 public void checkServerAvailable(RouteInfo routeInfo){
24 boolean reachable = NetAddressIsReachable.checkAddressReachable(routeInfo.getIp(), routeInfo.getCimServerPort(), 1000); 33 boolean reachable = NetAddressIsReachable.checkAddressReachable(routeInfo.getIp(), routeInfo.getCimServerPort(), 1000);
25 if (!reachable) { 34 if (!reachable) {
  35 + logger.error("ip={}, port={} are not available", routeInfo.getIp(), routeInfo.getCimServerPort());
  36 +
  37 + // rebuild cache
  38 + serverCache.rebuildCacheList();
  39 +
26 throw new CIMException(StatusEnum.SERVER_NOT_AVAILABLE) ; 40 throw new CIMException(StatusEnum.SERVER_NOT_AVAILABLE) ;
27 } 41 }
28 42
@@ -22,19 +22,19 @@ app.zk.connect.timeout=15000 @@ -22,19 +22,19 @@ app.zk.connect.timeout=15000
22 app.zk.root=/route 22 app.zk.root=/route
23 23
24 #路由策略,轮询 24 #路由策略,轮询
25 -#app.route.way=com.crossoverjie.cim.common.route.algorithm.loop.LoopHandle 25 +app.route.way=com.crossoverjie.cim.common.route.algorithm.loop.LoopHandle
26 26
27 #路由策略,随机 27 #路由策略,随机
28 #app.route.way=com.crossoverjie.cim.common.route.algorithm.random.RandomHandle 28 #app.route.way=com.crossoverjie.cim.common.route.algorithm.random.RandomHandle
29 29
30 #路由策略,一致性 hash 30 #路由策略,一致性 hash
31 -app.route.way=com.crossoverjie.cim.common.route.algorithm.consistenthash.ConsistentHashHandle 31 +#app.route.way=com.crossoverjie.cim.common.route.algorithm.consistenthash.ConsistentHashHandle
32 32
33 #一致性 hash 算法具体实现--自定义有序 map 33 #一致性 hash 算法具体实现--自定义有序 map
34 #app.route.way.consitenthash=com.crossoverjie.cim.common.route.algorithm.consistenthash.SortArrayMapConsistentHash 34 #app.route.way.consitenthash=com.crossoverjie.cim.common.route.algorithm.consistenthash.SortArrayMapConsistentHash
35 35
36 #一致性 hash 算法具体实现--TreeMap 36 #一致性 hash 算法具体实现--TreeMap
37 -app.route.way.consitenthash=com.crossoverjie.cim.common.route.algorithm.consistenthash.TreeMapConsistentHash 37 +#app.route.way.consitenthash=com.crossoverjie.cim.common.route.algorithm.consistenthash.TreeMapConsistentHash
38 38
39 # Redis 配置 39 # Redis 配置
40 spring.redis.host=xx 40 spring.redis.host=xx