如何学习开源项目(转载)

做者资料:章宇于2002年及2007年分别于清华大学电子工程系得到学士及博士学位,其后一直从事计算机系统领域的研究与开发工做,目前供职于华为技术有限公司云操做系统部门,从事OpenStack相关工做。出于工做缘由和我的兴趣,做者陆续关注了一些开源项目,主要包括:KVM/QEMU,libvirt,virt-mamager,OpenStack,Open vSwitch,Ceph,Zabbix等。编程

开源项目学习方法

学习各类开源项目,已经成为不少朋友不可回避的工做内容了。笔者本人也是如此。在接触并学习了若干个开源项目以后,笔者试图对本身工做过程当中的若干体会加以总结,以期对一些但愿借鉴的朋友有所裨益。
须要说明的是,笔者本人接触的开源项目大多属于计算机系统领域,例如Linux kernel,KVM,QEMU,OpenStack等。所以,此处介绍的经验一定也有些局限。请读者们自行分辨,区别对待。后端

1. 学习分层和目标管理

对于一个开源项目,能够将与之相关的各类知识和技能的学习大体划分为以下五个层次:数据结构

第一层次:了解项目的基本概念、基本用途、逻辑结构、基本原理、产生背景、应用场景等基本知识。

这个层次的基本定位其实就是“科普”。若是对于一个项目只须要有些基本了解,且短时间内并不须要上手进行实际技术工做,则学习到这个层次也就能够先应付一下了。架构

第二层次:掌握项目的基本安装流程和使用方法。

这个层次的基本定位是“入门”,以便对这个项目得到直观认识,对其安装和使用得到亲身体验。若是只是须要以as-is方式使用这个项目,则初步学习到这个层次便可。框架

第三层次:了解代码的组织,找到各个主要逻辑/功能模块与代码文件之间的对应关系,经过代码分析走通几个关键的、有表明性的执行流程。

这个层次的基本定位是“深刻”,开始理解这个项目的实际实现,可以真正将项目的功能、工做原理和代码实现对应起来,得到对这个项目工做过程的直观认识。这个层次是学习开源项目代码的真正开始。若是但愿基于这一项目进行应用开发,或者针对与这一项目密切相关的其余项目进行工做时,则对项目自己的代码进行这一层次的理解,会颇有帮助。编程语言

第四层次:了解该项目全部代码模块、程序文件的做用,走通全部主要执行流程。

这个层次的基本定位是“掌握”,可以比较全面、系统地理解这个项目的设计和实现,而且熟悉项目各个部分的代码。若是但愿对项目进行深度定制修改,或者对社区有所贡献,则应当以达到这个层次做为目标。函数

第五层次:钻研、领悟该项目的各类设计思想与代码实现细节。

这个层次的基本定位是“精通”,精益求精,学无止境。这是大神们追求的境界。若是但愿成为项目社区的重要贡献者乃至核心贡献者,则应当以这个层次做为努力的目标。工具

综上,对于一个开源项目的学习过程能够大体分为五个层次。至于到底要学习到什么阶段,投入多少相关精力,则彻底取决于学习的目的。学习

2. 知识基础

学习一个开源项目须要的知识基础主要包括:google

1)该项目涉及的技术领域的背景知识

举例而言,分析Linux Kenrel,则应该了解操做系统原理;学习OpenStack,则应该知道什么是云计算。若是没有这些背景知识做为基础,上来就死磕源代码,只能是事倍功半。

2) 该项目开发使用的语言及其各类开发调试工具

这个就无需多言了。

3) 英语

很遗憾,目前为止真正流行的开源项目大部分不是起源于国内。所以,除了学习个别极其流行、文档完备的项目以外,你们仍是须要自行搜集阅读英文资料参考。学好英语很重要。

固然,到底须要准备多少知识基础,彻底取决于学习的目的和层次。若是只是想科普一下,也就没必要太过麻烦了。

3. 学习思路

学习一个项目的过程,其实就是由表及里了解分析它的过程。上述说起的五个学习层次便组成了这样一个逐渐深刻的过程。在此基础之上,学习、分析代码的过程,也能够尝试作到由表及里、逐渐深刻。

在刚开始接触一个项目的时候,咱们看到的其实就是一个黑盒子。根据文档,咱们必定会发现盒子上具备若干对外接口。一般而言,这些接口能够被分为三类:

配置接口: 用于对盒子的工做模式、基本参数、扩展插件等等重要特性进行配置。这些配置每每是在盒子启动前一次性配好。在盒子的工做过程当中,这些配置或者不变,或者只在少数的状况下发生改变。

控制接口: 用于在盒子的工做过程当中,对于一些重要的行为进行操纵。这是盒子的管理员对盒子进行控制命令注入和状态信息读取的通路。

数据接口: 用于盒子在工做过程当中读取外部数据,并在内部处理完成后向外输出数据。这是盒子的用户真正关心的数据通路。

所以,在分析一个开源项目的代码时,能够围绕重要的配置、控制、数据接口展开分析工做,特别应该注意理解一个关键的接口背后隐藏的操做流程。例如,针对数据接口,至少应当走通一条完整的数据输入输出流程,也即在代码中找到数据从输入接口进入盒子后,通过各类处理、转发步骤,最终从输出接口被传输出去的整个执行过程。一旦走通了这样一条流程,则能够将与数据处理相关的各个主要模块、主要步骤贯穿起来,并将逻辑模块图上和文档中的抽象概念对应到代码实现之中,能够有效推动对于项目的深刻理解。

