sentinel集成nacos启动报[check-update] get changed dataId error, code: 403错误排查及解决

news2025/1/2 21:15:20

整合nacos报403错误

因为平台写的一个限流代码逻辑有问题,所以准备使用sentinel来限流。平台依赖里面已经引入了,之前也测试过,把sentinel关于nacos的配置加上后,启动一直输出403错误 [fixed-10.0.20.188_8848-test] [check-update] get changed dataId error, code: 403
在这里插入图片描述

403的原因

先说结论,sentinel(我这里用到的alibaba-sentinel-datasource2.1.2.RELEASE版本)的代码有问题,他这个版本的nacos相关配置没有usernamepassword的属性,导致只能在nacos服务没有配置账号密码的时候使用,一旦改了账号密码,就无法正常访问nacos。今年不能用去年可以是因为今年测试环境nacos改了密码而去年是默认的。(文心一言竟然跟我说,他是共享了nacos的配置,所以不用配置账号密码,离谱)

仓库找了个比这高的版本(2021.0.5.0),发现这两个属性加上了,有需要的可以升级试试。不得不吐槽一句,这个依赖的版本是真的多,而且还没啥规律。如果想通过改源码的方式解决问题看最后

<!-- https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-starter-alibaba-sentinel -->
<dependency>
	<groupId>com.alibaba.cloud</groupId>
	<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
	<version>2021.0.5.0</version>
</dependency>

在这里插入图片描述
配置截图,
在这里插入图片描述

com.alibaba.cloud.sentinel.datasource.config.NacosDataSourceProperties类截图:
在这里插入图片描述

403问题排查过程

打断点查看http请求代码

因为控制台输出了ERROR日志,找到输出日志的代码行,打个断点。这里打断点是最方便的,我是通过logging.levellog级别改成了trace,然后看的http请求日志,在请求那里打的断点。
com.alibaba.nacos.client.config.impl.ClientWorker
在这里插入图片描述
通过调试发现在386行会发起http请求nacos服务器,agent属性是sentinel自己写的一个HttpAgent对象,主要是在发送http请求前做一些处理(比如拼上配置文件里面配置的nacos.server-addr)。
在这里插入图片描述
调用agent.httpPost之后,会在com.alibaba.nacos.client.config.http.ServerHttpAgent#httpPost处理,ServerHttpAgent类是HttpAgent接口的实现类。这里面主要就是在发送http请求之前,通过injectSecurityInfo方法给请求参数加入一些安全相关的参数。
在这里插入图片描述
injectSecurityInfo方法里面会判断securityProxy属性里面是否有token,有就加入,这里为空,所以大概率是这个问题了。
在这里插入图片描述

和nacos框架发送的http请求做对比

为了做一个对比,查看一下nacos框架发送的http请求和这个有啥区别,因为这是nacos里面的代码,所以nacos框架也会调用,可以看一下nacos框架请求nacos服务器里面有哪些信息。
在这里插入图片描述
可以发现nacos框架发送的请求,他这个securityProxy里面是有token信息的。这个是能正常请求nacos服务器的。现在能确定问题就是出现在这里了。所以现在的重点就是securityProxy这个属性。
在这里插入图片描述

securityProxy属性排查

因为SecurityProxyServerHttpAgent类的属性,搜了一下发现这个属性只在构造函数那里初始化赋值的,所以在ServerHttpAgent类的构造函数那里打个断点。在nacos框架初始化和sentinel初始化的时候,都会来调用这个,所以我们可以通过调试nacos框架的初始化来排查sentinel这边的哪里出了问题。
在这里插入图片描述
com.alibaba.nacos.client.config.http.ServerHttpAgent#ServerHttpAgent(java.util.Properties)截图
在这里插入图片描述

由于这个地方是在项目启动的时候调用,所以打完断点需要重启一下。

nacos框架初始化securityProxy

进入断点之后,发现nacos框架的这个properties里面是有账号密码配置的(配置文件里面配置了)
在这里插入图片描述

