Nacos:实现版本控制调度,灰度版本隔离

本文作者:suxingrui
本文链接:https://blog.csdn.net/suxingrui/article/details/103791284
版权声明:本文为原创文章,转载请注明出处。

回顾2019年碰到的问题及解决方式
问题:Nacos:实现版本控制调度,灰度版本隔离

问题发现:
版本上到正式环境之后,有一段灰度测试的时间。
这段时间老服务与新服务共存,不想老服务调用新服务,新服务可以调用老服务,
或者实现新老服务不能相互调度,所以需要做一定的版本隔离,
当灰度测试验证通过之后,再放开限制或者下线老服务。

然后查找官方文档跟源码,官方似乎不支持?或者我没找对地方
找不到,那只能自己实现

调查分析:
分析源码之后,得出Nacos的负载均衡是基于Ribbon的
在这里插入图片描述
ServerList也是在不存在Bean时,才会使用自定义的
所以顾名思义,直接改造NacosServerList就能够实现自己的目标
主要是改写NacosServerList的instancesToServerList方法,原有的逻辑比较简单:
在这里插入图片描述

解决方法:
1、我这里简单的改成版本匹配才调用,正常来说每个服务的版本不可能一致,需要根据实际情况调整,比如版本后再加上特定的字符串gray等
在原有的基础上添加按版本过滤的功能,如何设置版本等信息,请参照另外一篇博文:Nacos:展示服务列表中的服务的启动时间

/**
 * @author xiaojing
 * @author renhaojun
 */
@Slf4j
public class NacosServerList extends AbstractServerList<NacosServer> {

	private NacosDiscoveryProperties discoveryProperties;

	private String serviceId;

	public NacosServerList(NacosDiscoveryProperties discoveryProperties) {
		this.discoveryProperties = discoveryProperties;
	}

	@Override
	public List<NacosServer> getInitialListOfServers() {
		return getServers();
	}

	@Override
	public List<NacosServer> getUpdatedListOfServers() {
		return getServers();
	}

	private List<NacosServer> getServers() {
		try {
			List<Instance> instances = discoveryProperties.namingServiceInstance().selectInstances(serviceId, true);
			return instancesToServerList(instances);
		} catch (Exception e) {
			throw new IllegalStateException("Can not get service instances from nacos, serviceId=" + serviceId, e);
		}
	}

	private List<NacosServer> instancesToServerList(List<Instance> instances) {
		List<NacosServer> result = new ArrayList<>();
		if (CollectionUtils.isEmpty(instances)) {
			return result;
		}
		boolean filter = false;
		String curVer = discoveryProperties.getMetadata().get("version");
		for (Instance instance : instances) {
			// 按版本隔离服务
			Map<String, String> tarMetadata = instance.getMetadata();
			String tarVer = tarMetadata.get("version");
			boolean tarSupportAll = "all".equalsIgnoreCase(tarMetadata.get("support"));
			if (tarSupportAll || StringUtils.equals(curVer, tarVer)) {
				result.add(new NacosServer(instance));
			} else {
				filter = true;
			}
		}
		if (filter && result.size() == 0) {
			log.info("{} 全部被过滤:{}", serviceId, instances);
		}

		return result;
	}

	public String getServiceId() {
		return serviceId;
	}

	@Override
	public void initWithNiwsConfig(IClientConfig iClientConfig) {
		this.serviceId = iClientConfig.getClientName();
	}
}

2、使用修改后的NacosServerList

/**
 * 自定义Ribbon的策略
 *
 * @author suxingrui
 * @time Aug 2, 2019 11:39:34 AM
 */
@Configuration
public class NacosRibbonConfiguration {

	@Bean
	public ServerList<?> ribbonServerList(IClientConfig config, NacosDiscoveryProperties nacosDiscoveryProperties) {
		NacosServerList serverList = new NacosServerList(nacosDiscoveryProperties);
		serverList.initWithNiwsConfig(config);
		return serverList;
	}
}

启动类加上注解:

@RibbonClients(defaultConfiguration = NacosRibbonConfiguration.class)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值