在rpc链路中的工作总结
Dubbo如何根据接口名称查询测试对应的远程接口
dubbo项目一般都有控制台,通过控制台可以测试对应的接口是否调用正常,可以请教同事。
注意填写参数类型时要填写DTO之类的时候把全限定名写上,参数值为json。
垃圾代码是什么样子的
public class Test {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
Map<Object, Object> res = doRpcInvoke2();
for (Integer integer : list) {
//Integer result = doRpcInvoke(integer);//假设rpc调用耗时50ms
}
}
private static Integer doRpcInvoke(Integer integer) {
return 1;
}
}
这里我在for中做了rpc调用,乍一看50ms的时间还能忍受,但是这是for循环,假设循环10次每次50就是500ms,而这个接口是首页调用。。还要算上其他接口的调用,这样就会导致首页加载的很慢,体验极差。那,怎么优化呢?
答案就是做本地缓存
public class Test {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> collect = list.stream().map(value -> value).collect(Collectors.toList());
Map<Object, Object> res = doRpcInvoke2(collect);
for (Integer integer : list) {
// error
// Integer result = doRpcInvoke(integer);//假设rpc调用耗时50ms
// do sth...
// correct
if (res.get(integer) != null) {
// do sth...
}
}
}
private static Integer doRpcInvoke(Integer integer) {
return 1;
}
private static Map<Object, Object> doRpcInvoke2(List<Integer> integers) {
return Collections.emptyMap();
}
}
大哥指点我的这个问题真是让我印象深刻,害。
此处应该顺带整理下一个问题:
为什么批量查询要比单个查询快?
估计是顺序io和随机io的区别,挖坑。
------------割-------------
rpc调用参数的验证
rpc调用完成后一定要对调用结果判空,如果是空的,加个info日志,返回到上层调用。
外部参数使用前不能嫌麻烦不做判断,出了bug排查更麻烦,一定要做判断。
1.模块间传递参数用包一下的方式透传
可以用BeanUtils.copyProperties,拷贝相同的属性值,
那承载属性的实体怎么办?
实体可以在当前模块再建一个dto专门用来透传属性,
引入依赖的方式不推荐,因为多模块的原因之一就是解耦
2.跨模块间的参数传递
最好(强制)用dto封装,这样后期如果需要加参数,直接在dto里加就可以
3.不能用join,但又必须关联查询的情况下
把数据分多次用Future select(相当于多线程去分别查,这样把本来的串行耗时变为并行耗时,且最终耗时由耗时最长的查询决定),查完的结果用map存储,通过get的方式组装结果,降低耗时
两表join可以用加索引的方式
4.新添加需暴露给外部调用的rpc接口
需手动在consumer.xml中配置以供外部调用
5.如何确定某个暴露的接口功能是可用的?
找到暴露的接口名称,去dubbo控制台,用名称搜索对应服务,找到接口里对应的方法, 传入对应的参数,测试接口
6.传递的参数没有意外情况不要反复序列化
定好前端需要的参数,后端拿到参数干脆别动,先传递到顶层调用再给前端转参数
7.模块接口测试
写完一个模块的接口后可以部署到测试环境,在dubbo控制台测试一下这个接口返回的数据是否符合需求
8.暴露的接口即服务
从暴露的接口了解业务是最快捷的办法
9.如何看一个没了解过的业务?
从顶层接口开始,一层层的向下只看暴露的接口,先把整个逻辑串起来,并且搞明白每个接口大概做了什么,然后再细看模块内逻辑,能画出流程图最好,这样整个链路就清晰了
关于查询语句
where条件里面,不加索引时,update会使用“表锁”进行更新,影响所有行的查询更新;
加了索引后,使用“行锁”进行udpate,只锁当前行。不影响其他行的查询更新。
关于索引能写的太多了,得补,大补。
另:数据库日期使用时间戳时可以加索引,datetime也可以加,但是效率应该比时间戳低,另外时间戳不考虑时区
一点代码技巧
Detail p1 = request.getDetail();
Detail p2 = productHandler.getDetail(id, schemeDTO, activityInfo);
LOGGER.info("对比活动信息, Detail, p1={}, p2={}", p1, p2);
// 直接转成 json 比
if (!Objects.equals(JsonHelper.toJson(p1), JsonHelper.toJson(p2))) {
LOGGER.info("对比活动信息, 对比失败");
throw new BizException(BizEEnum.ACTIVITY_CHANGED);
}
LOGGER.info("对比活动信息, 对比成功");
感觉会对性能有影响,不懒的话还是重写equals比较好。
感悟
报警群的问题关注应有始有终
始:在群中发现问题
过程:从问题中发现了什么?初步定位大概能看出什么问题?
终:反馈给相应的人,没有反馈就没有了价值
。