ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

WEBASE部署报错:node-mgr mysql user/password error排查全攻略

WEBASE部署报错:node-mgr mysql user/password error排查全攻略 WEBASE部署翻过车的人十有八九都跟这个报章打过照面“[Error]node-mgrs mysql user/password error!”。我第一次遇到的时候第一反应是“我密码是不是填错了”反复检查了好几遍配置文件密码确实没问题结果服务还是死活起不来。后来把整条链路捋了一遍才发现这个错背后能藏的东西比表面多得多——不只是密码本身还有认证插件、Host授权、YAML解析、JDBC驱动兼容性这些连环坑。这是一篇实战排查记录按我踩坑时的真实顺序来写。无论你是刚接触WEBASE的小白还是被这个错折磨了一下午的老手照着这里的排查链路走一遍基本都能定位到问题在哪。1. 这个报错在部署链路中的真实位置1.1 WEBASE各组件里谁在报这个错WEBASE这套区块链中间件平台部署时通常不止一个进程。其中node-mgrWeBASE-Node-Manager是核心管理服务负责跟链上节点通信、管理私钥、处理业务数据而这些数据最终要落到MySQL里。所以启动流程一展开node-mgr要做的第一件事就是初始化数据源跟MySQL建立连接池。如果这一步过不去整个服务直接起不来控制台或日志里就会抛这个error。说人话就是node-mgr想拿账号密码去开MySQL的门门没开服务就站在门口不走了。这就是为什么很多人在WEBASE-web或其他前端页面上看到502、连不上后端翻后端日志才发现是node-mgr压根没起来。1.2 日志在哪看别瞎猜报错信息虽然会出现在启动控制台但完整堆栈一般在日志文件里。WEBASE各子服务的日志路径通常长这样WeBASE-Node-Manager/logs/WeBASE-Node-Manager.log排查时我习惯先看这几点nohup.out或控制台最后的几行确认是不是确实卡在数据源初始化WeBASE-Node-Manager.log里的Caused by部分这里会带出最底层的数据库异常如果用了webase-deploy一键部署脚本还会有一个deploy.log里面记录了脚本执行到哪一步挂的。日志里的关键异常类型大概分三类我整理了一下方便你对号入座日志关键字指向原因Access denied for user xxx...账号密码错或Host授权不匹配Unknown database webasenodemanager数据库没建或建错名字Unable to load authentication plugin caching_sha2_passwordMySQL8默认认证插件与旧JDBC驱动不兼容Communications link failure端口不通、MySQL没起、或连接被拒1.3 “user/password error”的报错来源这个error本身是WEBASE启动脚本对数据库连通性做预检查时抛出来的。也就是说在你真正启动node-mgr之前脚本先替你做了一次“试连接”试不通就直接报这个错根本不会继续往下走。这时候容易产生一个误区以为改完配置重新启动就行忽略了脚本里也可能有独立的一套数据库连接配置。我后来发现webase-deploy部署目录下的配置和node-mgr的application.yml是两套东西必须保持一致。尤其是密码带特殊字符时脚本里能过YAML里不一定能过。2. 第一轮排查MySQL服务与连接验证2.1 先确认MySQL进程真的活着别笑这一步真的有很多人跳过。我见过不止一次MySQL服务压根没启动所有人都在检查配置文件和密码。在Linux上先敲两条命令ps -ef | grep mysql netstat -tlnp | grep 3306如果进程列表里没有mysqld或者3306端口没监听那问题根本不是user/password是MySQL压根没起来。针对netstat输出为空的情况还要区分是服务挂了还是只监听在本地# 看MySQL是否只绑定了127.0.0.1 ss -tlnp | grep 3306如果绑定的是127.0.0.1:3306而node-mgr通过其他IP去连自然会失败。这个在本地部署时不多见但如果你把MySQL和WEBASE拆分部署在不同的机器上就会踩中。2.2 用同样的账号在命令行里手动登录一次这是整个排查过程中性价比最高的一个动作。拿你配置在node-mgr里的用户名和密码在命令行里手动登录一遍mysql -unode_mgr_username -p -h127.0.0.1 -P3306注意这里的-h要跟node-mgr配置文件里的数据库地址保持一致。如果配置文件里写的是127.0.0.1你命令行也写127.0.0.1别用localhost替代因为两者在MySQL的授权匹配里并不是完全等价。手动登录的结果有几种能登录说明账号密码本身是对的问题在应用层继续看第4节报Access denied for user说明密码对不上或者Host授权不匹配处理办法看2.3登录卡住半天然后超时说明网络或防火墙有问题跟密码没关系。2.3 Host授权是最大的隐性变量MySQL的账号是由user和host两部分组成的。dbuserlocalhost和dbuser%是两个不同的账号密码也可以各自独立设置。很多人用root安装MySQL的时候root只授权了localhost。但node-mgr连接时如果走TCP协议访问127.0.0.1有些场景下MySQL会按host匹配可能匹配不到localhost授权导致Access denied。我在部署WEBASE时创建单独的业务账号时通常直接授权成%一劳永逸。命令是这样的CREATE USER webase% IDENTIFIED BY 你的密码; GRANT ALL PRIVILEGES ON webasenodemanager.* TO webase%; FLUSH PRIVILEGES;当然如果你内心比较抗拒用%那至少要明确知道node-mgr会从哪个IP连过来然后按具体IP授权。但别授权成localhost后又用127.0.0.1去连这种错最容易让人怀疑人生。下面这个表就是我当时用来判断的连接方式匹配的Hostmysql -uroot -p本地socketlocalhostmysql -uroot -p -h127.0.0.1127.0.0.1或%通配mysql -uroot -p -h内网IP对应IP或%通配3. 第二轮排查node-mgr配置文件的暗坑3.1 application.yml里的数据源配置长什么样如果命令行能登录那问题大概率出在node-mgr的配置文件上。核心配置文件位置在WeBASE-Node-Manager/conf/application.yml重点关注这一段spring: datasource: url: jdbc:mysql://127.0.0.1:3306/webasenodemanager?serverTimezoneAsia/ShanghaiuseUnicodetruecharacterEncodingUTF-8useSSLfalse username: webase password: 你的密码很多人改完配置启动还是报一样的错这时候要检查三件事用户名、密码是否跟MySQL里实际账号一致URL里的数据库名webasenodemanager是否真实存在配置里的IP和端口是否跟MySQL实际监听一致。3.2 密码里的特殊字符在YAML中会“自杀”这个坑极其隐蔽而且报错信息会让你误以为是密码本身填错了。如果你的MySQL密码里带有、#、:、{、}这类字符直接裸写在YAML里就可能被YAML解析器错误解读。比如密码是abc123某些解析逻辑会把后面的内容当成锚点或特殊语法遇到#开头后面的内容直接被当成注释吞掉。我见过一个真实案例密码设成Pass#1234结果#后面的1234被当注释实际密码变成PassMySQL那边一校验自然就是user/password error而且日志里完全看不出被截断。解决办法很简单把所有敏感字符串加上引号password: Pass#1234如果密码里本身有双引号那就用单引号包起来或者在双引号前加反斜杠转义。保守一点的建议是部署环境中直接用不含特殊字符的密码省掉一整个类别的麻烦。3.3 配置文件改完别忘了这一下很多人配置文件改对了但还是起不来因为Java进程还在用旧的配置跑着。重启服务不是简单地杀掉再起一次就行要确保旧进程彻底退出了ps -ef | grep WeBASE-Node-Manager kill -9 进程ID然后再启动。如果不放心可以在启动后立即看一眼日志搜tomcat或started关键字确认是新起的还是老的。另外如果webase-deploy脚本里也有一份数据库配置别只改node-mgr的application.yml。脚本在预检查阶段用的那份配置不更新你会被同一个报错反复拦在门口。4. 第三轮排查MySQL 8认证插件与JDBC驱动的兼容性4.1 现象命令行能登录服务死活起不来这是最邪门的一种情况也是我那次真正踩中的。MySQL命令行用root和新账号都能登录密码肯定没错Host授权也看过了配置文件也改对了YAML特殊字符也加了引号可node-mgr一启动报的还是user/password error。翻日志看到一行特别扎眼的Unable to load authentication plugin caching_sha2_password那一刻我意识到问题根本不在密码而在密码的“校验方式”。4.2 追根溯源MySQL 8默认认证插件的锅MySQL 5.7时代默认的认证插件是mysql_native_password老一辈JDBC驱动都认识它。到了MySQL 8.0默认改成了caching_sha2_password加密方式更安全但旧版本的mysql-connector-java驱动根本不认识这个插件。WEBASE某些版本自带的JDBC驱动还停留在5.1.x的时代拿它去连MySQL 8双方一对暗号谁都听不懂对方在说什么服务端只能丢出一句认证错误。表面上看起来是user/password error实际是“方言不通”。这个坑最迷惑人的地方就在于你手动用mysql命令行能登录是因为命令行客户端支持新的认证插件但应用里的JDBC驱动是“老古董”它不支持所以只有应用登录失败。4.3 两种修复思路的取舍修复有两种方向我按推荐程度排个序方案一把MySQL账号的认证插件改回mysql_native_passwordALTER USER webase% IDENTIFIED WITH mysql_native_password BY 你的密码; FLUSH PRIVILEGES;改完之后再启动node-mgr大概率就好了。这个方案不需要动任何代码或JAR包适合快速止血。方案二升级JDBC驱动到8.x版本去把WeBASE-Node-Manager/lib目录下旧版本的mysql-connector-java替换成8.0.x以上的版本同时确保URL里的参数是新驱动认可的写法。这个方案更“治本”但要注意WEBASE版本和驱动版本之间可能会有兼容性风险替换前先备份。我的建议是如果你只是部署环境方案一最省事如果是长期维护的正式环境方案二更稳妥。不过方案二一定要做好回滚准备别把所有库存倒腾完了发现WEBASE某些功能对驱动版本有硬性要求。5. 按场景修复从配置到验证的一次完整闭环5.1 场景A纯密码问题检查application.yml里username/password是否跟MySQL账号一致检查密码中特殊字符是否被YAML截断命令行用同一套账号密码登录验证。5.2 场景BHost授权不对查看MySQL用户表SELECT user, host, plugin FROM mysql.user;看WEBASE节点所在机器的实际IP是否在授权范围内如果拿不准直接授权成webase%再刷新权限。5.3 场景C认证插件兼容问题确认MySQL版本和JDBC驱动版本遇到MySQL 8 老驱动的组合直接改认证插件改完再验证一次SELECT user, host, plugin FROM mysql.user WHERE userwebase;5.4 修复后的标准验证流程不管走了上面哪条路最后我都会按这套流程确认服务真的起来了# 1. 确认MySQL连接正常 mysql -uwebase -p -h127.0.0.1 -P3306 -e select 1 # 2. 重新启动node-mgr服务 ./start.sh # 3. 盯日志看是否出现启动成功的标志 tail -f logs/WeBASE-Node-Manager.log日志里如果出现Started WeBASE-Node-Manager或等价字样并且不再抛数据源异常就说明这个报错已经彻底解决了。6. 同链路里我顺手踩掉的其它几个MySQL坑6.1 时区报错跟SSL握手长得比user/password error更迷惑启动时如果日志里有The server time zone value或Public Key Retrieval is not allowed这类异常前者是时区没设置后者是MySQL 8驱动连SSL相关参数缺了。虽然它们不会直接报user/password error但很多人在部署时会把这几个错合并在一起处理。我的JDBC URL模板是这样照抄基本能避开一大片坑jdbc:mysql://127.0.0.1:3306/webasenodemanager?serverTimezoneAsia/ShanghaiuseUnicodetruecharacterEncodingUTF-8useSSLfalseallowPublicKeyRetrievaltrue这里重点说一下allowPublicKeyRetrievaltrueMySQL 8的caching_sha2_password在非SSL连接下需要它来允许客户端获取公钥不加这个参数老驱动连上去会卡在认证阶段表现又像是一个认证错误。6.2 数据库和表没初始化经常被误判成密码问题WEBASE部署时需要一个初始化好的库。数据库名一般是webasenodemanager表结构由webase.sql或类似脚本导入。如果脚本没执行或者执行的库名对不上启动时可能会报Unknown database但某些版本融合了多条异常信息之后表面上看起来也像是连接失败。这个检查只要一条命令SHOW DATABASES LIKE webasenodemanager; USE webasenodemanager; SHOW TABLES;看到一堆表才算完只看到个空库也没用。6.3 连接数打满部署阶段的隐形杀手WEBASE各子服务会开数据库连接池。如果同一个MySQL实例上同时跑着多个环境或者连接池参数配得太大遇到Too many connections时表现也可能是连接失败。部署阶段建议先把连接池参数调保守一点比如maximum-pool-size先给10跑通了再根据实际负载调大。别一上来就给50、100开发机扛不住。另外WEBASE部署脚本里用的MySQL账号最好是独占的别跟其他业务系统共用一个账号。因为连接池回收不及时的时候一个账号能把所有连接占满其他系统跟着一起遭殃。6.4 小经验部署前把这几件事一次性做对最后分享一个经验。WEBASE这套东西部署排错90%的问题都集中在MySQL环节。与其一遍遍地重启试错不如部署前花五分钟把这几件事一次性捋清楚MySQL版本是多少。如果是8.0以上提前想好认证插件方案数据库账号的Host授权。按“来源IP 业务账号”的最小化原则来但别用localhost然后连127.0.0.1密码统一。部署脚本一份、node-mgr一份、MySQL一份三处完全一致密码别用特殊字符JDBC URL参数。时区、SSL、公钥获取这几个参数预先写对防火墙和端口。3306该放通的放通该确认监听地址的确认一下。把这些在部署前一次性做到位后面会非常省心。我把这套检查项做成了一个清单每次部署新环境都照着过一遍再也没在这个报错上浪费过时间。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进