Node.js连接MySQL时服务崩溃 报JSON解析错误 线上Ubuntu20.04运行异常
登录接口线上崩溃问题排查与解决
报错本质说明
控制台抛出的SyntaxError: *Unexpected token u in JSON at position 0*,核心是代码尝试将值为undefined的变量传入JSON.parse执行解析——因为undefined被隐式转成字符串后开头就是字母u,和报错堆栈指向的app.js:57位置的JSON.parse调用完全对应。
这套逻辑本地能跑、线上就崩,不是单一MySQL配置错,是几个本地调试根本碰不到的异常场景,到了线上就集中触发了。
常见触发原因
- 完全没处理数据库回调的错误分支:当前代码在
con.connect、con.query的回调里,压根没判断第一个传入的err参数。只要线上出现MySQL连接失败、权限不足、表结构不匹配等问题,query回调里的第二个返回值result就会是undefined。代码直接跳过错误判断,拿undefined做JSON.stringify再JSON.parse,必然触发解析崩溃。本地开发时因为所有配置和库结构都是适配好的,查询永远成功,所以根本碰不到这个分支。 - 同个连接对象重复发起connect:单个登录接口逻辑里,对同一个刚创建的连接对象,先后写了3次
con.connect()调用。本地低并发、单请求调试时,连接初始化的时序刚好能对上请求发送的时机,能正常拿到结果;线上并发上来后,连接状态还没初始化完成,后续的query就会直接失败,返回undefined触发报错。 - 本地和线上MySQL环境规则有差异:Ubuntu下的MySQL默认是区分表名大小写的,而本地Windows/Mac的MySQL默认不区分,只要本地建表用了大写字母,线上访问时表名匹配不上,查询直接报错;另外线上MySQL的账号权限、库表结构、字符集如果和本地不一致,也会直接触发查询失败,返回空值。
- 冗余的无效JSON转换:代码里把URL查询参数、MySQL查询结果都做了先
stringify再parse的操作,完全没必要——MySQL驱动返回的结果本身就是可直接操作的JS数组/对象,多套一层转换,一旦值出现异常,就会直接触发JSON解析错误。
对应解决方法
1. 补上全链路错误处理
所有数据库连接、查询的回调,第一步先判断错误状态,有错误时直接返回响应、打印日志,绝对不要跳过错误判断直接拿返回值做后续逻辑,核心修正片段参考:
con.connect(function(err) { if (err) { console.error('数据库连接失败:', err); return res.end(JSON.stringify({ Login: -1, msg: '数据库连接异常' })); } con.query(req_search_user, [queryParsed.username, queryParsed.password], function (err, result) { if (err) { console.error('用户查询失败:', err); return res.end(JSON.stringify({ Login: -1, msg: '查询异常' })); } // 兜底确认返回值是合法数组 const resultParsed = Array.isArray(result) ? result : []; // 后续原有登录判断逻辑... }) })
2. 修正连接初始化逻辑
- 去掉单个请求里重复发起的3次
con.connect()调用,同一连接对象只需要调用一次connect即可 - 不要在每个接口请求里都执行
mysql.createConnection,改为应用启动时全局初始化一次连接(或使用连接池),避免每个请求都新建连接带来的资源浪费和状态错乱
3. 对齐线上线下MySQL环境
- 登录线上MySQL,执行
show variables like 'lower_case_table_names';检查表名大小写规则,如果值为0,确认线上users表的名称大小写和代码里写的完全一致 - 核对当前使用的root账号,是否对
project库有SELECT、UPDATE的操作权限 - 检查线上
users表的字段,确认id、ip、date_time_activate字段都存在,结构和本地完全一致
4. 移除冗余的无效转换
去掉JSON.stringify(url.parse(req.url,true).query)再JSON.parse的重复转换,直接用url.parse(req.url,true).query拿到解析后的参数对象即可;同样去掉MySQL查询结果的JSON套娃转换,直接使用驱动返回的原生数组做判断,减少不必要的异常触发点。
内容的提问来源于stack exchange,提问作者Techno Cheap
相关产品推荐
相关产品推荐

