04 业务服务注册到 nacos 默认权重为0, 导致 gateway 获取不到业务服务

这篇具有很好参考价值的文章主要介绍了04 业务服务注册到 nacos 默认权重为0, 导致 gateway 获取不到业务服务。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

最近搭建 xxx服务 的时候碰到了一个这样的问题 

某业务服务 启动之后, 注册到 nacos, 然后 从 gateway 来获取该服务却报错, 没有找到 xxx服务 

之前 记录了一个 todo, 今天 来梳理一下 

主要是会涉及到我们关注的问题, 以及 服务的注册流程 不会大而全 

nacos 服务实例元数据存储在哪里?

根据服务查询 服务实例 的接口为 "/v1/ns/catalog/instances", 处理的方法入口为 CatalogController.instanceList 

里面查询 服务实例 主要是 ServiceStorage.serviceDataIndexes, 根据 service 获取到 实例列表 

所以 在服务注册的流程中会将 当前服务实例 注册到 nacos 的 ServiceStorage.serviceDataIndexes 中 

nacos 服务注册流程

主要有两个方面, 一个方面是 客户端 请求服务注册, 另一方面是 nacos 服务器对于 服务注册请求 的处理 

客户端 请求服务注册, 主要是在 上下文 初始化完成之后发布了事件, 然后 NacosAutoServiceRegistration 里面开始向 nacos 注册 

nacos 服务器对于 服务注册请求 的处理, 这里可以抽象的理解为 将实例注册到 ServiceStorage.serviceDataIndexes, 其他的细节在我们这里的问题中, 我们并不关注 

客户端请求服务注册

客户端 请求服务注册 的堆栈信息如下 

在 上下文 初始化完成之后发布了事件, 然后 NacosAutoServiceRegistration 里面开始向 nacos 注册 

请求的 url 为 "http://10.60.50.16:8849/nacos/v1/ns/instance" 

携带的参数来自于 当前服务的上下文, 以及 nacosDiscoveryProperties 

nacosDiscoveryProperties 读取自 spring.cloud.nacos.discovery 的相关配置 

request:86, HttpClient (com.alibaba.nacos.client.naming.net)
callServer:433, NamingProxy (com.alibaba.nacos.client.naming.net)
reqAPI:468, NamingProxy (com.alibaba.nacos.client.naming.net)
reqAPI:401, NamingProxy (com.alibaba.nacos.client.naming.net)
reqAPI:397, NamingProxy (com.alibaba.nacos.client.naming.net)
registerService:212, NamingProxy (com.alibaba.nacos.client.naming.net)
registerInstance:207, NacosNamingService (com.alibaba.nacos.client.naming)
registerInstance:187, NacosNamingService (com.alibaba.nacos.client.naming)
register:63, NacosServiceRegistry (org.springframework.cloud.alibaba.nacos.registry)
register:239, AbstractAutoServiceRegistration (org.springframework.cloud.client.serviceregistry)
register:74, NacosAutoServiceRegistration (org.springframework.cloud.alibaba.nacos.registry)
start:138, AbstractAutoServiceRegistration (org.springframework.cloud.client.serviceregistry)
bind:101, AbstractAutoServiceRegistration (org.springframework.cloud.client.serviceregistry)
onApplicationEvent:88, AbstractAutoServiceRegistration (org.springframework.cloud.client.serviceregistry)
onApplicationEvent:47, AbstractAutoServiceRegistration (org.springframework.cloud.client.serviceregistry)
doInvokeListener:172, SimpleApplicationEventMulticaster (org.springframework.context.event)
invokeListener:165, SimpleApplicationEventMulticaster (org.springframework.context.event)
multicastEvent:139, SimpleApplicationEventMulticaster (org.springframework.context.event)
publishEvent:402, AbstractApplicationContext (org.springframework.context.support)
publishEvent:359, AbstractApplicationContext (org.springframework.context.support)
finishRefresh:165, ServletWebServerApplicationContext (org.springframework.boot.web.servlet.context)
refresh:552, AbstractApplicationContext (org.springframework.context.support)
refresh:141, ServletWebServerApplicationContext (org.springframework.boot.web.servlet.context)
refresh:743, SpringApplication (org.springframework.boot)
refreshContext:390, SpringApplication (org.springframework.boot)
run:312, SpringApplication (org.springframework.boot)
run:1214, SpringApplication (org.springframework.boot)
run:1203, SpringApplication (org.springframework.boot)

nacos 服务器对于 服务注册请求 的处理

nacos 服务器这边 处理的堆栈信息如下 

ServiceStorage 中主要包含了 clientManager, serviceIndexesManager, serviceDataIndexes, serviceClusterIndex 这几个数据结构, 在服务注册的流程中都会填充对应的数据 

主要的处理有 注册 service → client + InstancePublishInfo 到 ServiceStorage.clientManager 

封装 ClientOperationEvent.ClientRegisterServiceEvent 事件发布, 这个事件会关联到后面的一系列的业务处理 

