这里发现的问题还挺多的,也遇到了好几个之前没见过的报错,不过主要还是记录Dubbo超时和1生成二维码无地址字符串返回的问题。
一、BindingException
含义:绑定异常。Mapper 接口和 XML SQL 映射不上
很好想到解决办法:
- 去检查自己的SQL有没有问题
- 看id、namespace、返回类型 / 参数类型对不对
- 如果是多参数加没加 @Param
- mapper和映射文件名字一不一样。
我这里就是mapper和映射文件名字不一样,导致没有匹配上,大意了。

二、日志 error code: 3-4
文末附Dubbo 错误码含义以及常见原因。
error code: 3-4 是服务端报错了,也就是代码有 bug。

可以看到是 ZfbPayServiceImpl.pcPay() 方法内部报错了。去看 pcPay 的代码,找到最可能出错的行:

注意到,如果 cartGoods 为 null 或空 → NPE( NullPointerException,空指针异常**)**
出现 NPE,优先查:
- 看哪个对象是 null,定位调用链哪一步返回 null;
- 看 Mapper 的 SQL、数据库查询、MyBatis 映射是否有问题;
- 看实体类属性是否初始化,有没有漏赋值;
- 检查包装类型拆箱;
- 区分是 null,还是空集合(空集合不会 NPE,但
get(0)会报索引越界)。
对应到图上的代码场景:orders.getCartGoods(),优先查:
① orders 对象是否为 null;② cartGoods 这个字段数据库有没有存;③ SQL语句有无问题(字段冲突可导致MyBatis 映射失败,把字段映射成 null);④实体类有没有初始化这个 List。

追踪一下发现:
orders 对象本身不为 null,说明 SQL 查到订单主表数据了,接着就去关心一下关联查询的 cartGoods 集合。cartGoods 也不为空,看一下关联查询语句有没有问题,没错,这时候就发现问题了。


OrdersMapper.xml中,findById 用了 SELECT * + LEFT JOIN ,两个表都有 id 列 →
列名冲突,导致 MyBatis 映射错乱,cartGoods 集合可能为空。
所以推断是列名冲突导致 NPE,NPE 被 catch 住后转成了 BusException
解决方案:
- 给列名起别名来避免冲突
- 或直接给子表的id映射删掉
三、Dubbo超时,error code: 3-7
这里可以看见支付宝返回成功了,SQL 查询已经成功返回数据了,我们之前的修改正确。

error code:3-7 → 执行太慢,支付宝调用耗时逼近Dubbo超时限制

Dubbo超时:
看是业务执行慢、第三方接口响应慢、Dubbo 线程 / 超时配置问题,还是网络问题。
- 业务代码慢:MySQL 慢查询、锁、N+1;Redis 阻塞。
- 调用第三方慢:支付宝 / ES / 短信,参数错也会拖慢响应。
- Dubbo 配置:超时时间太短;线程池打满排队;消费者 / 提供者超时不一致。
- 网络:服务器之间延迟、防火墙。
- 数据映射问题:MyBatis 映射异常,导致业务代码拿到 null,执行异常耗时间。
我们一个一个检查其实是挺费劲的,这个时候聪明高效的做法就是:编写测试类看测试报错。
如果自定义了异常,那么测试报错就会显示自定义异常,我们需要在代码中加入打印报错的语句。

测试报错如下:

这是说 AlipayClient 在验证支付宝返回数据的签名时失败了。
我当时就想到,应该是我配置的密钥有问题。因为之前操作的时候密钥就有些没弄明白。

于是我去找AI分析,发现确实是密钥的问题。(支付宝的知识我还没学啊,所以这里出了回头看感觉很弱智的问题,不过我觉得直接上手去学习这样学得更快而且更深刻,所以错误还是要记录的)
中间的内容就不细说了,就说遇到的主要报错信息过程吧,要不这个文章有点又臭又长的感觉了。
我先是修改了密钥,知道了RSA2签名的公钥要用支付宝公钥。然后修改,发现虽然测试通过了,代码测试生成二维码返回200,但是!但是data应该给我返回一串地址字符串的,而它返回null。

救命......
Qoder CN 答道 :"签名通过后返回 null,说明支付宝接口调用成功了但 qrCode 字段为空。很可能是响应有业务错误但没被检查到。建议在 pcPay 方法里加一行打印,看看支付宝实际返回了什么"
好的。
加的内容在上上上一张图中,第一个红框里。
System.out.println("支付宝响应: " + response.getBody());
文末附常见返回内容及原因。
我这里添加后测试返回" isv.invalid-app-id " --- AppID 无效。
后来查了一番发现我用的是生产环境不是沙箱环境!
需要重新获取,拿appId和私钥和支付宝公钥。
重新弄完之后就好了,能返回地址了。
四、文末礼
1. response.getBody() 常见返回内容及原因
|-------------------------------------------------|--------------------|
| 返回内容 | 原因 |
| "sub_code":"isv.invalid-app-id" | AppID 无效或应用未上线 |
| "sub_code":"isv.app-not-online" | 应用状态是「开发中」,未提交审核上线 |
| "sub_code":"isv.insufficient-isv-permissions" | 缺少接口权限 |
| "sub_code":"isv.app-call-limited" | 沙箱环境限制 |
2. Dubbo 错误码
格式为 X-Y,X 是大类,Y 是具体编号。常用的如下:
|----------|-------------|--------------------------|
| 错误码 | 含义 | 常见原因 |
| 3-0 | 网络异常 | 连接断开、DNS 解析失败 |
| 3-1 | 线程池耗尽 | 服务端并发请求太多 |
| 3-2 | 超时(客户端) | 客户端等待响应超时 |
| 3-3 | 序列化失败 | 对象没实现 Serializable、类型不匹配 |
| 3-4 | 业务异常 | 服务端方法内部抛异常(NPE 等) |
| 3-5 | 服务未找到 | 接口没注册到注册中心 |
| 3-6 | 路由失败 | 找不到可用的服务实例 |
| 3-7 | 服务端超时警告 | 执行时间接近/超过 timeout |
| 3-8 | 限流/降级 | 触发了限流规则,请求被拒绝 |
| 3-9 | 参数校验失败 | 方法参数不合法 |
| 3-10 | 优雅停机 | 服务正在关闭,拒绝新请求 |
1 系列 --- 注册中心错误
|----------|----------------------|
| 错误码 | 含义 |
| 1-37 | 注册中心返回空地址列表(你日志里出现过) |
99 系列 --- 通用/未知错误
|----------|----------|
| 错误码 | 含义 |
| 99-0 | 未知远程通信错误 |