在这里插入图片描述
com.alibaba.nacos.client.security.SecurityProxy构造器里面给账号密码属性赋值(sentinel的那个压根都没有这两个属性,所以也能解释的通了,按道理这么低级的错误不应该的)
在这里插入图片描述
赋值完成之后,调用SecurityProxy里面的login方法,这个方法会发送登录请求,然后拿到token赋值给accessToken属性。
在这里插入图片描述

sentinel整合nacos的初始化securityProxy

com.alibaba.cloud.sentinel.custom.SentinelDataSourceHandler#afterSingletonsInstantiated类继承了SmartInitializingSingleton类,并重写了afterSingletonsInstantiated方法
文心一言:

SmartInitializingSingleton接口用于在Spring容器中所有单例Bean初始化完成后执行一些自定义的初始化逻辑。当所有单例Bean的依赖关系都解析完毕,并且所有单例Bean的实例化与初始化过程完成后,Spring容器会自动回调SmartInitializingSingleton接口的实现类的afterSingletonsInstantiated()方法。这个方法只会被调用一次。

在这个重写的方法内部,会对每个数据源进行初始化。sentinel里面每一个数据源都对应一个bean,这个beansentinel自己的beanFactory创建。
在这里插入图片描述
注册bean的方法。里面有一行BeanDefinitionBuilder.genericBeanDefinition(dataSourceProperties.getFactoryBeanName());代码,用来创建一个bean定义构造器对象,后面要使用这个对象要创建NacosDataSourceFactoryBean类的bean
文心一言:

BeanDefinitionBuilder主要用于在Spring的IoC(Inversion of Control,控制反转)容器中构建和配置Bean定义。Bean定义描述了如何创建一个Bean实例,包括其类名、作用域、初始化方法、属性设置等信息。通过BeanDefinitionBuilder,开发者可以以编程的方式轻松地创建和配置Bean定义,而不需要手动编写冗长的XML配置文件或注解。

在这里插入图片描述
遍历属性集合,然后里面校验一下,就通过BeanDefinitionBuilder builder对象把这些属性添加进去
在这里插入图片描述
注册bean之后又通过beanFactory来获取bean,注册的bean类型是com.alibaba.cloud.sentinel.datasource.factorybean.NacosDataSourceFactoryBean类型
在这里插入图片描述
sentinel自己实现的BeanFactory#getObject方法内,每次都是返回NacosDataSource对象(也就是说前面创建的bean是这个自定义的工厂bean,每次getBean都是获取到NacosDataSource对象,如果想获取到这个bean对象本身,getBean的时候名字前面加一个&)。在初始化Properties的时候,只判断地址是否配置,都没有关于账号密码的代码,所以sentinelnacos数据源在当初设计的时候,就是没有考虑到nacos会改账号或密码的情况,而不是配置文件里面漏了这两个属性。
在这里插入图片描述
因为前面都没有账号密码,所以ServerHttpAgent构造器这里的属性里面只有两个值,肯定也没有用户名和密码的。
在这里插入图片描述
在这里插入图片描述
大致的调用栈
在这里插入图片描述

排查结论

通过排查发现,这个对象所需的属性是从配置文件中拿的,因为nacos框架配置了usernamepassword,所以拿的到。而sentinel并没有提供相应的属性配置,所以就为空,直接导致了后面的403问题。

解决方案

  1. 如开头所说,升级版本就可以了,这是最简单的,当然有的系统可能升级之后会报错,这个就需要自己排查一下了
  2. 把账号密码改成默认的(当我没说,这个应该没人弄)
  3. 重写代码,自己项目main/java下面创建一个全类名一样的类,覆盖原有的类
    com.alibaba.cloud.sentinel.datasource.factorybean.NacosDataSourceFactoryBean类和com.alibaba.cloud.sentinel.datasource.config.NacosDataSourceProperties类,在两个类里面都加上usernamepassword属性,然后在NacosDataSourceFactoryBean里面赋值给属性类。
    或者说不改NacosDataSourceProperties代码直接改NacosDataSourceFactoryBean工厂,在里面获取nacos框架的配置,用那里面的账号密码也可以。

