0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

阅读开源项目源码的实用技巧(下)

jf_78858299 来源:labuladong 作者:labuladong 2023-04-12 11:37 次阅读

技巧二、多猜,多搜索,可以在底层库(标准库、网络框架等)打条件断点过筛选出关键流程

这句话其实是高效 debug 的关键。初看源码时「猜」是很重要且很有效的手段,结合 IDE 的搜索功能,能够帮我们快速定位关键代码。

为什么底层库适合打断点呢?因为出看大项目的代码很难搞清楚其中的细节,加上各种异步、多线程的操作,很容易把代码「跟丢」。如果把断点打在底层库的接口/方法上,就可以根据调用栈分析调用过程。

当然,底层库被调用的次数比较多,可能出现很多无关的调用,所以要结合条件断点来过滤掉无关的调用。

还是用 Pulsar 举例,我现在想探究 producer 发送消息的流程,那么 producer 和 broker 之间的网络通信过程就是一个重要的切入点。

首先发现 Pulsar 的网络协议使用的是 protobuf,而且注意到PulsarApi.proto这个文件中有一个BaseCommand定义:

message BaseCommand {
    enum Type {
        CONNECT     = 2;
        SUBSCRIBE   = 4;

        PRODUCER    = 5;

        SEND        = 6;
        SEND_RECEIPT= 7;

        MESSAGE     = 9;
        ACK         = 10;

        PING = 18;
        PONG = 19;
        ...
    }
    
    required Type type = 1;

    
    optional CommandConnect connect          = 2;
    optional CommandConnected connected      = 3;
    ...
}

又发现 Pulsar 底层靠 netty 框架实现网络通信,那么我们可以大胆猜测, 源码里肯定有一个大 switch 语句 ,来根据 command 里面的 type 分类处理对应的 command。

所以我们可以全局搜索一下case SEND_RECEIPT ,就找到了PulsarDecoder这个文件:

图片

这里会根据不同的 command type 调用不同的 handle 函数,所以可以认为这里是 Pulsar 关键功能的入口。

而且注意这是 common 包,也就是说 client 和 broker 都会依赖这个包, 所以断点打在 switch 这里就可以看到 client 和 broker 的网络交互 ,每次跳转的 case 就是网络命令的交互顺序:

图片

PS:因为 ping/pong 心跳消息在调试时很烦人,所以我们可以通过条件断点跳过心跳消息。另外,我们需要把 client 里面的各种 timeout 都调大一些,避免调试时出现超时的错误。

这样,启动我们的测试用例,仅仅通过这一个断点,就能搞明白 Pulsar 发消息的流程了:

当然,如果你想探究每一步具体做了什么,就跳进具体的 handle 函数里一步步调试即可。

技巧三、利用各种可视化工具

你比如,上面说的网络通信过程,我们知道了 produce 一条消息的流程,但每条 protobuf 数据包里面到底存了什么信息呢?

关于这个问题,社区有大佬写了一个 lua 脚本, 可以用 wireshark 解析 Pulsar 协议格式 ,具体说明在这里:

https://github.com/apache/pulsar/tree/master/wireshark

按照说明配置并启动 wireshark 之后,可以使用如下过滤命令过滤掉无关的数据包:

tcp.port eq 6650 and pulsar and protobuf.field.name ne "ping" and protobuf.field.name ne "pong"

接下来启动 standalone,通过 Java client 发送一条消息,就可以在 wireshark 抓到 10 个数据包,和刚才通过 debug 得到的流程是一样的:

同时,我们还可以查看每个包的具体数据,比如PARTITITONED_METADATA命令就是在查询 topic 对应的 partition 有多少,因为这里是个非分区的 topic,所以PARTITITONED_METADATA_RESPONSE返回了 0:

再比如LOOKUP命令用来查询 broker 的 URL,因为我们启动的 standalone 只有一个 broker,所以LOOKUP_RESPONSE返回的只有一个 URL:

在真实的使用场景中肯定有多个 broker,所以这个LOOKUP_RESPONSE应该会返回多个 broker URL。

最后看一下真正发送消息的SEND命令里面具体有什么数据:

图片

可以看到这里面有 producer_name, sequence_id 等数据,每条消息的 sequence_id 单调递增,用来防止由于网络重传导致的消息重复,和 tcp 里面的 seq 差不多的原理。

另外可以看到真正的消息数据放在数据包的最后,通过一个字段记录数据的长度。

具体的玩法可以有很多,我这里就不一一列举了,其实除了 wireshark 分析 Pulsar 的网络通信, 还可以使用 zookeeper 的可视化工具查看 Pulsar 的元数据

比如 prettyZoo 就是一款对 zookeeper 可视化的开源工具,那么我就可以在 Pulsar standalone 启动之后(会自动启动 zookeeper),让 prettyZoo 连接到 zookeeper 的端口,很直观地查看 zookeeper 里面的节点数据:

图片

这里面很多数据可能不好理解,但我们手上有源码, 这些路径大概率是以字符串常量的形式表现的,那全局搜索就行了

比如这个producer-name的路径,我们搜一下就定位出来了:

图片

简单浏览一下源码,原来是借助 zookeeper 生成全局唯一的生产者名字。

最后

