文章目录

前言下面来实现。

一、配置yml二、content-center端扩展Ribbon

前言

假设有两个微服务一个叫user-center ,一个叫content-center。为了容灾,两个微服务在BJ集群和CD集群都有部署。 且 user-center ,content-center两个微服务都有不同的版本,v1版本的content-center 只能调用v1版本的user-center 且 要求同一集群下的应用优先调用,也就是说:content-center如果在BJ集群里那么在调用user-center微服务时优先调用BJ集群下的content-center。

下面来实现。

一、配置yml

application:

name: content-center

cloud:

nacos:

discovery:

server-addr: localhost:8848

cluster-name: BJ-Center

metadata:

target-version: v2

version: v1

server:

port: 8081

application:

name: user-center

cloud:

nacos:

discovery:

#指定Nacos的地址

server-addr: localhost:8848

#指定集群名称

cluster-name: BJ-Center

metadata:

version: v2

server:

port: 8082

application:

name: user-center

cloud:

nacos:

discovery:

#指定Nacos的地址

server-addr: localhost:8848

#指定集群名称

cluster-name: CD-Center

metadata:

version: v2

server:

port: 8083

二、content-center端扩展Ribbon

import com.alibaba.nacos.api.exception.NacosException;

import com.alibaba.nacos.api.naming.NamingService;

import com.alibaba.nacos.api.naming.pojo.Instance;

import com.alibaba.nacos.client.naming.core.Balancer;

import com.netflix.client.config.IClientConfig;

import com.netflix.loadbalancer.AbstractLoadBalancerRule;

import com.netflix.loadbalancer.BaseLoadBalancer;

import com.netflix.loadbalancer.Server;

import lombok.extern.slf4j.Slf4j;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.cloud.alibaba.nacos.NacosDiscoveryProperties;

import org.springframework.cloud.alibaba.nacos.ribbon.NacosServer;

import org.springframework.util.CollectionUtils;

import org.springframework.util.StringUtils;

import java.util.ArrayList;

import java.util.List;

import java.util.Objects;

import java.util.stream.Collectors;

@Slf4j

public class NacosFinalRule extends AbstractLoadBalancerRule {

@Autowired

NacosDiscoveryProperties nacosDiscoveryProperties;

@Override

public void initWithNiwsConfig(IClientConfig iClientConfig) {

}

@Override

public Server choose(Object o) {

try {

//1.拿到loadBalancer

BaseLoadBalancer loadBalancer = (BaseLoadBalancer)this.getLoadBalancer();

//2.拿到请求的微服务的名称

String name = loadBalancer.getName();

//3.用 nacosDiscoveryProperties 拿到服务发现的相关API 以及配置文件中配置的集群名字 以及配置中的目标版本

NamingService namingService = nacosDiscoveryProperties.namingServiceInstance();

String clusterName = nacosDiscoveryProperties.getClusterName();

String target_version = nacosDiscoveryProperties.getMetadata().get("target-version");

//4.用 NocasApi 获取这个微服务的所有实例 A

List instances = namingService.selectInstances(name, true);

//如果配置了目标版本,则筛选出目标版本的实例集合

List metadataMatchInstances = new ArrayList<>();

if(!StringUtils.isEmpty(target_version)){

metadataMatchInstances = instances.stream().filter(instance ->

Objects.equals(instance.getMetadata().get("version"), target_version)).collect(Collectors.toList());

if(CollectionUtils.isEmpty(metadataMatchInstances)){

log.warn("未找到元数据匹配的目标实例!请检查配置. target-version:{}",target_version);

return null;

}

}

//5.如果配置了集群名称则 筛选同集群下的微服务实例集合B

List clusterMetadataMatchInstances = new ArrayList<>();

if(!StringUtils.isEmpty(clusterName)){

clusterMetadataMatchInstances = metadataMatchInstances.stream().filter(instance -> Objects.equals(instance.getClusterName(), clusterName)).collect(Collectors.toList());

//6.B空用A,否则用B

if(CollectionUtils.isEmpty(clusterMetadataMatchInstances)){

log.warn("发生跨集群的调用,instance name:{} clusterName:{}",name,clusterName);

clusterMetadataMatchInstances = metadataMatchInstances;

}

}

//7.用NocasApi 权重负载均衡

Instance instance = Balancer_local.getHostByRandomWeight_local(clusterMetadataMatchInstances);

log.info("NacosSameClusterWeightedRule.instance:url:{},port:{}",instance.getIp(),instance.getPort());

return new NacosServer(instance);

} catch (NacosException e) {

log.error("NacosSameClusterWeightedRule.NacosException:",e);

e.printStackTrace();

}

return null;

}

}

class Balancer_local extends Balancer {

public static Instance getHostByRandomWeight_local(List hosts){

return getHostByRandomWeight(hosts);

}

}

再调用user-center时,先根据元数据得到8082,8083两个实例,再根据cluster-name 筛选出8082

文章来源

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。