目前阿里集团每天有近1000PB的数据是通过LogAgent采集的,为了让LogAgent做到资源占用节省和高效采集,背后是基于HiSDP去构建的。
缘由
当决定采用C++编程语言去开发一个软件时,紧接着所面临的问题是软件库、平台与框架的选择。当然,选择的范围估计很大程度来自开源软件。进一步地,无外乎两种思路:
- 根据所开发软件的需要选择各种合适的开源软件,然后将这些开源软件组合到一起去完成软件开发工作。这种方式所带来的问题在于,将各个开源软件拼凑到一起需要耗费一定的精力。此外,可能因为踩各开源软件中的坑而导致最终软件产品的稳定期拉得更长,后期的维护成本也更高。
- 采用市面上成熟的大型开源软件项目,对之进行裁剪去满足项目开发的需要。这一方式虽说在裁剪上需要消耗一定的精力(这是一次性的工作内容),但由于大型项目的成熟确保了其所选择的各个开源子项目的质量得到了充分的验证而避免我们再踩坑,且其中所使用各开源软件的代码能很好地起到示范作用去帮助工程师更快地上手写出更具质量的代码。HiSDP就是基于这一思路而产生的!
HiSDP源于Google的Chromium开源软件,即大家平时经常使用的Chrome浏览器的开源版。作者因为曾经有大约3年半的时间是基于Chromium做淘宝浏览器和UC浏览器电脑版的软件开发工作,所以对Chromium背后所蕴藏的Google之工程理念和对工程质量的要求有着深刻的认识与体感,
包含但不限于:
- 重度依赖单元测试。Chromium对单元测试代码的组织与实践形成了一套行之有效、很容易上手的工程规范,很好地示范了如何通过gtest/gmock去编写单元测试代码,并让执行单元测试的动作与开发环境做到了无缝整合。
特别重视程序的性能度量。Google一直力争让Chrome浏览器在运行速度上与竞品保持优势,为此非常重视性能数据的可视化,tracing功能就是在这样的背景下产生的(用Chrome浏览器导航到chrome://tracing这个网址就可以对浏览器打开的网页进行性能tracing)。
- 极度关注程序的编译效率。由于Chromium的代码量很是庞大,所以这个项目从开始之初就在一直持续地优化整个工程的编译速度。除了gn+ninja这一编译工具组合,Chromium的代码组织与程序格式也为了加速编译而做了规范并细致地执行到位。
- 将程序的可查错性当作良好的编程习惯。整个Chromium的代码随处可见DCHECK(与assert相似),以及在关键点存在CHECK(会产生dump文件而记录下发生问题的现场)。
- 严格执行Google C++ Coding Style中所定义的编码规范。为了帮助新手更好地掌握这一规范,甚至还开发出了cpplint这样的代码规范扫描工具(用Python实现的)。
- 对软件设计质量的持续极致追求。Chrome浏览器大约6周出一个大版本,每个版本都能看到对之前没有做到位的完善痕迹,有的改进尺度之大足以让人为之动容。这种工程实践所带来的结果是Chromium的整体代码质量很高且久经考验。
基于我对Chromium的这些认识,很自然地想到将那些能力与气质带到其他项目中,希望能“站在巨人的肩膀上”以“杀鸡用牛刀”的思路去开发其他C++软件。
HiSDP是High-productivity Software Development Platform的简写。取这个名的本意是希望他成为C++编程语言的高效软件开发平台。然而,将Chromium裁剪成HiSDP并使之适合用于集团服务器环境下的软件开发还是经历了一些波折。最大的问题在于,Chromium的开发环境基本上是基于Ubuntu 16.04构建的,存在内核版本比集团环境的更高而导致无法直接正常运行的问题,当然这个问题经过一番折腾后得到了解决。
能力
- 具备跨Windows、Mac和caozuoxitong.html" target="_blank">Linux操作系统的软件开发能力。HiSDP完全保留了Chomium的base库,该库抽象并封装了file、string、threading、process、message_loop、memory、profiling等诸多内容,能很好地满足其他软件开发工作的基础需要。
- 具备复杂工程的高效源代码组织与快速构建能力。通过gn文件(与CMakeLists.txt文件的作用相似)对源文件进行管理;通过ninja(与make类似)调用编译器完成编译工作;通过DEPS文件管理工程所依赖的第三方Git仓库。可以想象,gn文件的语法完全考虑了跨平台场景下源代码的组织形式。构建速度将随着项目规模的增大而表现得愈加明显。
- 全面复用与Chromium配套的各种开发工具。Chromium将各种工具都放到了depot_tools 这个独立的Git仓库中,其中包含了支撑高效软件开发工作的各种脚手架工具。
- 实现了被开发软件与HiSDP自身的很好解耦。通过引入HiApp的概念,将基于HiSDP开发的软件的源代码都放在一个独立的Git仓库中,将HiApp与这个仓库挂钩而实现了与HiSDP的代码组合。下面的命令示例了如何获取depot_tools、HiSDP和LogAgent的代码,希望有助于帮助理解HiApp的概念。
?
class="cke_widget_element">$ git clone http://gitlab.alibaba-inc.com/middleware-expert/depot_tools.git depot_tools
$ vim ~/.barshrc // 追加下面内容
export PATH="/path/to/depot_tools/:$PATH"
$ source ~/.barshrc
$ mkdir LogAgent && cd LogAgent
$ fetch hisdp --hiapp=git@gitlab.alibaba-inc.com:LogAgent/Agent.git@release-3.0
简单说来,使用depot_tools和HiSDP的开发体验与Chromium是完全一样的。
价值
- 解决“技术可以,开发不行”现象。当个体对软件工程没有足够的认识,并不清楚除了编程语言和算法外,还有其他关键因素影响着开发效率和最终的软件质量,那时就会表现出“技术可以,开发不行”,即各种技术知识都知道,但却做不到有质效地开展软件开发工作。HiSDP因为继承了Chromium十多年所沉淀的工程经验,所以是一个很好的学习场所,即便一开始没有意识到那么做背后所蕴含的理念,只要模仿就可能最终贯通领悟。
- 助力跨平台软件开发。由于天然地支持开发可运行于Windows、Mac和Linux上的软件,HiApp因为有这样的“底座”而更容易实现跨平台开发。
- 提高软件开发效率。这一点是显而易见的,围绕工程各个方面的脚手架工作在HiSDP上都已具备,只需在HiApp的开发中专注于所需解决的业务问题。
- 通过代码共享解决了版本依赖问题。与大多C++程序员所希望的所不同的是,HiSDP不是以库的形式呈现的,而是完全以源码形式。借助HiApp这一概念,使得被开发软件的源代码也成为了HiSDP的一部分。这一形式省去了采用库形式发布所带来的版本升级与同步问题,当HiSDP中修复了缺陷时,由HiApp的开发者通过pull最新的代码做到修复。如果读者细想这一点,会对其价值有更深的认识。
挑战
正如“天下没有免费的午餐”所表达的哲理,当我们在享受HiSDP所带来的优势时,也不得不面临一些挑战,即掌握HiSDP需要一定的时间、其入门的门坎相对要高出不少。诚然,这一挑战需要工程师个体通过学习去应对,且学习过程需要在即便上手后仍持续保持,因为HiSDP真的是一个巨大的知识宝藏,从技术和工程领域都给出了很多有启发性的实现参考和解决方案,非常值得“细品慢嚼”。
最后,LogAgent在刚过去的2018财年很好地用HiSDP演绎了“用牛刀杀鸡”的工程理念。
附录
- 《What is GN?》
- 《The Ninja build system》
原文链接