重写的NacosDataSourceProperties类,记得加setget方法,也可以使用Lombok

package com.alibaba.cloud.sentinel.datasource.config;

import com.alibaba.cloud.sentinel.datasource.factorybean.NacosDataSourceFactoryBean;
import org.springframework.util.StringUtils;

import javax.validation.constraints.NotEmpty;

/**
 * Nacos Properties class Using by {@link DataSourcePropertiesConfiguration} and
 * {@link NacosDataSourceFactoryBean}.
 *
 * @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
 */
public class NacosDataSourceProperties extends AbstractDataSourceProperties {

    private String serverAddr;

    @NotEmpty
    private String groupId = "DEFAULT_GROUP";

    @NotEmpty
    private String dataId;

    private String endpoint;

    private String namespace;

    private String accessKey;

    private String secretKey;

    /**
     * 自己添加的属性 用户名
     */
    private String username;

    /**
     * 自己添加的属性 名称
     */
    private String password;

    public NacosDataSourceProperties() {
        super(NacosDataSourceFactoryBean.class.getName());
    }

    @Override
    public void preCheck(String dataSourceName) {
        if (StringUtils.isEmpty(serverAddr)) {
            serverAddr = this.getEnv().getProperty(
                    "spring.cloud.sentinel.datasource.nacos.server-addr",
                    "localhost:8848");
        }
    }

    public String getServerAddr() {
        return serverAddr;
    }

    public void setServerAddr(String serverAddr) {
        this.serverAddr = serverAddr;
    }

    public String getGroupId() {
        return groupId;
    }

    public void setGroupId(String groupId) {
        this.groupId = groupId;
    }

    public String getDataId() {
        return dataId;
    }

    public void setDataId(String dataId) {
        this.dataId = dataId;
    }

    public String getEndpoint() {
        return endpoint;
    }

    public void setEndpoint(String endpoint) {
        this.endpoint = endpoint;
    }

    public String getNamespace() {
        return namespace;
    }

    public void setNamespace(String namespace) {
        this.namespace = namespace;
    }

    public String getAccessKey() {
        return accessKey;
    }

    public void setAccessKey(String accessKey) {
        this.accessKey = accessKey;
    }

    public String getSecretKey() {
        return secretKey;
    }

