Nacos服务跨分组调用
一、 问题背景
nacos有两种服务隔离的机制,一个是空间namespace,一般我们用namespace区分环境,另外一个是分组group,nacos的默认调用机制是同namespace下的同group的服务才可以相互调用;
那现在有个问题: 在测试阶段,由于测试环境和开发环境数据库等不一致,在测试出bug后,开发人员需要连接到测试环境上复线定位bug,但是如果开发人员本地启动测试环境,那么就会导致测试环境服务多了个本地的实例,这样测试在调用这个服务的时候很有可能就会访问这个本地服务,导致服务异常,所以一般我们都会采用本地服务自定义group分组的方式注册;
一般来说,一个服务关连多个其他服务,开发人员就需要把所有相关的服务都注册到自定义的group分组中,这样才能保证接口通常,但是起很多服务又会导致电脑内存消耗巨大,所以就想着能不能只启动存在问题的那个服务,其他关联服务还是使用测试环境的服务,基于这种考虑才想实现跨分组调用,减少无关服务的启动.
二、实现方案
1.版本要求
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2021.0.4.0</version>
</dependency>

如果 Java 项目的 nacos discovery 版本用的是 2021以上,则不需要重写 Ribbon 的负载均衡类,因为该版本的 Nacos 不依赖 Ribbon,只需要重写服务发现即可
2.重写服务发现
public class NacosServiceDiscoveryV2 extends NacosServiceDiscovery {
public NacosServiceDiscoveryV2(NacosDiscoveryProperties discoveryProperties, NacosServiceManager nacosServiceManager) {
super(discoveryProperties, nacosServiceManager);
this.discoveryProperties = discoveryProperties;
this.nacosServiceManager = nacosServiceManager;
}
private NacosDiscoveryProperties discoveryProperties;
private NacosServiceManager nacosServiceManager;
// 重写该方法
public List<ServiceInstance> getInstances(String serviceId) throws NacosException {
String group = this.discoveryProperties.getGroup();
// 优先保证同分组下的服务调用
List<Instance> instances = this.namingService().selectInstances(serviceId, group, true);
if (CollUtil.isEmpty(instances)) {
// 如果同分组下找不到服务,那么就从默认分组下找服务
instances = this.namingService().selectInstances(serviceId, "DEFAULT_GROUP", true);
}
return hostToServiceInstanceList(instances, serviceId);
}
public List<String> getServices() throws NacosException {
String group = this.discoveryProperties.getGroup();
ListView<String> services = this.namingService().getServicesOfServer(1, Integer.MAX_VALUE, group);
return services.getData();
}
public static List<ServiceInstance> hostToServiceInstanceList(List<Instance> instances, String serviceId) {
List<ServiceInstance> result = new ArrayList(instances.size());
Iterator var3 = instances.iterator();
while (var3.hasNext()) {
Instance instance = (Instance) var3.next();
ServiceInstance serviceInstance = hostToServiceInstance(instance, serviceId);
if (serviceInstance != null) {
result.add(serviceInstance);
}
}
return result;
}
public static ServiceInstance hostToServiceInstance(Instance instance, String serviceId) {
if (instance != null && instance.isEnabled() && instance.isHealthy()) {
NacosServiceInstance nacosServiceInstance = new NacosServiceInstance();
nacosServiceInstance.setHost(instance.getIp());
nacosServiceInstance.setPort(instance.getPort());
nacosServiceInstance.setServiceId(serviceId);
nacosServiceInstance.setInstanceId(instance.getInstanceId());
Map<String, String> metadata = new HashMap();
metadata.put("nacos.instanceId", instance.getInstanceId());
metadata.put("nacos.weight", instance.getWeight() + "");
metadata.put("nacos.healthy", instance.isHealthy() + "");
metadata.put("nacos.cluster", instance.getClusterName() + "");
if (instance.getMetadata() != null) {
metadata.putAll(instance.getMetadata());
}
metadata.put("nacos.ephemeral", String.valueOf(instance.isEphemeral()));
nacosServiceInstance.setMetadata(metadata);
if (metadata.containsKey("secure")) {
boolean secure = Boolean.parseBoolean((String) metadata.get("secure"));
nacosServiceInstance.setSecure(secure);
}
return nacosServiceInstance;
} else {
return null;
}
}
private NamingService namingService() {
return this.nacosServiceManager.getNamingService();
}
}
3.重写自动配置类,更早的加载到Nacos容器中
@Configuration(proxyBeanMethods = false)
@ConditionalOnDiscoveryEnabled
@ConditionalOnNacosDiscoveryEnabled
@AutoConfigureBefore({NacosDiscoveryAutoConfiguration.class})
public class NacosDiscoveryAutoConfigurationV2 {
@Bean
@ConditionalOnMissingBean
public NacosServiceDiscovery nacosServiceDiscovery(NacosDiscoveryProperties nacosDiscoveryProperties, NacosServiceManager nacosServiceManager) {
return new NacosServiceDiscoveryV2(nacosDiscoveryProperties, nacosServiceManager);
}
}
其他版本的nacos的话,可能需要借助Ribbon负载均衡来处理跨分组调用,具体可参考以下:
参考:
Nacos服务跨分组调用的更多相关文章
- ABP框架中微服务跨域调用其它服务接口
AjaxResponse为ABP自动包装的JSON格式 /// <summary> /// 通过地址和参数取得返回OutPut数据 /// </summary> /// < ...
- ThinkPHP实现跨模块调用操作方法概述
ThinkPHP实现跨模块调用操作方法概述 投稿:shichen2014 字体:[增加 减小] 类型:转载 使用 $this 可以调用当前模块内的方法,但是很多情况下经常会在当前模块中调用其他模块 ...
- ThinkPHP 跨模块调用操作方法(A方法与R方法)
ThinkPHP 跨模块调用操作方法(A方法与R方法) 跨模块调用操作方法 前面说了可以使用 $this 来调用当前模块内的方法,但实际情况中还经常会在当前模块调用其他模块的方法.ThinkPHP 内 ...
- AJAX跨域调用ASP.NET MVC或者WebAPI服务的解决方案
问题描述 当跨域(cross domain)调用ASP.NET MVC或者ASP.NET Web API编写的服务时,会发生无法访问的情况. 重现方式 使用模板创建一个最简单的ASP.NET Web ...
- 关于AJAX跨域调用ASP.NET MVC或者WebAPI服务的问题及解决方案
作者:陈希章 时间:2014-7-3 问题描述 当跨域(cross domain)调用ASP.NET MVC或者ASP.NET Web API编写的服务时,会发生无法访问的情况. 重现方式 使用模 ...
- 实现jquery.ajax及原生的XMLHttpRequest跨域调用WCF服务的方法
关于ajax跨域调用WCF服务的方法很多,经过我反复的代码测试,认为如下方法是最为简便的,当然也不能说别人的方法是错误的,下面就来上代码,WCF服务定义还是延用上次的,如: namespace Wcf ...
- 以短链服务为例,探讨免AppKey、免认证、Ajax跨域调用新浪微博API
新浪微博的API官方提供了很多种调用方式,支持编程的,归根结底就是两种: 1.基于Oauth协议,使用Open API.(http://open.weibo.com/wiki/%E6%8E%88%E6 ...
- Thinkphp入门 二 —空操作、空模块、模块分组、前置操作、后置操作、跨模块调用(46)
原文:Thinkphp入门 二 -空操作.空模块.模块分组.前置操作.后置操作.跨模块调用(46) [空操作处理] 看下列图: 实际情况:我们的User控制器没有hello()这个方法 一个对象去访问 ...
- AJAX跨域调用ASP.NET MVC或者WebAPI服务
关于AJAX跨域调用ASP.NET MVC或者WebAPI服务的问题及解决方案 作者:陈希章 时间:2014-7-3 问题描述 当跨域(cross domain)调用ASP.NET MVC或者ASP. ...
- SpringCloud使用Nacos服务发现实现远程调用
本文使用SpringCloud结合Nacos服务发现,Feign远程调用做一个简单的Demo. 1 Nacos 关于Nacos之前写了两篇文章关于SpringBoot对它的使用,感兴趣可以查看一下. ...
随机推荐
- Vue双向数据绑定原理-中
defineProperty方法 defineProperty除了可以动态修改/新增对象的属性以外, 还可以在修改/新增的时候给该属性添加get/set方法, 从而实现数据劫持. defineProp ...
- React中引入外部js文件
假设需要引入本地的一个jquery库: <script src="http://127.0.0.1:8080/plugins/jquery.min.js" type=&quo ...
- SqlSugar的查询函数SqlFunc
用法 我们可以使用SqlFunc这个类调用Sql函数,用法如下: db.Queryable<Student>().Where(it => SqlFunc.ToLower(it.Nam ...
- Python 解析JSON实现主机管理
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,它以易于阅读和编写的文本形式表示数据.JSON 是一种独立于编程语言的数据格式,因此在不同的编程语言中都有对 ...
- PHP基础题目
1.请写一个函数实现以下功能:字符串'open_door'转换成'OpenDoor','make_by_id'转换成'MakeById' function strHandle($str) { $ret ...
- 2.2 实验:UPX脱壳--《恶意代码分析实战》
Lab01-02.exe 实验内容: 1.将文件上传到http://www.VirusTotal.com 进行分析并查看报告.文件匹配到了已有的反病毒软件特征吗? 2.是否有这个文件被加壳或混淆的任何 ...
- SESSION会话机制解析
Windows Session(会话)的概念 会话 session 是由代表单个用户登录会话的所有进程和系统对象组成的.其中的对象包括所有的窗口,桌面和windows stations.桌面是特定se ...
- Navicat 15 for MySQL 破解【我亲测可用】
1.去官网下载正版 https://www.navicat.com.cn/ 2.破解下载:https://files-cdn.cnblogs.com/files/del88/NavicatKeygen ...
- IIS的详细配置
一:配置默认文档 输入ip打开哪个页面是由默认文档设定的 1.打开IIS配置页面,点击网站.我们的默认站点已经启动,可以看到绑定的ip和网页的路径 2.选中Default Web Site,可以看到有 ...
- XML和JSON的比较
XML和JSON的比较 XML与JSON都可以用来描述或者存储数据,两者都有各自的优点,使用场景取决于需求. 描述 XML 可扩展标记语言Extensible Markup Language,是一种用 ...