作者 crossoverJie
提交者 GitHub

Merge pull request #33 from crossoverJie/cim-1.0.4

cim 1.0.4
正在显示 19 个修改的文件 包含 848 行增加11 行删除
package com.crossoverjie.cim.client.handle;
import com.crossoverjie.cim.client.service.ShutDownMsg;
import com.crossoverjie.cim.client.thread.ReConnectJob;
import com.crossoverjie.cim.client.util.SpringBeanFactory;
import com.crossoverjie.cim.common.constant.Constants;
... ... @@ -37,6 +38,8 @@ public class CIMClientHandle extends SimpleChannelInboundHandler<CIMResponseProt
private ScheduledExecutorService scheduledExecutorService ;
private ShutDownMsg shutDownMsg ;
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
... ... @@ -71,11 +74,20 @@ public class CIMClientHandle extends SimpleChannelInboundHandler<CIMResponseProt
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
LOGGER.info("客户端断开了,重新连接!");
if (shutDownMsg == null){
shutDownMsg = SpringBeanFactory.getBean(ShutDownMsg.class) ;
}
//用户主动退出,不执行重连逻辑
if (shutDownMsg.checkStatus()){
return;
}
if (scheduledExecutorService == null){
scheduledExecutorService = SpringBeanFactory.getBean("scheduledTask",ScheduledExecutorService.class) ;
}
LOGGER.info("客户端断开了,重新连接!");
// TODO: 2019-01-22 后期可以改为不用定时任务,连上后就关闭任务 节省性能。
scheduledExecutorService.scheduleAtFixedRate(new ReConnectJob(ctx),0,10, TimeUnit.SECONDS) ;
}
... ...
package com.crossoverjie.cim.client.service;
import org.springframework.stereotype.Component;
/**
* Function:
*
* @author crossoverJie
* Date: 2019-02-27 16:17
* @since JDK 1.8
*/
@Component
public class ShutDownMsg {
private boolean isCommand ;
/**
* 置为用户主动退出状态
*/
public void shutdown(){
isCommand = true ;
}
public boolean checkStatus(){
return isCommand ;
}
}
... ...
... ... @@ -25,6 +25,9 @@ public class QueryHistoryCommand implements InnerCommand {
@Override
public void process(String msg) {
String[] split = msg.split(" ");
if (split.length < 2){
return;
}
String res = msgLogger.query(split[1]);
System.out.println(res);
}
... ...
... ... @@ -4,6 +4,7 @@ import com.crossoverjie.cim.client.client.CIMClient;
import com.crossoverjie.cim.client.service.InnerCommand;
import com.crossoverjie.cim.client.service.MsgLogger;
import com.crossoverjie.cim.client.service.RouteRequest;
import com.crossoverjie.cim.client.service.ShutDownMsg;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
... ... @@ -36,9 +37,14 @@ public class ShutDownCommand implements InnerCommand {
@Resource(name = "callBackThreadPool")
private ThreadPoolExecutor executor;
@Autowired
private ShutDownMsg shutDownMsg ;
@Override
public void process(String msg) {
LOGGER.info("系统关闭中。。。。");
shutDownMsg.shutdown();
routeRequest.offLine();
msgLogger.stop();
executor.shutdown();
... ...
... ... @@ -45,8 +45,8 @@ cim.clear.route.request.url=http://45.78.28.220:8083/offLine
#cim.clear.route.request.url=http://localhost:8083/offLine
# 客户端唯一ID
cim.user.id=1545574841528
cim.user.userName=zhangsan
cim.user.id=1551267098213
cim.user.userName=test3
# 回调线程队列大小
cim.callback.thread.queue.size = 2
... ...
package com.crossoverjie.cim.common.data.construct;
import java.util.Arrays;
import java.util.Comparator;
/**
* Function:根据 key 排序的 Map
*
* @author crossoverJie
* Date: 2019-02-25 18:17
* @since JDK 1.8
*/
public class SortArrayMap {
/**
* 核心数组
*/
private Node[] buckets;
private static final int DEFAULT_SIZE = 10;
/**
* 数组大小
*/
private int size = 0;
public SortArrayMap() {
buckets = new Node[DEFAULT_SIZE];
}
/**
* 写入数据
* @param key
* @param value
*/
public void add(Long key, String value) {
checkSize(size + 1);
Node node = new Node(key, value);
buckets[size++] = node;
}
/**
* 校验是否需要扩容
* @param size
*/
private void checkSize(int size) {
if (size >= buckets.length) {
//扩容自身的 3/2
int oldLen = buckets.length;
int newLen = oldLen + (oldLen >> 1);
buckets = Arrays.copyOf(buckets, newLen);
}
}
/**
* 顺时针取出数据
* @param key
* @return
*/
public String firstNodeValue(long key) {
if (size == 0){
return null ;
}
for (Node bucket : buckets) {
if (bucket == null){
continue;
}
if (bucket.key >= key) {
return bucket.value;
}
}
return buckets[0].value;
}
/**
* 排序
*/
public void sort() {
Arrays.sort(buckets, 0, size, new Comparator<Node>() {
@Override
public int compare(Node o1, Node o2) {
if (o1.key > o2.key) {
return 1;
} else {
return -1;
}
}
});
}
public void print() {
for (Node bucket : buckets) {
if (bucket == null) {
continue;
}
System.out.println(bucket.toString());
}
}
public int size() {
return size;
}
/**
* 数据节点
*/
private class Node {
public Long key;
public String value;
public Node(Long key, String value) {
this.key = key;
this.value = value;
}
@Override
public String toString() {
return "Node{" +
"key=" + key +
", value='" + value + '\'' +
'}';
}
}
}
... ...
package com.crossoverjie.cim.common.route.algorithm;
import java.util.List;
/**
* Function:
*
* @author crossoverJie
* Date: 2019-02-27 00:31
* @since JDK 1.8
*/
public interface RouteHandle {
/**
* 再一批服务器里进行路由
* @param values
* @param key
* @return
*/
String routeServer(List<String> values,String key) ;
}
... ...
package com.crossoverjie.cim.common.route.algorithm.consistenthash;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.List;
/**
* Function:一致性 hash 算法抽象类
*
* @author crossoverJie
* Date: 2019-02-27 00:35
* @since JDK 1.8
*/
public abstract class AbstractConsistentHash {
/**
* 新增节点
* @param key
* @param value
*/
protected abstract void add(long key,String value);
/**
* 排序节点,数据结构自身支持排序可以不用重写
*/
protected void sort(){}
/**
* 根据当前的 key 通过一致性 hash 算法的规则取出一个节点
* @param value
* @return
*/
protected abstract String getFirstNodeValue(String value);
/**
* 传入节点列表以及客户端信息获取一个服务节点
* @param values
* @param key
* @return
*/
public String process(List<String> values,String key){
for (String value : values) {
add(hash(value), value);
}
sort();
return getFirstNodeValue(key) ;
}
/**
* hash 运算
* @param value
* @return
*/
public Long hash(String value){
MessageDigest md5;
try {
md5 = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("MD5 not supported", e);
}
md5.reset();
byte[] keyBytes = null;
try {
keyBytes = value.getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("Unknown string :" + value, e);
}
md5.update(keyBytes);
byte[] digest = md5.digest();
// hash code, Truncate to 32-bits
long hashCode = ((long) (digest[3] & 0xFF) << 24)
| ((long) (digest[2] & 0xFF) << 16)
| ((long) (digest[1] & 0xFF) << 8)
| (digest[0] & 0xFF);
long truncateHashCode = hashCode & 0xffffffffL;
return truncateHashCode;
}
}
... ...
package com.crossoverjie.cim.common.route.algorithm.consistenthash;
import com.crossoverjie.cim.common.route.algorithm.RouteHandle;
import java.util.List;
/**
* Function:
*
* @author crossoverJie
* Date: 2019-02-27 00:33
* @since JDK 1.8
*/
public class ConsistentHashHandle implements RouteHandle {
private AbstractConsistentHash hash ;
public void setHash(AbstractConsistentHash hash) {
this.hash = hash;
}
@Override
public String routeServer(List<String> values, String key) {
return hash.process(values, key);
}
}
... ...
package com.crossoverjie.cim.common.route.algorithm.consistenthash;
import com.crossoverjie.cim.common.data.construct.SortArrayMap;
/**
* Function:自定义排序 Map 实现
*
* @author crossoverJie
* Date: 2019-02-27 00:38
* @since JDK 1.8
*/
public class SortArrayMapConsistentHash extends AbstractConsistentHash {
private SortArrayMap sortArrayMap = new SortArrayMap();
/**
* 虚拟节点数量
*/
private static final int VIRTUAL_NODE_SIZE = 2 ;
@Override
public void add(long key, String value) {
for (int i = 0; i < VIRTUAL_NODE_SIZE; i++) {
Long hash = super.hash("vir" + key + i);
sortArrayMap.add(hash,value);
}
sortArrayMap.add(key, value);
}
@Override
public void sort() {
sortArrayMap.sort();
}
@Override
public String getFirstNodeValue(String value) {
long hash = super.hash(value);
System.out.println("value=" + value + " hash = " + hash);
return sortArrayMap.firstNodeValue(hash);
}
}
... ...
package com.crossoverjie.cim.common.route.algorithm.consistenthash;
import java.util.SortedMap;
import java.util.TreeMap;
/**
* Function:TreeMap 实现
*
* @author crossoverJie
* Date: 2019-02-27 01:16
* @since JDK 1.8
*/
public class TreeMapConsistentHash extends AbstractConsistentHash {
private TreeMap<Long,String> treeMap = new TreeMap<Long, String>() ;
/**
* 虚拟节点数量
*/
private static final int VIRTUAL_NODE_SIZE = 2 ;
@Override
public void add(long key, String value) {
for (int i = 0; i < VIRTUAL_NODE_SIZE; i++) {
Long hash = super.hash("vir" + key + i);
treeMap.put(hash,value);
}
treeMap.put(key, value);
}
@Override
public String getFirstNodeValue(String value) {
long hash = super.hash(value);
System.out.println("value=" + value + " hash = " + hash);
SortedMap<Long, String> last = treeMap.tailMap(hash);
if (!last.isEmpty()) {
return last.get(last.firstKey());
}
return treeMap.firstEntry().getValue();
}
}
... ...
package com.crossoverjie.cim.common.route.algorithm.loop;
import com.crossoverjie.cim.common.route.algorithm.RouteHandle;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;
/**
* Function:
*
* @author crossoverJie
* Date: 2019-02-27 15:13
* @since JDK 1.8
*/
public class LoopHandle implements RouteHandle {
private AtomicLong index = new AtomicLong();
@Override
public String routeServer(List<String> values,String key) {
if (values.size() == 0) {
throw new RuntimeException("CIM 服务器可用服务列表为空");
}
Long position = index.incrementAndGet() % values.size();
if (position < 0) {
position = 0L;
}
return values.get(position.intValue());
}
}
... ...
package com.crossoverjie.cim.common.data.construct;
import org.junit.Test;
import java.util.SortedMap;
import java.util.TreeMap;
public class SortArrayMapTest {
@Test
public void ad() {
SortArrayMap map = new SortArrayMap() ;
for (int i = 0; i < 9; i++) {
map.add(Long.valueOf(i) ,"127.0.0." + i);
}
map.print();
System.out.println(map.size());
}
@Test
public void add() {
SortArrayMap map = new SortArrayMap() ;
for (int i = 0; i < 10; i++) {
map.add(Long.valueOf(i) ,"127.0.0." + i);
}
map.print();
System.out.println(map.size());
}
@Test
public void add2() {
SortArrayMap map = new SortArrayMap() ;
for (int i = 0; i < 20; i++) {
map.add(Long.valueOf(i) ,"127.0.0." + i);
}
map.sort();
map.print();
System.out.println(map.size());
}
@Test
public void add3() {
SortArrayMap map = new SortArrayMap() ;
map.add(100L,"127.0.0.100");
map.add(10L,"127.0.0.10");
map.add(8L,"127.0.0.8");
map.add(1000L,"127.0.0.1000");
map.print();
System.out.println(map.size());
}
@Test
public void firstNode() {
SortArrayMap map = new SortArrayMap() ;
map.add(100L,"127.0.0.100");
map.add(10L,"127.0.0.10");
map.add(8L,"127.0.0.8");
map.add(1000L,"127.0.0.1000");
map.sort();
map.print();
String value = map.firstNodeValue(101);
System.out.println(value);
}
@Test
public void firstNode2() {
SortArrayMap map = new SortArrayMap() ;
map.add(100L,"127.0.0.100");
map.add(10L,"127.0.0.10");
map.add(8L,"127.0.0.8");
map.add(1000L,"127.0.0.1000");
map.sort();
map.print();
String value = map.firstNodeValue(1);
System.out.println(value);
}
@Test
public void firstNode3() {
SortArrayMap map = new SortArrayMap() ;
map.add(100L,"127.0.0.100");
map.add(10L,"127.0.0.10");
map.add(8L,"127.0.0.8");
map.add(1000L,"127.0.0.1000");
map.sort();
map.print();
String value = map.firstNodeValue(1001);
System.out.println(value);
}
@Test
public void firstNode4() {
SortArrayMap map = new SortArrayMap() ;
map.add(100L,"127.0.0.100");
map.add(10L,"127.0.0.10");
map.add(8L,"127.0.0.8");
map.add(1000L,"127.0.0.1000");
map.sort();
map.print();
String value = map.firstNodeValue(9);
System.out.println(value);
}
@Test
public void add4() {
SortArrayMap map = new SortArrayMap() ;
map.add(100L,"127.0.0.100");
map.add(10L,"127.0.0.10");
map.add(8L,"127.0.0.8");
map.add(1000L,"127.0.0.1000");
map.sort();
map.print();
System.out.println(map.size());
}
int count = 1000000 ;
@Test
public void add5() {
SortArrayMap map = new SortArrayMap() ;
long star = System.currentTimeMillis() ;
for (int i = 0; i < count; i++) {
double d = Math.random();
int ran = (int)(d*100);
map.add(Long.valueOf(i + ran) ,"127.0.0." + i);
}
map.sort();
long end = System.currentTimeMillis() ;
System.out.println("排序耗时 " + (end -star));
System.out.println(map.size());
}
@Test
public void add6(){
SortArrayMap map = new SortArrayMap() ;
long star = System.currentTimeMillis() ;
for (int i = 0; i < count; i++) {
double d = Math.random();
int ran = (int)(d*100);
map.add(Long.valueOf(i + ran) ,"127.0.0." + i);
}
long end = System.currentTimeMillis() ;
System.out.println("不排耗时 " + (end -star));
System.out.println(map.size());
}
@Test
public void add7(){
TreeMap<Long,String> treeMap = new TreeMap<Long, String>() ;
long star = System.currentTimeMillis() ;
for (int i = 0; i < count; i++) {
double d = Math.random();
int ran = (int)(d*100);
treeMap.put(Long.valueOf(i + ran) ,"127.0.0." + i);
}
long end = System.currentTimeMillis() ;
System.out.println("耗时 " + (end -star));
System.out.println(treeMap.size());
}
@Test
public void add8(){
TreeMap<Long,String> map = new TreeMap<Long, String>() ;
map.put(100L,"127.0.0.100");
map.put(10L,"127.0.0.10");
map.put(8L,"127.0.0.8");
map.put(1000L,"127.0.0.1000");
SortedMap<Long, String> last = map.tailMap(101L);
if (!last.isEmpty()) {
System.out.println(last.get(last.firstKey()));
}else {
System.out.println(map.firstEntry().getValue());
}
}
}
\ No newline at end of file
... ...
package com.crossoverjie.cim.common.route.algorithm.consistenthash;
import org.junit.Assert;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
public class SortArrayMapConsistentHashTest {
@Test
public void getFirstNodeValue() {
AbstractConsistentHash map = new SortArrayMapConsistentHash() ;
List<String> strings = new ArrayList<String>();
for (int i = 0; i < 10; i++) {
strings.add("127.0.0." + i) ;
}
String process = map.process(strings,"zhangsan");
System.out.println(process);
Assert.assertEquals("127.0.0.2",process);
}
@Test
public void getFirstNodeValue2() {
AbstractConsistentHash map = new SortArrayMapConsistentHash() ;
List<String> strings = new ArrayList<String>();
for (int i = 0; i < 10; i++) {
strings.add("127.0.0." + i) ;
}
String process = map.process(strings,"zhangsan2");
System.out.println(process);
Assert.assertEquals("127.0.0.3",process);
}
@Test
public void getFirstNodeValue3() {
AbstractConsistentHash map = new SortArrayMapConsistentHash() ;
List<String> strings = new ArrayList<String>();
for (int i = 0; i < 10; i++) {
strings.add("127.0.0." + i) ;
}
String process = map.process(strings,"1551253899106");
System.out.println(process);
Assert.assertEquals("127.0.0.6",process);
}
@Test
public void getFirstNodeValue4() {
AbstractConsistentHash map = new SortArrayMapConsistentHash() ;
List<String> strings = new ArrayList<String>();
strings.add("45.78.28.220:9000:8081") ;
strings.add("45.78.28.220:9100:9081") ;
String process = map.process(strings,"1551253899106");
System.out.println(process);
Assert.assertEquals("45.78.28.220:9000:8081",process);
}
@Test
public void getFirstNodeValue5() {
AbstractConsistentHash map = new SortArrayMapConsistentHash() ;
List<String> strings = new ArrayList<String>();
strings.add("45.78.28.220:9000:8081") ;
strings.add("45.78.28.220:9100:9081") ;
strings.add("45.78.28.220:9100:10081") ;
String process = map.process(strings,"1551253899106");
System.out.println(process);
Assert.assertEquals("45.78.28.220:9000:8081",process);
}
@Test
public void getFirstNodeValue6() {
AbstractConsistentHash map = new SortArrayMapConsistentHash() ;
List<String> strings = new ArrayList<String>();
strings.add("45.78.28.220:9000:8081") ;
strings.add("45.78.28.220:9100:9081") ;
strings.add("45.78.28.220:9100:10081") ;
String process = map.process(strings,"1551253899106");
System.out.println(process);
Assert.assertEquals("45.78.28.220:9000:8081",process);
}
@Test
public void getFirstNodeValue7() {
AbstractConsistentHash map = new SortArrayMapConsistentHash() ;
List<String> strings = new ArrayList<String>();
strings.add("45.78.28.220:9000:8081") ;
strings.add("45.78.28.220:9100:9081") ;
strings.add("45.78.28.220:9100:10081") ;
strings.add("45.78.28.220:9100:00081") ;
String process = map.process(strings,"1551253899106");
System.out.println(process);
Assert.assertEquals("45.78.28.220:9000:8081",process);
}
}
\ No newline at end of file
... ...
package com.crossoverjie.cim.common.route.algorithm.consistenthash;
import org.junit.Assert;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
public class TreeMapConsistentHashTest {
@Test
public void getFirstNodeValue() {
AbstractConsistentHash map = new TreeMapConsistentHash() ;
List<String> strings = new ArrayList<String>();
for (int i = 0; i < 10; i++) {
strings.add("127.0.0." + i) ;
}
String process = map.process(strings,"zhangsan");
System.out.println(process);
Assert.assertEquals("127.0.0.2",process);
}
@Test
public void getFirstNodeValue2() {
AbstractConsistentHash map = new TreeMapConsistentHash() ;
List<String> strings = new ArrayList<String>();
for (int i = 0; i < 10; i++) {
strings.add("127.0.0." + i) ;
}
String process = map.process(strings,"zhangsan2");
System.out.println(process);
Assert.assertEquals("127.0.0.3",process);
}
@Test
public void getFirstNodeValue3() {
AbstractConsistentHash map = new TreeMapConsistentHash() ;
List<String> strings = new ArrayList<String>();
for (int i = 0; i < 10; i++) {
strings.add("127.0.0." + i) ;
}
String process = map.process(strings,"1551253899106");
System.out.println(process);
Assert.assertEquals("127.0.0.6",process);
}
}
\ No newline at end of file
... ...
... ... @@ -25,11 +25,17 @@ public class AppConfiguration {
@Value("${app.zk.connect.timeout}")
private int zkConnectTimeout;
@Value("${app.route.way}")
private String routeWay;
@Value("${app.route.way.consitenthash}")
private String consistentHashWay;
public int getZkConnectTimeout() {
return zkConnectTimeout;
}
public int getPort() {
return port;
}
... ... @@ -54,4 +60,19 @@ public class AppConfiguration {
this.zkAddr = zkAddr;
}
public String getRouteWay() {
return routeWay;
}
public void setRouteWay(String routeWay) {
this.routeWay = routeWay;
}
public String getConsistentHashWay() {
return consistentHashWay;
}
public void setConsistentHashWay(String consistentHashWay) {
this.consistentHashWay = consistentHashWay;
}
}
... ...
package com.crossoverjie.cim.route.config;
import com.crossoverjie.cim.common.route.algorithm.RouteHandle;
import com.crossoverjie.cim.common.route.algorithm.consistenthash.AbstractConsistentHash;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
... ... @@ -13,28 +15,29 @@ import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;
/**
* Function:
*
* @author crossoverJie
* Date: 2018/12/23 00:25
* Date: 2018/12/23 00:25
* @since JDK 1.8
*/
@Configuration
public class BeanConfig {
@Autowired
private AppConfiguration appConfiguration ;
private AppConfiguration appConfiguration;
@Bean
public ZkClient buildZKClient(){
public ZkClient buildZKClient() {
return new ZkClient(appConfiguration.getZkAddr(), appConfiguration.getZkConnectTimeout());
}
@Bean
public LoadingCache<String,String> buildCache(){
public LoadingCache<String, String> buildCache() {
return CacheBuilder.newBuilder()
.build(new CacheLoader<String, String>() {
@Override
... ... @@ -47,6 +50,7 @@ public class BeanConfig {
/**
* Redis bean
*
* @param factory
* @return
*/
... ... @@ -62,6 +66,7 @@ public class BeanConfig {
/**
* http client
*
* @return okHttp
*/
@Bean
... ... @@ -69,8 +74,27 @@ public class BeanConfig {
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.connectTimeout(30, TimeUnit.SECONDS)
.readTimeout(10, TimeUnit.SECONDS)
.writeTimeout(10,TimeUnit.SECONDS)
.writeTimeout(10, TimeUnit.SECONDS)
.retryOnConnectionFailure(true);
return builder.build();
}
@Bean
public RouteHandle buildRouteHandle() throws Exception {
String routeWay = appConfiguration.getRouteWay();
RouteHandle routeHandle = (RouteHandle) Class.forName(routeWay).newInstance();
if (routeWay.contains("ConsistentHash")) {
//一致性 hash 算法
Method method = Class.forName(routeWay).getMethod("setHash", AbstractConsistentHash.class);
AbstractConsistentHash consistentHash = (AbstractConsistentHash)
Class.forName(appConfiguration.getConsistentHashWay()).newInstance();
method.invoke(routeHandle,consistentHash) ;
return routeHandle ;
} else {
return routeHandle;
}
}
}
... ...
... ... @@ -5,6 +5,7 @@ import com.crossoverjie.cim.common.exception.CIMException;
import com.crossoverjie.cim.common.pojo.CIMUserInfo;
import com.crossoverjie.cim.common.res.BaseResponse;
import com.crossoverjie.cim.common.res.NULLBody;
import com.crossoverjie.cim.common.route.algorithm.RouteHandle;
import com.crossoverjie.cim.route.cache.ServerCache;
import com.crossoverjie.cim.route.service.AccountService;
import com.crossoverjie.cim.route.service.UserInfoCacheService;
... ... @@ -48,6 +49,10 @@ public class RouteController {
@Autowired
private UserInfoCacheService userInfoCacheService ;
@Autowired
private RouteHandle routeHandle ;
@ApiOperation("群聊 API")
@RequestMapping(value = "groupRoute", method = RequestMethod.POST)
@ResponseBody()
... ... @@ -145,7 +150,8 @@ public class RouteController {
//登录校验
StatusEnum status = accountService.login(loginReqVO);
if (status == StatusEnum.SUCCESS) {
String server = serverCache.selectServer();
String server = routeHandle.routeServer(serverCache.getAll(),String.valueOf(loginReqVO.getUserId()));
String[] serverInfo = server.split(":");
CIMServerResVO vo = new CIMServerResVO(serverInfo[0], Integer.parseInt(serverInfo[1]),Integer.parseInt(serverInfo[2]));
... ...
... ... @@ -21,7 +21,17 @@ app.zk.connect.timeout=15000
# zk 注册根节点
app.zk.root=/route
#路由策略,轮询
#app.route.way=com.crossoverjie.cim.common.route.algorithm.loop.LoopHandle
#路由策略,一致性 hash
app.route.way=com.crossoverjie.cim.common.route.algorithm.consistenthash.ConsistentHashHandle
#一致性 hash 算法具体实现--自定义有序 map
#app.route.way.consitenthash=com.crossoverjie.cim.common.route.algorithm.consistenthash.SortArrayMapConsistentHash
#一致性 hash 算法具体实现--TreeMap
app.route.way.consitenthash=com.crossoverjie.cim.common.route.algorithm.consistenthash.TreeMapConsistentHash
# Redis 配置
spring.redis.host=47.98.194.60
... ...