    public void setSecretKey(String secretKey) {
        this.secretKey = secretKey;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getUsername() {
        return username;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getPassword() {
        return password;
    }
}

重写的NacosDataSourceFactoryBean类,太长了,这里就列出部分,直接加进去就行了。别忘了setget方法

    /**
     * 自己添加的属性 用户名
     */
    private String username;


    /**
     * 自己添加的属性 密码
     */
    private String password;

	@Override
    public NacosDataSource getObject() throws Exception {
        Properties properties = new Properties();
        if (!StringUtils.isEmpty(this.serverAddr)) {
            properties.setProperty(PropertyKeyConst.SERVER_ADDR, this.serverAddr);
        } else {
            properties.setProperty(PropertyKeyConst.ACCESS_KEY, this.accessKey);
            properties.setProperty(PropertyKeyConst.SECRET_KEY, this.secretKey);
            properties.setProperty(PropertyKeyConst.ENDPOINT, this.endpoint);
        }
        if (!StringUtils.isEmpty(this.namespace)) {
            properties.setProperty(PropertyKeyConst.NAMESPACE, this.namespace);
        }
        // 自己加的逻辑  把账号密码加进去
        if (!StringUtils.isEmpty(this.username)) {
            properties.setProperty(PropertyKeyConst.USERNAME, this.username);
        }
        if (!StringUtils.isEmpty(this.password)) {
            properties.setProperty(PropertyKeyConst.PASSWORD, this.password);
        }
        return new NacosDataSource(properties, groupId, dataId, converter);
    }

改造之后效果截图:
在这里插入图片描述
账号密码等属性都有了
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2268221.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

紫光同创-盘古200pro+开发板

本原创文章由深圳市小眼睛科技有限公司创作&#xff0c;版权归本公司所有&#xff0c;如需转载&#xff0c;需授权并注明出处&#xff08;www.meyesemi.com) 一、开发系统介绍 开发系统概述 MES2L676-200HP 开发板采用紫光同创 logos2 系列 FPGA&#xff0c;型号&#xff1a;…

Vue开发环境搭建上篇:安装NVM和NPM(cpnm、pnpm)

文章目录 引言I 安装NVM1.1 Windows系统安装NVM,实现Node.js多版本管理1.2 配置下载镜像1.3 NVM常用操作命令II NPM永久使用淘宝源安装 cnpm安装pnpm【推荐】see also: vscode常用插件引言 淘宝镜像:http://npm.taobao.org 和 http://registry.npm.taobao.org 已在 2022.06.3…

【AI大模型】探索GPT模型的奥秘:引领自然语言处理的新纪元

目录 &#x1f354; GPT介绍 &#x1f354; GPT的架构 &#x1f354; GPT训练过程 3.1 无监督的预训练语言模型 3.2 有监督的下游任务fine-tunning &#x1f354; 小结 学习目标 了解什么是GPT.掌握GPT的架构.掌握GPT的预训练任务. &#x1f354; GPT介绍 GPT是OpenAI公…

正则表达式(三剑客之sed)

1.sed工具的使用 1.1 sed工具 1&#xff09;命令格式&#xff1a;sed -n ‘n’ p filename 1.2 打印某行 1&#xff09;打印第二行 [rootlocalhost ~]# sed -n 2p /etc/passwd 2&#xff09;第二行重复打印 [rootlocalhost ~]# sed 2p /etc/passwd 3&#xff09;所有行全部…

细说STM32F407单片机IIC总线基础知识

目录 一、 I2C总线结构 1、I2C总线的特点 2、I2C总线通信协议 3、 STM32F407的I2C接口 二、 I2C的HAL驱动程序 1、 I2C接口的初始化 2、阻塞式数据传输 &#xff08;1&#xff09;函数HAL_I2C_IsDeviceReady() &#xff08;2&#xff09;主设备发送和接收数据 &#…

Android笔试面试题AI答之Android基础(7)

Android入门请看《Android应用开发项目式教程》&#xff0c;视频、源码、答疑&#xff0c;手把手教 文章目录 1.Android开发如何提高App的兼容性&#xff1f;**1. 支持多版本 Android 系统****2. 适配不同屏幕尺寸和分辨率****3. 处理不同硬件配置****4. 适配不同语言和地区**…

《机器学习》线性回归模型实现

目录 一、一元线性回归模型 1、数据 2、代码 3、结果 二、多元线性回归模型 1、数据 2、代码 3、结果 一、一元线性回归模型 1、数据 2、代码 # 导入所需的库 import pandas as pd # 用于数据处理和分析 from matplotlib import pyplot as plt # 用于数据可视化 fr…

基于DIODES AP43781+PI3USB31531+PI3DPX1207C的USB-C PD Video 之全功能显示器连接端口方案

随着USB-C连接器和PD功能的出现&#xff0c;新一代USB-C PD PC显示器可以用作个人和专业PC工作环境的电源和数据集线器。 虽然USB-C PD显示器是唯一插入墙壁插座的交流电源输入设备&#xff0c;但它可以作为数据UFP&#xff08;上游接口&#xff09;连接到连接到TCD&#xff0…

QWidget应用封装为qt插件,供其他qt应用调用

在之前的文章中,有介绍通过QProcess的方式启动QWidget应用,然后将其窗口嵌入到其他的qt应用中,作为子窗口使用.这篇文章主要介绍qt插件的方式将QWidget应用的窗口封装为插件,然后作为其他Qt应用中的子窗口使用. 插件优点: 与主程序为同一个进程,免去了进程间繁琐的通信方式,…

关于 覆铜与导线之间间距较小需要增加间距 的解决方法

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/144776995 长沙红胖子Qt&#xff08;长沙创微智科&#xff09;博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV…

ArcGIS教程(009):ArcGIS制作校园3D展示图

文章目录 数据下载校园3D展示图制作创建要素类矢量化【楼】要素矢量化【绿地】矢量化【范围】矢量化处理打开ArcScene添加动画数据下载 https://download.csdn.net/download/WwLK123/90189025校园3D展示图制作 创建要素类 添加底图: 新建【文件地理数据库】,并修改名称为【…

权限注解+AOP切面+额外工具(UUID生成id,JWT,Servlet客户端,字符串String工具类,Redis序列化,ip工具类)

权限功能和注解的关系 ①、定义三个注解 //角色认证&#xff0c;必须具有指定角色标识才能进入该方法 Retention(RetentionPolicy.RUNTIME) Target({ElementType.METHOD,ElementType.TYPE}) public interface RequiresRoles{//需要校验的角色标识String[] value() default {}…

RGB、HSV颜色模型及MATLAB互换应用实例

一、前言 RGB和HSV模型是数字图像处理中颜色空间中的两种重要表示方式&#xff0c;RGB和HSV都是描述颜色的数学模型&#xff0c;可以用于表示和处理图像中的颜色信息。 RGB模型是一种基于光的颜色模型&#xff0c;由红&#xff08;Red&#xff09;、绿&#xff08;Green&#x…

MySQL基础-常见的增删改查操作语句总结

1.数据库操作 查看所有数据库 show databases;创建数据库 create database db_stu; --如果数据库已经存在就不创建 create database if not exists db_stu; --添加默认字符集 create database db_stu default charset utf8mb4;删除数据库 drop database db_stu; --如果存在…

【运维】部署MKDocs

部署MKDocs obsidian 记录笔记&#xff0c;通过 mkdocs 私有化部署。 1 使用MKDocs创建笔记 创建仓库&#xff0c;安装 Material for MkDocs 和 mkdocs-minify-plugin mkdir tmp cd tmp git initpip install mkdocs-material pip install mkdocs-minify-pluginmkdocs new .2 …

黑马Java面试教程_P2_MySQL

系列博客目录 文章目录 系列博客目录前言1. 优化1.1 MySQL中&#xff0c;如何定位慢查询&#xff1f;面试文稿 1.2 面试官接着问&#xff1a;那这个SQL语句执行很慢,如何分析 ( 如何优化&#xff09;呢?面试文稿 1.3 了解过索引吗?(什么是索引)1.4 继续问 索引的底层数据结构…

【优选算法】盛最多水的容器(双指针算法)

11. 盛最多水的容器 - 力扣&#xff08;LeetCode&#xff09; 【1.题目】 【2.算法原理】 【3.代码编写】 优化之后就遍历了一遍数组&#xff0c;时间复杂度变为O(N)&#xff0c;就使用了几个变量&#xff0c;空间复杂度为O(1)。 class Solution { public:int maxArea(vecto…

安装torch-geometric库

目录 1.查看 torch 和 CUDA 版本 2.依次下载和 torch 和 CUDA 对应版本的四个依赖库pyg-lib、torch-scatter、torch-sparse、torch-cluster以及torch-spline-conv 3.下载并安装torch-geometric库 1.查看 torch 和 CUDA 版本 查看CUDA版本 nvcc -V 查看pytorch版本 pip s…

王佩丰24节Excel学习笔记——第十八讲:Lookup和数组

【以 Excel2010 系列学习&#xff0c;用 Office LTSC 专业增强版 2021 实践】 【本章技巧】 地址栏公式可以使用 F9 查看&#xff0c;取消请按Esc键&#xff0c;或者公式前的红色叉&#xff1b;使用数组时一定要注意使用绝对引用&#xff0c;方便下拉&#xff1b;使用数组时一…

【hackmyvm】hacked靶机wp

tags: HMVrootkitDiamorphine Type: wp 1. 基本信息^toc 文章目录 1. 基本信息^toc2. 信息收集2.1. 端口扫描2.2. 目录扫描2.3. 获取参数 3. 提权 靶机链接 https://hackmyvm.eu/machines/machine.php?vmHacked 作者 sml 难度 ⭐️⭐️⭐️⭐️️ 2. 信息收集 2.1. 端口扫描…