1.Dubbo 常见错误及解决方法
地址找不到:No provider available
找不到服务,这时候可能有这么几种情况:
Provider 服务没启动,或者注册中心Nacos宕机了。
Dubbo 的服务配置有误差,必须保证服务名,组别(默认是 Dubbo ),version 三者都正确。
排查:
访问注册中心的 Ops 系统,查询对应的服务是否有提供者列表;同时检查调用者应用所在服务器的日志(一般每种注册服务的客户端都会有对应的日志记录),查看是否有地址信息的推送/拉取记录。
如无,则表明发布者发布服务失败,检查发布者的应用启动是否成功。
如有服务,则检查调用者应用所连接的注册中心,确认跟预期的环境要匹配。
调用超时:client-side timeout
一般超时是调用端发生在请求发出后,无法在指定的时间内获得对应的响应。原因大概有以下几种情况:
服务端确实处理比较慢,无法在指定的时间返回结果,调用端就自动返回一个超时的异常响应来结束此次调用。
服务端如果响应的比较快,但当客户端 负载很高,负载压力很大的时候,会因为客户端请求发不出去、响应卡在 TCP Buffer 等问题,造成超时。因为客户端接收到服务端发来的数据或者请求服务端的数据,都会在系统层面排队,如果系统负载比较高,在内核态的时间占比就会加长,从而造成客户端获取到值时已经超时。
排查
在调用超时的方法代码逻辑里加入时间逻辑:
long start = System.currentTimeMillis();
//逻辑代码
long end = System.currentTimeMillis();
log.info("文件上传调用时间是{}",end-start);
这样就可以查看当前超时方法的调用时间了,分析Dubbo调用超时的原因,根据业务的实际调用时间在代码中设置timeout时间。当然也有可能是网络状况的原因导致超时。
序列化失败:HessianRuntimeException
排查:
检查方法的入参是否实现 Serializable 接口。
检查服务方法的传入传出参数是否继承了 Number、Date、ArrayList、HashMap 等 Hessian 特殊化处理的类。
2.Java断言
语法1:assert expression;
//expression代表一个布尔类型的表达式,如果为真,就继续正常运行,如果为假,程序退出
语法2:assert expression1 : expression2;
//expression1是一个布尔表达式,expression2是一个基本类型或者Object类型,如果expression1为真,则程序忽略expression2继续运行;如果expression1为假,则运行expression2,然后退出程序。
assertEquals(true, StringUtils.isEmpty(user.getName));
第一个参数是true,就是断言的期望值,看逗号后边的另一个参数的结果,如果结果为true,就是期望值,返回期望值。
assertNotNull(name);
判断参数是否不为空,如果name为空,在这行跳出执行。
如果name不为空,则继续执行代码。
断言可以配合枚举类使用。
断言可以检查运行结果。
断言失败时会抛出 AssertionError,导致程序结束退出。因此,断言不能用于可恢复的程序错误。
虽然断言返回的是 boolean 值,但是并不能将其作为条件判断语句。