registerInstance:65, EphemeralClientOperationServiceImpl (com.alibaba.nacos.naming.core.v2.service.impl)
registerInstance:50, ClientOperationServiceProxy (com.alibaba.nacos.naming.core.v2.service)
registerInstance:104, InstanceOperatorClientImpl (com.alibaba.nacos.naming.core)
register:115, InstanceController (com.alibaba.nacos.naming.controllers)

ClientRegisterServiceEvent  的处理会涉及到如下业务流程, 一个事件链 

ClientRegisterServiceEvent -> ServiceChangedEvent -> PushDelayTaskExecuteEngine -> PushExecuteTask.run

ClientRegisterServiceEvent 的事件处理, 会注册 service -> clientId 到 ServiceStorage.serviceIndexesManager 中


PushExecuteTask.run 里面涉及的处理主要是刷新 ServiceStorage.serviceDataIndexes, serviceClusterIndex
主要的处理是在 ServiceStorage.getPushData 中, 处理之后 当前服务的所有 Instance 列表就更新了
也就是上面提到的 "将实例注册到 ServiceStorage.serviceDataIndexes"

parseInstance:128, ServiceStorage (com.alibaba.nacos.naming.core.v2.index)
getAllInstancesFromIndex:109, ServiceStorage (com.alibaba.nacos.naming.core.v2.index)
getPushData:84, ServiceStorage (com.alibaba.nacos.naming.core.v2.index)
generatePushData:76, PushExecuteTask (com.alibaba.nacos.naming.push.v2.task)
run:58, PushExecuteTask (com.alibaba.nacos.naming.push.v2.task)
run:116, TaskExecuteWorker$InnerWorker (com.alibaba.nacos.common.task.engine)

为什么 xxx服务 注册到 nacos 之后默认权重为 0?

在 nacos 中 Instance 的默认 weight 为 1 

但是 为什么 xxx服务 注册到 nacos 之后 默认权重为 0 呢?

nacos 这边 InstanceController.register 拿到的 Instance 的权重为 0, 原因是客户端传过来的 weight 参数值为 0 

进而 注册到 clientManager 的 InstancePublishInfo 中的 weight 为 0 

ServiceStorage.getPushData 中获取 服务的所有 Instnace 的时候, 从 clientManager 中拿到的 InstancePublishInfo 的 weight 为 0 

进而 导致了 ServiceStorage.serviceDataIndexes 的服务对应的 Instnace 的 weight 为 0 

app -> unknown
metadata -> {"instance":"DESKTOP-SPHPNQ2","preserved.register.source":"SPRING_CLOUD","uptime":"2022-03-02 16:02:27"}
ip -> 10.60.50.16
weight -> 0.0
ephemeral -> true
encoding -> UTF-8
groupName -> DEFAULT_GROUP
namespaceId -> xxx_config
port -> 7703
enable -> true
healthy -> true

客户端发送 服务注册请求 的时候 

携带的参数来自于 当前服务的上下文, 以及 nacosDiscoveryProperties, 我们这里关注的权重来自于 nacosDiscoveryProperties.weight 

查看一下 xxx服务 这边的 spring.cloud.nacos.discovery.weight 的配置, 写死的 0 

            String serviceId = registration.getServiceId();
            Instance instance = new Instance();
            instance.setIp(registration.getHost());
            instance.setPort(registration.getPort());
            instance.setWeight((double)this.nacosDiscoveryProperties.getWeight());
            instance.setClusterName(this.nacosDiscoveryProperties.getClusterName());
            instance.setMetadata(registration.getMetadata());

            try {
                this.namingService.registerInstance(serviceId, instance);
                log.info("nacos registry, {} {}:{} register finished", new Object[]{serviceId, instance.getIp(), instance.getPort()});
            } catch (Exception var5) {
                log.error("nacos registry, {} register failed...{},", new Object[]{serviceId, registration.toString(), var5});
            }

gateway 这边获取 xxx服务实例 的时候过滤掉 weight 小于等于 0 的处理 

具体的处理是在 NacosNamingService.selectInstances(ServiceInfo serviceInfo, boolean healthy) 中 

    private List<Instance> selectInstances(ServiceInfo serviceInfo, boolean healthy) {
        List list;
        if (serviceInfo != null && !CollectionUtils.isEmpty(list = serviceInfo.getHosts())) {
            Iterator iterator = list.iterator();

            while(true) {
                Instance instance;
                do {
                    if (!iterator.hasNext()) {
                        return list;
                    }

                    instance = (Instance)iterator.next();
                } while(healthy == instance.isHealthy() && instance.isEnabled() && instance.getWeight() > 0.0D);

                iterator.remove();
            }
        } else {
            return new ArrayList();
        }
    }

完 文章来源地址https://www.toymoban.com/news/detail-401712.html

到了这里,关于04 业务服务注册到 nacos 默认权重为0, 导致 gateway 获取不到业务服务的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包