在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比较好。

感悟

报警群的问题关注应有始有终

始:在群中发现问题

过程:从问题中发现了什么?初步定位大概能看出什么问题?

终:反馈给相应的人,没有反馈就没有了价值

posted @ 2021-11-10 11:18  夜旦  阅读(73)  评论(0编辑  收藏  举报