本文也够长了,主要介绍了一些阅读开源项目源码的实用技巧,总结来说就是: 善于找资源,善于用工具

虽然本文是以 Pulsar 为例,但这些技巧都是通用的,可以运用到任何比较成熟的开源项目上去。

如果你也有什么经验分享,可以留言告诉我,掌握技巧只是漫漫长路的第一步,让我们共同在开源社区里成长进步。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • IDE
    IDE
    +关注

    关注

    0

    文章

    334

    浏览量

    46675
  • 开源
    +关注

    关注

    3

    文章

    3245

    浏览量

    42396
  • DEBUG
    +关注

    关注

    3

    文章

    89

    浏览量

    19883
收藏 人收藏

    评论

    相关推荐

    Matepad pro12.2 已上市半个月,但是还没有在开源网站看到该项目开源信息,违背开源精神

    Matepad pro12.2 已上市半个月,本人自己也购买了同款12+256的pad,想要同步学习这款pad的一些体验还不错的功能点,但是目前为止还没有在开源网站看到该项目开源
    发表于 08-27 17:25

    关于Linux的源代码阅读问题

    ,linux开源,应该所有库函数都可以进去的了。2.在Linux项目,没有像MDK那样做一个项目,然后规范文件分类吗?否则,项目一大,文
    发表于 11-21 11:04

    机友分享 | 导入机智云Android开源项目的正确姿势

    以下文章来源于小雨编程 ,作者小雨tt“使用机智云AIoT平台支持项目自生成APP源码,即可轻松解决Android开源项目啦,”开发者下载源码
    发表于 09-28 10:58

    【HiSpark系列】润和 HiHope 社区 开源项目集合

    Demo App的源码https://gitee.com/hihopeorg/GOpenSource_AppKit目前相关的开源代码都放在了这里,感兴趣的可以看一
    发表于 10-22 09:52

    C语言开源项目

    值得学习的C语言开源项目- 1. WebbenchWebbench是一个在linux使用的非常简单的网站压测工具。它使用fork()模拟多个客户端同时访问我们设定的URL,测试网站在压力下工
    发表于 08-20 06:15

    下载编译源码的要点和搭建源码阅读环境的方法

    下载编译源码的要点和搭建源码阅读环境的方法。下载编译源码,一方面是为了搭建源码阅读环境,另一方面
    发表于 01-10 06:49

    STM32项目开发中超级实用技巧分享

    STM32项目开发中超级实用技巧一. 利用软启动打补丁二. 优化等级尽量选择不优化三. 合理利用开关总中断所有的热爱都要不遗余力,真正喜欢它便给它更高的优先级,和更多的时间吧!关于STM32其它
    发表于 01-21 06:22

    分享一个超级实用的源码阅读小技巧

    工欲善其事必先利其器; 我发现函数调用图可以让我们更加直观地了解到源码函数直接的调用和层次关系,提高阅读源码的效率 。 1 前言 看源码的时候,心血来潮想弄一
    的头像 发表于 05-29 11:50 2017次阅读
    分享一个超级实用的<b class='flag-5'>源码</b><b class='flag-5'>阅读</b>小技巧

    优秀的 Verilog/FPGA开源项目介绍(一)

    的参考价值。 这里再介绍一开源协议的区别,方便大家在阅读使用这些开源项目时尊重规则。 详情查看:https://suisuisi.blog
    的头像 发表于 10-11 15:31 9186次阅读
    优秀的 Verilog/FPGA<b class='flag-5'>开源</b><b class='flag-5'>项目</b>介绍(一)

    模拟阅读开源分享

    电子发烧友网站提供《模拟阅读开源分享.zip》资料免费下载
    发表于 11-14 11:21 0次下载
    模拟<b class='flag-5'>阅读</b>器<b class='flag-5'>开源</b>分享

    矩阵显示器上的新闻阅读开源项目

    电子发烧友网站提供《矩阵显示器上的新闻阅读开源项目.zip》资料免费下载
    发表于 02-08 10:46 0次下载
    矩阵显示器上的新闻<b class='flag-5'>阅读</b>器<b class='flag-5'>开源</b><b class='flag-5'>项目</b>

    阅读开源项目源码实用技巧(上)

    本文分享一在使用或者学习开源项目源码的过程中的一些经验技巧。 因为我最近在研究 Apache Pulsar 这款消息队列,所以就以这个项目
    的头像 发表于 04-12 11:34 1102次阅读
    <b class='flag-5'>阅读</b><b class='flag-5'>开源</b><b class='flag-5'>项目</b><b class='flag-5'>源码</b>的<b class='flag-5'>实用技巧</b>(上)

    Java算法大全源码开源源码

    Java算法大全源码开源源码
    发表于 06-07 14:58 1次下载

    如何去阅读源码,我总结了18条心法

    在一个优秀的开源项目中,设计模式处处存在,所以在你开始阅读源码之前最好先了解一常见的一些设计模式。当你了解了一些设计模式以后,在
    的头像 发表于 07-17 16:00 768次阅读
    如何去<b class='flag-5'>阅读</b><b class='flag-5'>源码</b>,我总结了18条心法

    浙大博导开源飞控planner源码

    浙大博导开源飞控planner源码
    发表于 06-12 11:43 4次下载