惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
云风的 BLOG
云风的 BLOG
Microsoft Security Blog
Microsoft Security Blog
WordPress大学
WordPress大学
GbyAI
GbyAI
C
Check Point Blog
M
MIT News - Artificial intelligence
T
The Blog of Author Tim Ferriss
Jina AI
Jina AI
博客园 - 【当耐特】
U
Unit 42
月光博客
月光博客
腾讯CDC
Y
Y Combinator Blog
小众软件
小众软件
博客园_首页
Last Week in AI
Last Week in AI
酷 壳 – CoolShell
酷 壳 – CoolShell
The GitHub Blog
The GitHub Blog
博客园 - 聂微东
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
MongoDB | Blog
MongoDB | Blog
博客园 - Franky
T
Tailwind CSS Blog

博客园 - 三国梦回

oracle中date类型在mybatis中查询时遇到的坑 mitmweb在linux上进行反向代理及浏览器中实时查看请求响应 codex对接智谱coding plan,我发现连cc switch也不用了 windows codex更新失败如何处理 windos上codex沙盒报错问题记录 廉颇老矣,装个EclipseMemoryAnalyzer都能卡一小时 codex windows平台中elevated sandbox机制学习 codex windows平台中unelevated sandbox机制学习 bug排查:nacos做配置管理,给服务返回的配置竟然是错的 windows安装codex desktop和cc-switch,接deepseek v4 flash windows安装ddns-go,上传动态的ipv6到自己的域名 immortalWrt路由器上抓包查看电脑联网如何获取ip 路由器刚刷的immortalWrt系统,我是如何配置ipv6的 路由器刷openwrt之ImmortalWrt过程记录--上 spring boot 项目中oracle datasource设置schema spring cloud项目中,在bootstrap.yml中指定了active的profile,结果不生效 nginx location没学好,把自己坑了一把 技术问题记录20260125 最近遇到的两个技术问题记录 linux服务器文件上传失败 线上遇到的redis和数据库数据未同步问题、redisson内部实现问题 复杂业务系统线上问题排查过程 nacos中配了一个数字,springboot取回来怎么变了 一个java空指针异常的解决过程 简单记录下最近2个月完成的线上系统迁移工作 centos停服,迁移centos7.3系统到新搭建的openEuler 端口telnet不通排查过程 https证书中的subject alternative name字段作用及如何生成含该字段的证书 linux中如何判断一个rpm是手动安装还是通过yum安装的 对接服务升级后仅支持tls1.2,jdk1.7默认使用tls1.0,导致调用失败
线上服务重启后,从nacos取不到配置了,怎么回事
三国梦回 · 2026-02-13 · via 博客园 - 三国梦回

背景

前一阵,线上某个服务升级,典型的spring boot应用,引入了spring cloud,主要是为了使用nacos来统一管理配置。

典型的bootstrap.yml配置如下,包含了用户名密码:

image-20260213093118522

服务启动时,就会去nacos读取配置,读取配置当然要先登录,这里配置的用户名密码就是登录用的。

我们遇到的问题是,线上那个服务,不是第一次上线,一直跑得好好的,本次更新主要是更新了fat jar,改了点业务逻辑,像bootstrap.yml这些没任何改动。结果运维同事替换了jar包后一重启,说启动不了,说你这个包是不是有问题啊。

定位过程

抓包

过去运维那边看了下,发现报错是说什么数据库连不上,ip一看,是开发环境的数据库ip,我就感觉是不是没取到nacos里的配置,所以用了默认的开发环境配置了(fat jar中有默认的开发环境配置文件)。

我就说这得抓个包看看,nacos的监听端口是8848,主要用于登录,获取token;还有9849,用于服务注册、配置拉取等。

tcpdump -i any tcp port 8848 or tcp port 9848 -w nacos.pcap

把包抓下来一看,发现确实没拉取到配置,但是,原因是登录就失败了。

报文如下:

image-20260213093813785

网页端登录

难道是密码错了吗,然后同样的用户密码,在nacos管理系统那里登录,发现是正常的。这个确实是很奇怪,F12看了下,看了接口也是上面那个接口。

image-20260213094323596

唯一不同的也就是参数携带方式有一点差异:

image-20260213094353557

