From e332c9c4ccae60d9e80208187be1232db061bd4a Mon Sep 17 00:00:00 2001 From: icanci Date: Sat, 4 Feb 2023 22:09:36 +0800 Subject: [PATCH] LoadBalancingSupport --- .../loopstack/ras/client/aop/RpcCallAop.java | 10 +- .../ConsistencyHashLoadBalancing.java | 2 +- .../FastestCallSpeedLoadBalancing.java | 48 ++++- .../loadbalancing/FirstLoadBalancing.java | 2 +- .../loadbalancing/InOrderLoadBalancing.java | 2 +- .../loadbalancing/LastLoadBalancing.java | 2 +- .../LeastFrequentlyUsedLoadBalancing.java | 8 +- .../LeastRecentlyUsedLoadBalancing.java | 8 +- .../loadbalancing/LoadBalancingSupport.java | 71 +++++++ .../loadbalancing/RandomLoadBalancing.java | 2 +- .../FastestCallSpeedLoadBalancingHolder.java | 183 ++++++++++++++++++ .../model/InOrderBalancingHolder.java | 2 +- .../model/LoadBalancingHolder.java | 1 + .../ras/client/facade/RpcCallFacade.java | 24 ++- .../cache/loadbalancing/test/TreeSetTest.java | 77 ++++++++ .../cache/loadbalancing/test/UrlTest.java | 61 ++++++ .../cn/icanci/loopstack/ras/server/Test.java | 8 + 17 files changed, 489 insertions(+), 22 deletions(-) create mode 100644 client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/model/FastestCallSpeedLoadBalancingHolder.java create mode 100644 client/src/test/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/test/TreeSetTest.java create mode 100644 client/src/test/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/test/UrlTest.java create mode 100644 server/src/main/java/cn/icanci/loopstack/ras/server/Test.java diff --git a/client/src/main/java/cn/icanci/loopstack/ras/client/aop/RpcCallAop.java b/client/src/main/java/cn/icanci/loopstack/ras/client/aop/RpcCallAop.java index 9f37274..b0347ad 100644 --- a/client/src/main/java/cn/icanci/loopstack/ras/client/aop/RpcCallAop.java +++ b/client/src/main/java/cn/icanci/loopstack/ras/client/aop/RpcCallAop.java @@ -1,5 +1,7 @@ package cn.icanci.loopstack.ras.client.aop; +import cn.icanci.loopstack.ras.client.cache.loadbalancing.LoadBalancingSupport; + import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; @@ -7,8 +9,7 @@ import org.aspectj.lang.annotation.Pointcut; import org.springframework.stereotype.Component; /** - * AOP拦截 - * TODO 拦截执行时间和相关请求参数,记录到缓存 + * AOP拦截 - 拦截执行时间和相关请求参数,记录到缓存 * * @author icanci * @since 1.0 Created in 2023/01/16 19:56 @@ -17,7 +18,7 @@ import org.springframework.stereotype.Component; @Component public class RpcCallAop { - @Pointcut("execution(public * cn.icanci.loopstack.ras.client.facade.RpcCallFacade.call(..))") + @Pointcut("execution(public * cn.icanci.loopstack.ras.client.facade.RpcCallFacade.reallyCall(..))") private void callAop() { } @@ -28,7 +29,8 @@ public class RpcCallAop { long startTime = System.currentTimeMillis(); Object returnVal = pjp.proceed(); long endTime = System.currentTimeMillis(); - // TODO 记录执行时间、执行的内容 + // 刷新数据 + LoadBalancingSupport.refreshCallSpeedInfo(args, (endTime - startTime)); return returnVal; } } diff --git a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/ConsistencyHashLoadBalancing.java b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/ConsistencyHashLoadBalancing.java index f01ae3e..208a18a 100644 --- a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/ConsistencyHashLoadBalancing.java +++ b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/ConsistencyHashLoadBalancing.java @@ -6,7 +6,7 @@ import cn.icanci.loopstack.ras.common.enums.LoadBalanceTypeEnum; import org.springframework.stereotype.Service; /** - * 一致性hash负载均衡 + * 一致性哈希 * * @author icanci * @since 1.0 Created in 2023/01/30 19:34 diff --git a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/FastestCallSpeedLoadBalancing.java b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/FastestCallSpeedLoadBalancing.java index f3f37a3..b09b31b 100644 --- a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/FastestCallSpeedLoadBalancing.java +++ b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/FastestCallSpeedLoadBalancing.java @@ -1,30 +1,74 @@ package cn.icanci.loopstack.ras.client.cache.loadbalancing; +import cn.icanci.loopstack.ras.client.cache.loadbalancing.model.FastestCallSpeedLoadBalancingHolder; import cn.icanci.loopstack.ras.client.cache.loadbalancing.model.LoadBalancingHolder; +import cn.icanci.loopstack.ras.client.cache.model.ApplicationValue; +import cn.icanci.loopstack.ras.client.cache.model.ClientApplicationValue; import cn.icanci.loopstack.ras.common.enums.LoadBalanceTypeEnum; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.commons.collections4.CollectionUtils; import org.springframework.stereotype.Service; /** + * 调用速度最快 + * * @author icanci * @since 1.0 Created in 2023/01/30 19:36 */ @Service @LoadBalancingBean(LoadBalanceTypeEnum.FASTEST_CALL_SPEED) public class FastestCallSpeedLoadBalancing extends LoadBalancingCache implements LoadBalancing { + /** + * 数据缓存结果模型 + */ + private static Map HOLDER = new ConcurrentHashMap<>(); @Override public void init() { + // 1.根据路由表,找到所有的指定路由方式 + if (isLbAppEmpty()) { + return; + } + Set applicationValues = filterLbType(LoadBalanceTypeEnum.FIRST); + if (CollectionUtils.isEmpty(applicationValues)) { + return; + } + Map tempMap = new ConcurrentHashMap<>(); + // 2.遍历应用表,构建缓存 + for (ClientApplicationValue applicationValue : applicationValues) { + String appId = applicationValue.getAppId(); + Set apps = applicationValue.getApplicationValues(); + tempMap.put(appId, new FastestCallSpeedLoadBalancingHolder(apps)); + } + // 3.替换 + HOLDER = tempMap; } @Override public void refresh() { - + init(); } @Override protected LoadBalancingHolder getHolder(String appId) { - return null; + return HOLDER.get(appId); + } + + /** + * 缓存构建刷新 + * + * @param appId appId + * @param ip ip + * @param port port + * @param runtime runtime + */ + public void refresh(String appId, String ip, int port, long runtime) { + FastestCallSpeedLoadBalancingHolder holder = HOLDER.get(appId); + holder.refresh(ip, port, runtime); } } diff --git a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/FirstLoadBalancing.java b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/FirstLoadBalancing.java index 334dc03..2c3028c 100644 --- a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/FirstLoadBalancing.java +++ b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/FirstLoadBalancing.java @@ -14,7 +14,7 @@ import org.apache.commons.collections4.CollectionUtils; import org.springframework.stereotype.Service; /** - * 负载均衡算法实现 + * 第一个 * * @author icanci * @since 1.0 Created in 2023/01/23 10:23 diff --git a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/InOrderLoadBalancing.java b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/InOrderLoadBalancing.java index 59e4005..5b289cd 100644 --- a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/InOrderLoadBalancing.java +++ b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/InOrderLoadBalancing.java @@ -14,7 +14,7 @@ import org.apache.commons.collections4.CollectionUtils; import org.springframework.stereotype.Service; /** - * 负载均衡算法实现 + * 按顺序 * * @author icanci * @since 1.0 Created in 2023/01/23 10:23 diff --git a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/LastLoadBalancing.java b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/LastLoadBalancing.java index 7c2c7ba..76a511a 100644 --- a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/LastLoadBalancing.java +++ b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/LastLoadBalancing.java @@ -14,7 +14,7 @@ import org.apache.commons.collections4.CollectionUtils; import org.springframework.stereotype.Service; /** - * 负载均衡算法实现 + * 最后一个 * * @author icanci * @since 1.0 Created in 2023/01/23 10:23 diff --git a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/LeastFrequentlyUsedLoadBalancing.java b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/LeastFrequentlyUsedLoadBalancing.java index 981c5bf..4cef718 100644 --- a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/LeastFrequentlyUsedLoadBalancing.java +++ b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/LeastFrequentlyUsedLoadBalancing.java @@ -1,11 +1,13 @@ package cn.icanci.loopstack.ras.client.cache.loadbalancing; -import org.springframework.stereotype.Service; - import cn.icanci.loopstack.ras.client.cache.loadbalancing.model.LoadBalancingHolder; import cn.icanci.loopstack.ras.common.enums.LoadBalanceTypeEnum; +import org.springframework.stereotype.Service; + /** + * 最不经常使用 + * * @author icanci * @since 1.0 Created in 2023/01/30 19:36 */ @@ -25,6 +27,6 @@ public class LeastFrequentlyUsedLoadBalancing extends LoadBalancingCache impleme @Override protected LoadBalancingHolder getHolder(String appId) { - return HOLDER.get(appId); + return null; } } diff --git a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/LeastRecentlyUsedLoadBalancing.java b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/LeastRecentlyUsedLoadBalancing.java index 5336520..5b45a54 100644 --- a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/LeastRecentlyUsedLoadBalancing.java +++ b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/LeastRecentlyUsedLoadBalancing.java @@ -1,11 +1,13 @@ package cn.icanci.loopstack.ras.client.cache.loadbalancing; -import org.springframework.stereotype.Service; - import cn.icanci.loopstack.ras.client.cache.loadbalancing.model.LoadBalancingHolder; import cn.icanci.loopstack.ras.common.enums.LoadBalanceTypeEnum; +import org.springframework.stereotype.Service; + /** + * 最近最久未使用 + * * @author icanci * @since 1.0 Created in 2023/01/30 19:36 */ @@ -25,6 +27,6 @@ public class LeastRecentlyUsedLoadBalancing extends LoadBalancingCache implement @Override protected LoadBalancingHolder getHolder(String appId) { - return HOLDER.get(appId); + return null; } } diff --git a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/LoadBalancingSupport.java b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/LoadBalancingSupport.java index 3d6352d..ecf7a56 100644 --- a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/LoadBalancingSupport.java +++ b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/LoadBalancingSupport.java @@ -4,15 +4,22 @@ import cn.icanci.loopstack.ras.client.cache.MetaCacheHolder; import cn.icanci.loopstack.ras.client.cache.model.ApplicationValue; import cn.icanci.loopstack.ras.client.cache.model.ClientApplicationValue; import cn.icanci.loopstack.ras.common.enums.LoadBalanceTypeEnum; +import io.netty.util.internal.ThrowableUtil; +import java.io.IOException; +import java.net.InetAddress; +import java.net.URL; import java.util.Collection; import java.util.Map; import java.util.Optional; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.aop.support.AopUtils; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; +import com.alibaba.fastjson.JSON; import com.google.common.collect.Maps; /** @@ -24,6 +31,8 @@ import com.google.common.collect.Maps; */ public final class LoadBalancingSupport extends MetaCacheHolder { + private static final Logger logger = LoggerFactory.getLogger(LoadBalancingSupport.class); + /** 执行存储单元 */ private static final Map LB_REPOSITORY = Maps.newHashMap(); @@ -76,4 +85,66 @@ public final class LoadBalancingSupport extends MetaCacheHolder { LB_REPOSITORY.put(loadBalancingBean.value(), loadBalancing); } } + + /** + * 数据刷新 + * + * @param args 方法参数 + * String appId, String url, Object request, Map headers, Method method, int readTimeOut, int retry, Class clazz + * + * @param rt 执行调用的耗时 + */ + public static void refreshCallSpeedInfo(Object[] args, long rt) { + try { + // 获取 appid + String appId = String.valueOf(args[0]); + String url = String.valueOf(args[1]); + // REQUEST_FORMAT + ClientApplicationValue clientApplicationValue = CLIENT_APPLICATION_MAP.get(appId); + if (clientApplicationValue == null) { + return; + } + // 解析 ip 和 port + String ip = parseIp(url); + int port = parsePort(url); + + LoadBalanceTypeEnum loadBalanceType = clientApplicationValue.getLoadBalanceType(); + LoadBalancing loadBalancing = LB_REPOSITORY.get(loadBalanceType); + // 只处理 FastestCallSpeedLoadBalancing 类型 + if (loadBalancing instanceof FastestCallSpeedLoadBalancing) { + FastestCallSpeedLoadBalancing fastestCallSpeedLoadBalancing = (FastestCallSpeedLoadBalancing) loadBalancing; + fastestCallSpeedLoadBalancing.refresh(appId, ip, port, rt); + } + } catch (Throwable ex) { + logger.error("[LoadBalancingSupport][refreshCallSpeedInfo] args:{},rt:{}rt, error:{}", JSON.toJSONString(args), rt, ThrowableUtil.stackTraceToString(ex)); + } + } + + /** + * 获取端口号 + * + * @param href 网址 + * @return port + */ + public static int parsePort(String href) throws IOException { + URL url = new URL(href); + int port = url.getPort(); + if (port < 0) { + port = url.getDefaultPort(); + } + return port; + } + + /** + * 根据域名解析IP地址 + * + * @param href href + * @return getHostAddress + */ + public static String parseIp(String href) throws IOException { + URL url = new URL(href); + String host = url.getHost(); + InetAddress inetAddress = InetAddress.getByName(host); + return inetAddress.getHostAddress(); + } } diff --git a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/RandomLoadBalancing.java b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/RandomLoadBalancing.java index 23cf0e3..39744e3 100644 --- a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/RandomLoadBalancing.java +++ b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/RandomLoadBalancing.java @@ -14,7 +14,7 @@ import org.apache.commons.collections4.CollectionUtils; import org.springframework.stereotype.Service; /** - * 负载均衡算法实现 + * 随机 * * @author icanci * @since 1.0 Created in 2023/01/23 10:23 diff --git a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/model/FastestCallSpeedLoadBalancingHolder.java b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/model/FastestCallSpeedLoadBalancingHolder.java new file mode 100644 index 0000000..d43505f --- /dev/null +++ b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/model/FastestCallSpeedLoadBalancingHolder.java @@ -0,0 +1,183 @@ +package cn.icanci.loopstack.ras.client.cache.loadbalancing.model; + +import cn.icanci.loopstack.ras.client.cache.model.ApplicationValue; + +import java.util.*; +import java.util.concurrent.atomic.AtomicInteger; + +import org.apache.commons.lang3.StringUtils; + +import com.google.common.collect.Lists; + +/** + * @author icanci + * @since 1.0 Created in 2023/02/04 21:00 + */ +public class FastestCallSpeedLoadBalancingHolder extends LoadBalancingHolder { + /** + * 应用列表 + */ + private final Set applicationHolder; + + /** + * 缓存队列的最大长度 + * 同一个App调用次数超过1千次,则清零 + */ + private AtomicInteger maxQueueSize = new AtomicInteger(1000); + + public FastestCallSpeedLoadBalancingHolder(Set applications) { + // 初始化 + applicationHolder = new TreeSet<>(new Comparator() { + @Override + public int compare(InnerFastestCallSpeedLoadBalancingHolder o1, InnerFastestCallSpeedLoadBalancingHolder o2) { + return (int) (o1.getAverageCallRuntime() - o2.getAverageCallRuntime()); + } + }); + init(applications); + // 设置下一个 + setNext(); + } + + /** + * 初始化操作 + * + * @param applications applications + */ + private void init(Set applications) { + for (ApplicationValue application : applications) { + applicationHolder.add(new InnerFastestCallSpeedLoadBalancingHolder(application)); + } + } + + /** + * 设置下一个需要加载的数据 + */ + @Override + public void setNext() { + Optional speedOptional = applicationHolder.stream() + .filter(appHolder -> appHolder.getApplicationValue().getOnline() == 0 && appHolder.getApplicationValue().getIsDelete() == 0).findFirst(); + if (speedOptional.isPresent()) { + this.next = speedOptional.get().getApplicationValue(); + maxQueueSize.decrementAndGet(); + } else { + speedOptional = applicationHolder.stream().filter(appHolder -> appHolder.getApplicationValue().getOnline() == 0).findFirst(); + if (speedOptional.isPresent()) { + this.next = speedOptional.get().getApplicationValue(); + maxQueueSize.decrementAndGet(); + } else { + speedOptional = applicationHolder.stream().filter(appHolder -> appHolder.getApplicationValue().getOnline() == 1).findFirst(); + if (speedOptional.isPresent()) { + this.next = speedOptional.get().getApplicationValue(); + maxQueueSize.decrementAndGet(); + } + } + } + + tryFixQueueSize(); + } + + /** + * 尝试处理次数 + */ + private void tryFixQueueSize() { + if (maxQueueSize.get() <= 0) { + maxQueueSize = new AtomicInteger(1000); + } + } + + /** + * refresh + * + * @param ip ip + * @param port port + * @param runtime runtime + */ + public void refresh(String ip, int port, long runtime) { + if (runtime < 0) { + return; + } + Optional target = applicationHolder.stream() + .filter(appHolder -> StringUtils.equals(appHolder.getApplicationValue().getAddress(), ip) && appHolder.getApplicationValue().getPort() == port).findFirst(); + if (!target.isPresent()) { + return; + } + InnerFastestCallSpeedLoadBalancingHolder holder = target.get(); + ApplicationValue applicationValue = holder.getApplicationValue(); + long averageCallRuntime = holder.getAverageCallRuntime(); + List callRuntimeQueue = holder.getCallRuntimeQueue(); + callRuntimeQueue.add(runtime); + double average = callRuntimeQueue.stream().mapToDouble(Long::longValue).average().orElse(0D); + InnerFastestCallSpeedLoadBalancingHolder temp = new InnerFastestCallSpeedLoadBalancingHolder(applicationValue, (long) average, callRuntimeQueue); + applicationHolder.removeIf(appHolder -> StringUtils.equals(appHolder.getApplicationValue().getAddress(), ip) && appHolder.getApplicationValue().getPort() == port); + applicationHolder.add(temp); + } + + /** + * 内部对象 + */ + public static class InnerFastestCallSpeedLoadBalancingHolder { + /** + * app 信息 + */ + private final ApplicationValue applicationValue; + /** + * 执行平均时间 + */ + private long averageCallRuntime = 0L; + /** + * 执行耗时队列 + */ + private List callRuntimeQueue = Lists.newArrayList(); + + /** + * 初始化构造函数 + * - + * @param applicationValue applicationValue + */ + public InnerFastestCallSpeedLoadBalancingHolder(ApplicationValue applicationValue) { + this.applicationValue = applicationValue; + } + + public InnerFastestCallSpeedLoadBalancingHolder(ApplicationValue applicationValue, long averageCallRuntime, List callRuntimeQueue) { + this.applicationValue = applicationValue; + this.averageCallRuntime = averageCallRuntime; + this.callRuntimeQueue = callRuntimeQueue; + } + + public ApplicationValue getApplicationValue() { + return applicationValue; + } + + public long getAverageCallRuntime() { + return averageCallRuntime; + } + + public void setAverageCallRuntime(long averageCallRuntime) { + this.averageCallRuntime = averageCallRuntime; + } + + public List getCallRuntimeQueue() { + return callRuntimeQueue; + } + + public void setCallRuntimeQueue(List callRuntimeQueue) { + this.callRuntimeQueue = callRuntimeQueue; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + InnerFastestCallSpeedLoadBalancingHolder that = (InnerFastestCallSpeedLoadBalancingHolder) o; + return Objects.equals(applicationValue, that.applicationValue); + } + + @Override + public int hashCode() { + return Objects.hash(applicationValue); + } + } + +} diff --git a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/model/InOrderBalancingHolder.java b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/model/InOrderBalancingHolder.java index ca67e61..656cafb 100644 --- a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/model/InOrderBalancingHolder.java +++ b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/model/InOrderBalancingHolder.java @@ -60,7 +60,7 @@ public class InOrderBalancingHolder extends LoadBalancingHolder { * @param size 当前执行的大小 */ private void fixInOrderIndex(int size) { - if (inOrderAtomicInteger.get() == size) { + if (inOrderAtomicInteger.get() == size - 1) { inOrderAtomicInteger = new AtomicInteger(0); } } diff --git a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/model/LoadBalancingHolder.java b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/model/LoadBalancingHolder.java index 13d4e5c..f17db6c 100644 --- a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/model/LoadBalancingHolder.java +++ b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/model/LoadBalancingHolder.java @@ -33,4 +33,5 @@ public abstract class LoadBalancingHolder { // 返回当前的 return tmpNext; } + } diff --git a/client/src/main/java/cn/icanci/loopstack/ras/client/facade/RpcCallFacade.java b/client/src/main/java/cn/icanci/loopstack/ras/client/facade/RpcCallFacade.java index 8a686bc..e95abc7 100644 --- a/client/src/main/java/cn/icanci/loopstack/ras/client/facade/RpcCallFacade.java +++ b/client/src/main/java/cn/icanci/loopstack/ras/client/facade/RpcCallFacade.java @@ -3,8 +3,8 @@ package cn.icanci.loopstack.ras.client.facade; import cn.hutool.http.Method; import cn.icanci.loopstack.api.client.Client; import cn.icanci.loopstack.api.client.http.HttpClientImpl; -import cn.icanci.loopstack.ras.client.exception.RpcCallException; import cn.icanci.loopstack.ras.client.cache.holder.RasRepositoryHolder; +import cn.icanci.loopstack.ras.client.exception.RpcCallException; import java.util.Map; import java.util.concurrent.TimeUnit; @@ -120,10 +120,26 @@ public class RpcCallFacade { * @return 返回请求返回数据 */ public T call(String appId, String relativePath, Object request, Map headers, Method method, int readTimeOut, int retry, Class clazz) { - // 构建请求参数 - Client.RpcRequest rpcRequest = new Client.RpcRequest(resolvingRequestUrl(appId, relativePath), request, headers == null ? DEFAULT_HEADERS : headers, method, readTimeOut, - TimeUnit.SECONDS, retry); + return reallyCall(appId, resolvingRequestUrl(appId, relativePath), request, headers == null ? DEFAULT_HEADERS : headers, method, readTimeOut, retry, clazz); + } + /** + * 请求调用 + * + * @param appId appId AOP 使用 + * @param url url + * @param request 请求 + * @param headers 请求头 + * @param method 请求方法 + * @param readTimeOut 请求超时时间(单位 秒) + * @param retry 重试次数 + * @param clazz 请求返回类型 + * @param 请求返回泛型 + * @return 返回请求返回数据 + */ + public T reallyCall(String appId, String url, Object request, Map headers, Method method, int readTimeOut, int retry, Class clazz) { + // 构建请求参数 + Client.RpcRequest rpcRequest = new Client.RpcRequest(url, request, headers, method, readTimeOut, TimeUnit.SECONDS, retry); // 调用 return CLIENT.call(rpcRequest, clazz); } diff --git a/client/src/test/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/test/TreeSetTest.java b/client/src/test/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/test/TreeSetTest.java new file mode 100644 index 0000000..9106a6c --- /dev/null +++ b/client/src/test/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/test/TreeSetTest.java @@ -0,0 +1,77 @@ +package cn.icanci.loopstack.ras.client.cache.loadbalancing.test; + +import java.util.*; + +import org.junit.Test; + +/** + * @author icanci + * @since 1.0 Created in 2023/02/04 21:35 + */ +public class TreeSetTest { + @Test + public void test1() { + TreeSet tests = new TreeSet<>(new Comparator() { + @Override + public int compare(Test1 o1, Test1 o2) { + return o1.index - o2.index; + } + }); + tests.add(new Test1(111)); + tests.add(new Test1(222)); + tests.add(new Test1(333)); + System.out.println(tests); + Test1 first = tests.first(); + Test1 test1 = new Test1(999); + tests.remove(first); + tests.add(test1); + System.out.println(tests); + } + + @Test + public void test2() { + List callRuntimeQueue = new ArrayList<>(); + callRuntimeQueue.add(111L); + callRuntimeQueue.add(222L); + callRuntimeQueue.add(333L); + double average = callRuntimeQueue.stream().mapToDouble(Long::longValue).average().orElse(0D); + System.out.println((long) average); + } + + public static class Test1 { + private int index; + + public Test1(int index) { + this.index = index; + } + + public int getIndex() { + + return index; + } + + public void setIndex(int index) { + this.index = index; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + Test1 test = (Test1) o; + return index == test.index; + } + + @Override + public int hashCode() { + return Objects.hash(index); + } + + @Override + public String toString() { + return new StringJoiner(",").add("index=" + index).toString(); + } + } +} diff --git a/client/src/test/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/test/UrlTest.java b/client/src/test/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/test/UrlTest.java new file mode 100644 index 0000000..26bf88d --- /dev/null +++ b/client/src/test/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/test/UrlTest.java @@ -0,0 +1,61 @@ +package cn.icanci.loopstack.ras.client.cache.loadbalancing.test; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.URI; +import java.net.URL; + +import org.junit.Test; + +/** + * @author icanci + * @since 1.0 Created in 2023/02/04 21:35 + */ +public class UrlTest { + @Test + public void test1() throws IOException { + String host1 = "https://blog.csdn.net/qq_43566496/article/details/84938575"; + System.out.println(parseIp(host1)); + System.out.println(parsePort(host1)); + + + String host2 = "http://127.0.0.1:8080/qq_43566496/article/details/84938575"; + System.out.println(parseIp(host2)); + System.out.println(parsePort(host2)); + + URI uri = URI.create("http://127.0.0.1:8080/qq_43566496/article/details/84938575"); + String host = uri.getHost(); + int port = uri.getPort(); + System.out.println(host); + System.out.println(port); + } + + /** + * 获取端口号 + * + * @param href 网址 + * @return port + */ + public int parsePort(String href) throws IOException { + URL url = new URL(href); + int port = url.getPort(); + if (port < 0) { + port = url.getDefaultPort(); + } + return port; + } + + /** + * 根据域名解析IP地址 + * + * @param href href + * @return getHostAddress + * @throws IOException + */ + public String parseIp(String href) throws IOException { + URL url = new URL(href); + String host = url.getHost(); + InetAddress inetAddress = InetAddress.getByName(host); + return inetAddress.getHostAddress(); + } +} diff --git a/server/src/main/java/cn/icanci/loopstack/ras/server/Test.java b/server/src/main/java/cn/icanci/loopstack/ras/server/Test.java new file mode 100644 index 0000000..a4a877c --- /dev/null +++ b/server/src/main/java/cn/icanci/loopstack/ras/server/Test.java @@ -0,0 +1,8 @@ +package cn.icanci.loopstack.ras.server; + +/** + * @author icanci + * @since 1.0 Created in 2023/02/04 21:38 + */ +public class Test { +} -- Gitee