From 14818051eeeb243a11aa0d8236fe6d99ec12bc66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=87=8C=E7=9B=AE?= Date: Wed, 26 Jun 2019 19:47:37 +0800 Subject: [PATCH] A ribbon rule integrated with nacos cluster and respect nacos server's weight configuration. --- .../alibaba/nacos/ribbon/ExtendBalancer.java | 21 ++++++ .../cloud/alibaba/nacos/ribbon/NacosRule.java | 66 +++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 spring-cloud-alibaba-nacos-discovery/src/main/java/org/springframework/cloud/alibaba/nacos/ribbon/ExtendBalancer.java create mode 100644 spring-cloud-alibaba-nacos-discovery/src/main/java/org/springframework/cloud/alibaba/nacos/ribbon/NacosRule.java diff --git a/spring-cloud-alibaba-nacos-discovery/src/main/java/org/springframework/cloud/alibaba/nacos/ribbon/ExtendBalancer.java b/spring-cloud-alibaba-nacos-discovery/src/main/java/org/springframework/cloud/alibaba/nacos/ribbon/ExtendBalancer.java new file mode 100644 index 00000000..3f21a9ad --- /dev/null +++ b/spring-cloud-alibaba-nacos-discovery/src/main/java/org/springframework/cloud/alibaba/nacos/ribbon/ExtendBalancer.java @@ -0,0 +1,21 @@ +package org.springframework.cloud.alibaba.nacos.ribbon; + +import com.alibaba.nacos.api.naming.pojo.Instance; +import com.alibaba.nacos.client.naming.core.Balancer; + +import java.util.List; + +/** + * @author itmuch.com + */ +public class ExtendBalancer extends Balancer { + /** + * 根据权重,随机选择实例 + * + * @param instances 实例列表 + * @return 选择的实例 + */ + public static Instance getHostByRandomWeight2(List instances) { + return getHostByRandomWeight(instances); + } +} diff --git a/spring-cloud-alibaba-nacos-discovery/src/main/java/org/springframework/cloud/alibaba/nacos/ribbon/NacosRule.java b/spring-cloud-alibaba-nacos-discovery/src/main/java/org/springframework/cloud/alibaba/nacos/ribbon/NacosRule.java new file mode 100644 index 00000000..50a6f916 --- /dev/null +++ b/spring-cloud-alibaba-nacos-discovery/src/main/java/org/springframework/cloud/alibaba/nacos/ribbon/NacosRule.java @@ -0,0 +1,66 @@ +package org.springframework.cloud.alibaba.nacos.ribbon; + +import com.alibaba.nacos.api.naming.NamingService; +import com.alibaba.nacos.api.naming.pojo.Instance; +import com.netflix.client.config.IClientConfig; +import com.netflix.loadbalancer.AbstractLoadBalancerRule; +import com.netflix.loadbalancer.DynamicServerListLoadBalancer; +import com.netflix.loadbalancer.Server; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.alibaba.nacos.NacosDiscoveryProperties; +import org.springframework.util.CollectionUtils; + +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +/** + * 支持优先调用同集群实例的ribbon负载均衡规则. + * + * @author itmuch.com + */ +public class NacosRule extends AbstractLoadBalancerRule { + private static final Logger LOGGER = LoggerFactory.getLogger(NacosRule.class); + + @Autowired + private NacosDiscoveryProperties nacosDiscoveryProperties; + + @Override + public Server choose(Object key) { + try { + String clusterName = this.nacosDiscoveryProperties.getClusterName(); + DynamicServerListLoadBalancer loadBalancer = (DynamicServerListLoadBalancer) getLoadBalancer(); + String name = loadBalancer.getName(); + + NamingService namingService = this.nacosDiscoveryProperties.namingServiceInstance(); + + List instances = namingService.selectInstances(name, true); + List instancesToChoose = instances; + + if (StringUtils.isNotBlank(clusterName)) { + List sameClusterInstances = instances.stream() + .filter(instance -> Objects.equals(clusterName, instance.getClusterName())) + .collect(Collectors.toList()); + if (!CollectionUtils.isEmpty(sameClusterInstances)) { + instancesToChoose = sameClusterInstances; + } else { + LOGGER.warn("发生跨集群的调用,name = {}, clusterName = {}, instance = {}", name, clusterName, instances); + } + } + + Instance instance = ExtendBalancer.getHostByRandomWeight2(instancesToChoose); + + return new NacosServer(instance); + } catch (Exception e) { + LOGGER.warn("NacosRule发生异常", e); + return null; + } + } + + @Override + public void initWithNiwsConfig(IClientConfig iClientConfig) { + } +} \ No newline at end of file