这个网页端,是用户名、密码都在form表单的http body里。而api那边,是username在url里,密码在body里。

拉人

然后我们就确认是nacos 服务端感觉有点问题。另外,我们也找了其他类似的服务A,把那个服务A用的nacos用户名、密码拿过来,配置到本服务里,重启,发现竟然也报同样的错误。

然后就感觉是nacos服务端出了问题,找到对应负责的同事,一起来看。我们还测了下,把服务A自己重启了下,发现重启也启动不起来了,同样是提示403,用户找不到。

接下来,继续测试,当时是怀疑是不是密码有特殊字符导致的,然后nacos负责人,把我们的用户的密码重置了下,然后我们重试,发现可以了。

最终的解决,就是靠:

把用户的密码重置一下,也就是改一下密码就好了(但不是特殊字符的问题,我们试着改成了有特殊字符的密码,发现还是可以成功启动的)。

这个事当时也就了了,没管了。

继续探索

登录接口

今天空了后,感觉这个事情还是有点古怪,为什么密码重置后就好了,当时我就怀疑:nacos服务端内部估计有缓存,可能是缓存出问题了,然后重置密码这个动作,就导致缓存变得正常了。

网上没找到特别匹配我这个案例的,翻了半天,看到有nacos源码解析的,于是我就想着代码拉下来看一下算了。

线上的nacos版本不确定,但应该是2.2.2,因为我看了下开发环境就是这个版本。

找了对应的源码:

https://github.com/alibaba/nacos/tree/2.2.2

https://github.com/alibaba/nacos/releases/tag/2.2.0

直接下了个zip包,idea里打开。

全局搜索login",发现如下代码:

com.alibaba.nacos.plugin.auth.impl.controller.UserController#login

image-20260213095720124

image-20260213095743794

然后,这里有个根据用户名,查找用户详细信息的:

image-20260213095803120

下面这里,先是去一个缓存map里查询,如果没开启一个cacheEnabled的开关,则会继续去查数据库,以数据库的为准:

private Map<String, User> userMap = new ConcurrentHashMap<>();

image-20260213095851520

我看了下,我们本地开发环境的开关,反正是默认打开的,我估计,线上也是这样,也就是说,是允许缓存的,这都年末了,运维放假了,不打扰了。

具体的缓存开关是这个:

public static final String NACOS_CORE_AUTH_CACHING_ENABLED = "nacos.core.auth.caching.enabled";

配置文件中是开启的:

[root@COMPASS-NACOS-1 nacos]# cat conf/application.properties |grep caching
### Turn on/off caching of auth information. By turning on this switch, the update of auth information would have a 15 seconds delay.
nacos.core.auth.caching.enabled=true

那就是了,应该就是缓存里的用户数据有问题。

那为啥,重置密码就好了呢?

修改密码接口

修改密码这个,我们当时还测试了,自己改密码还不行,必须是nacos负责人那个管理账号改了才生效的。

另外,我看了下,上面那个登录接口里,查用户的sql如下:

    public User findUserByUsername(String username) {
        String sql = "SELECT username,password FROM users WHERE username=? ";
        return databaseOperate.queryOne(sql, new Object[] {username}, USER_ROW_MAPPER);
    }

那修改密码,全局搜一下update users

image-20260213100640175

com.alibaba.nacos.plugin.auth.impl.controller.UserController#updateUser

image-20260213100822326

我们发现,改密码的接口,朴实无华,就是改下数据库,没涉及到清下缓存啥的:

image-20260213100836452

那就从那个缓存的map着手,看了下:

com.alibaba.nacos.plugin.auth.impl.users.NacosUserDetailsServiceImpl#reload

结果发现了一个定时任务,这里每隔15s执行一次,从数据库加载user数据到缓存:

image-20260213101021274

那就理解了,改密码是只操作数据库;然后定时任务去数据库查询最新数据,放到缓存里,这样呢,缓存数据就和数据库数据一致了。

另一个猜测:缓存每15秒从数据库同步,缓存数据有问题,是不是说明有问题的可能是数据库呢?也就是说,数据库里的用户数据出了问题,通过修改密码的方式才正常,然后15秒后,缓存里数据变得正常。

至于数据库数据为啥出了问题,这个就不好找了,本篇就不探究了。