在实践这一思路的过程当中,笔者建议能够优先从控制接口和数据接口中各自选择一二重要者进行背后的执行流程详细分析,力争找到其中每一步的函数调用及数据传递关系(对于一些系统、应用库提供的底层函数能够先行跳过以节省时间)。这一工做完成以后,则第1节中第三层次的学习目标便可初步达成。

配置接口在不一样的项目中的重要程度不一样。对于一些架构极为灵活、配置空间甚大的项目(如OpenStack的Ceilometer),则能够适当多花些时间加以研究,不然简单了解便可。

对于这个学习思路,下文中还将结合实例进行进一步的说明。

4. 若干小建议

如下是笔者的一些零散建议,供你们参考。

1)作好记录

在刚刚入手开始学习某个项目的源代码时,其实颇有点破译密码的感受。大量的数据结构和函数方法散落在代码的各个角落里,等待着学习者将它们贯穿到一个个重要的执行流程中。所以,在分析学习的过程当中,不管有什么零散收获,都值得认真记录下来。珍珠天然会串成项链的。

2)不要过度纠缠于细节

立志搞懂一个项目的每行源代码是值得尊敬的,但至少在刚刚入手的时候是没有必要的。若是过于纠缠于代码的实现细节,则可能很快就被搞得头晕眼花不胜其烦了(看英文资料的时候,每遇到一个不认识的词都要马上查词典么?)。不妨避免细节上的过分纠缠,仍是先尽快走通关键的执行流程,将项目的骨干框架搭起来,而后再以此为参照,就能够清晰判断什么代码值得深刻分析,什么地方能够简单略过了。

3)想像和联想很重要

如前所述,从零开始搞懂一个项目的代码,就像破译密码。所以,不妨展开合理的想象和联想,将各个零散的发现和理解联系起来,并加以分析印证。在这个过程当中,对项目所在领域的背景知识、对项目自己的逻辑框架和工做原理等方面的理解,都是想像和联想的参照与指导。此外,一些关键的函数名、变量名等等都是联想的hint。本质上,编程语言也是语言,而程序代码就是说明文。在分析代码时,必定要超越语言和代码的细节去理解被说明的事物自己。

4)该搜就搜

分析代码的时候,很容易出现的状况就是,一个执行流程走到半截找不到下一步了。。。在这种状况下,固然首先仍是推荐采用各类调试工具的单步执行功能加以跟踪。若是暂时不会,或者种种缘由只能进行静态代码分析,那么该搜就搜吧。各类IDE工具的文本搜索都能用,哪怕是grep也行。至于到底以什么为搜索关键词,就须要琢磨琢磨了。

5)外事不决问google,内事不决问百度

如题,不解释。

5. 一个例子:OpenStack Cinder分析

此处将以OpenStack Cinder为例,并结合KVM/Qemu和Ceph,说明如何参考上述思路对一个开源项目进行分析。

可能有朋友奇怪为何选这么个东东作例子。这个吧。。。写文章时忽发起想,举例子是随手抓来。木有缘由。。。

首先,想对Cinder进行分析,必定要了解若干相关的基础知识。什么是云计算?什么是块存储?什么是OpenStack?Cinder在OpenStack里的做用?等等等等。若是对这些东西没有概念,则后续学习是很难开展下去的。

在此基础上,若是有条件,则最好可以亲自部署和实际操做一下Cinder(包括必要的其余OpenStack组件),以便对Cinder得到一个直观的认识和体验,为后续分析提供一些参考。此处假定Cinder使用的后端是Ceph,而OpenStack上运行的虚拟机是KVM。

而后,应该从概念上对咱们要分析的系统的逻辑框架有个理解。从整体的范畴上讲,应该了解Horizon和Nova各自的逻辑模块结构,以及它们和Cinder的协同工做方式、关系。这部分与Cinder的控制接口及执行路径分析密切相关。此外,还应该了解Cinder和KVM/QEMU、Ceph之间的相互关系。这对于真正理解Cinder颇有帮助。从Cinder自身而言,应该了解其内部逻辑模块构成、各自的功能、相互间的控制、数据链接关系等。

在完成上述准备以后,则能够开始对Cinder的代码进行分析了。如前所述,应该考虑在控制接口和数据接口中各自选择一两个关键的、有表明性的加以分析。至于配置接口,假定其实现了某一配置便可,暂时不须要过多花费时间。

Cinder的核心功能实际上是OpenStack上的volume管理。至少在Cinder+Ceph方案中,Cinder自身并不在数据传输关键路径上。所以,控制接口的分析就是Cinder源代码分析的重中之重。就入手阶段而言,则有两个接口及其对应执行流程能够做为Cinder分析的起点,即volume的create和attach操做。若是可以完全打通这两个操做的执行流程(至少要看到Cinder与Ceph经过librbd交互的层面),则对于真正理解Cinder的功能与实现大有帮助。

虽然基于KVM的虚拟机在经过QEMU访问Cinder建立的、Ceph提供的volume时并不经过Cinder,也即,这一部分的源代码其实已经超出了Cinder源代码学习的范畴,可是,若是但愿真正完全地理解Cinder,则对于这一部分知识仍是应该有所涉猎,至少应该有概念上的了解。

在达到上述阶段以后,则能够根据自身的需求决定后续计划了。

相关文章
相关标签/搜索