线上服务重启后 nacos取不到配置

背景

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

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

服务启动时,就会去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

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

报文如下:

网页端登录#

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

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

这个网页端,是用户名、密码都在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

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

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

复制代码
private Map<String, User> userMap = new ConcurrentHashMap<>();

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

具体的缓存开关是这个:

复制代码
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

复制代码
com.alibaba.nacos.plugin.auth.impl.controller.UserController#updateUser

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

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

复制代码
com.alibaba.nacos.plugin.auth.impl.users.NacosUserDetailsServiceImpl#reload

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

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

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

相关推荐
青 春 记 忆7 小时前
Dify Docker Compose 通用无损升级指南:从备份、双版本预演到切换与回滚
运维·人工智能·python·docker·容器
GlueNa2SiO37 小时前
03-Flask模板引擎Jinja2详解
笔记·python·flask
临沂GEO9 小时前
GEO搜索优化科普|正规地理位置流量运营入门指南
大数据·人工智能·python·流量运营
大模型码小白10 小时前
Spring AI Tool 实现自然语言操作 MySQL 数据库详解
服务器·开发语言·数据库·人工智能·python·mysql·spring
荷蒲11 小时前
【小白量化Qbuddy】利用AI学习中文Python
人工智能·python·学习
数据狐(Datafox)12 小时前
京东商品列表API技术解析与落地应用(含标准 JSON 示例)
java·大数据·前端·人工智能·python·数据分析·json
量化吞吐机13 小时前
2026年下半年手工交易规则走向量化表达,产品该先接住哪一步
人工智能·python
Metaphor69213 小时前
使用 Python 读取和删除 Excel 文件属性
python·excel
迷迭香yy14 小时前
Python构建转融券多空识别系统从接口到因子的全流程 IG50免费开源股票数据API接口
开发语言·python·开源
月光船幽幽15 小时前
真实即粗糙,光滑是伪造
人工智能·python