.. Kenneth Lee 版权所有 2018-2020
:Authors: Kenneth Lee :Version: 1.0
开源交付
本文是前一个文档(设计规范)的逻辑延伸,讨论组织层面的架构控制问题。由于逻辑相 对独立,所以就“分了模块”:)
很多组织都在搞“开源”,还常常细分为“内部开源”和“外部开源”这两种概念。但很多管理 层甚至工程师其实都不知道开源本质到底是什么东西,仿佛把代码给出去,就叫“开源”。
从这样描述的语义来说,“开源”的作用似乎和“慈善”的效果一样,只具有“广告”效应。这 就是为什么很多公司管理层总认为“开源”不是正道,你会认为一个公司负责“慈善”部分的 工作是这个公司的关键问题吗?这不一般是给董事长老婆的福利么?
如果我们能有“守弱”一点的思维,虚心实腹,谨守直接可见的逻辑,少那么多高大上理念 。我们很容易会发现,开源的作用就只有一个:工程师可以看得见源代码。
从这个基本逻辑开始推演,我们就必须接受,“开源的好处就是工程师可以看得见代码”, 不是“高手都做开源”,“开源后高手就会加入我们的开发”,“开源是工程师职业生涯的证明 书”,“开源会把不好的代码暴露在阳关下,人们就会把代码写好”……真是扯淡,老婆还在天 天抱怨房子没有隔壁老王的房子大呢,你有空去看别人的代码?你都不看,你指望别人看 ?自己都不想当大侠,却等别人当大侠为国为民(其实主要是想他为你)?你这是装天真 还是揣着明白装糊涂啊?
工程师什么时候会有空去看别人的代码呢?嘿嘿,当然是要抄的时候(有时是定位问题的 时候,但其实不是主流)。
比如我要做一个GPIO驱动,怎么做呢?当然是直接找其他厂商的驱动直接拷过来开始改啊 。找哪个呢?当然是找一个接近的啊,比如我的设备是经过一个controller来控制所有 gpio端口的,上面还连了一个iommu,就找具有这个特征的厂商的呗。找不到?那就找一个 接近的喽,先用那个作为基础,没有iommu不要紧,网卡不是用了iommu吗,从网卡这里再 抄一个。还要用debugfs暴露调试接口?不要紧,这个模式不是和rasdaemon很像吗?从ras 框架上拷贝就可以了。什么?还要一个内存分配算法,那我们可以拷贝slab的算法啊, slab太重了?也不要紧,uclibc那个malloc肯定不重,从那里拷贝吧……
你看,这就是现在大部分工程师写代码的过程——拷贝粘贴,再把逻辑拼在一起,减少漏洞 ,搞定。
开源给了他们拷贝的机会。
拷贝的缺点我们都知道了,这会导致代码的急剧膨胀(这也是当初Linaro成立的原始动力 ,因为ARM厂商众多,这种拷贝的做法让ARM的目录转眼间就超过Linux的所有其他代码了, Linus出来一顿痛骂,然后几家ARM SoC供应商跑到Linaro合计合计,一年后这个目录又缩 回到普通大小了:))
这就是代码都在一起的威力:你手上一个二进制,我手上一个二进制,把拷贝的目录合并 ?先开一年会好不好啊?
考量这个细节,我们就可以区分出开源交付的两种形态了:
交付二进制,提供源代码(我们简称二进制交付)
交付源代码(我们简称源码交付)
很多企业(特别是国内企业)开源,其实做的是前者,这上面的收益其实很低,其实就是 慈善,因为除了拷贝,你做不了其他任何事情。
第二种才是真的能达成构架收益的开源,比如我做一个内存算法,交付给一个统计程序。 这个我不是交付一个libmem.so的,我交付的是stat/mem这个子目录,这样,任何一个其中 的开发工程师手上都是全部代码,架构师和系统工程师就有机会权衡我们前一片提到的“抽 象”问题,决定每个特性是开克隆,还是合并为一个抽象。这完全取决于这个系统的架构师 对这个市场的需求的选取(是需求在决定关联,不是设计)。这样,整个系统才有可能真 得“合道”(最优解)。
开源的需求是来自非常细节的设计和开发过程,不是你纸上谈兵在PPT上可以想清楚的。它 的重要性和慈善,贡献之类的关系非常少。它是放下了“保密”的包袱,来换取架构优化的 优势。如果这个地方没有架构优化的余地,你就只剩下“泄密”这个缺点了。
很多工程师可能觉得这是个小问题,但如何拷贝代码还能保持复用,对很多大型企业来说 都是大问题。因为他们代码量巨大。我们以前曾经尝试过一种所谓CBB(Common Build Block)的策略,事实证明这种方法就是个彻底的失败。
所谓CBB,就是把相对独立的模块独立出来的,在多个产品之间共享。但这种东西只能停留 在PPT上用来YY。因为根本就不存在没有依赖的所谓“独立模块”。就说你做的是一个二叉树 好吧。纯粹的算法,应该可以在各个产品中复用吧?
好了,我有这个需求了,要用你的CBB了。现在的问题是,里面要分配内存用什么分配函数 ?
要写日志呢?
收到signal呢?
多线程访问呢?
要跨机迁移呢?
要异常倒换呢?
……
你可以说,这些东西我都可以做成“可配置的”——为了用你一个二叉树算法,我还要配置一 大堆这种参数?我不如自己写呢。而且,本来一个二叉树算法挺好写的,结果要考虑十几 种配置数百种组合下都能跑?——什么叫“过度设计”啊?小哥哥。
什么可以被抽象,什么必须分离,现在没有算法可以自动做到,AI也不行。只有人能做到 ,而人必须看得见代码才能做到,这就是开源的驱动力。其他的,都是浮云。就算你不开 源,软件的开发本质仍是这样,你不对架构师提供源代码,带来的仅仅是这个损失。所以 考虑源代码提供的边界,在于你认为这个地方有多少可抽象的余地。如果你部门墙太多, 纯用二进制交流,或者用二进制交付,提供源代码这种方式号称开源,你的架构就面对很 大的挑战。非源代码交付,几天以后二进制就和源代码对不上了。作为程序员,各位扪心 自问,你们愿意定位或者考虑源代码和二进制对不上的东西吗?
软件本身就是件非常精巧的事情,好像修理一个机械表,我们巴不得戴上放大镜,显微镜 。结果你让人戴上墨镜来修,这个结果是什么,还用解释吗?
对这个模式的认知,也给我们如何对组织进行架构控制提供了思路。要对组织进行架构思 想渗透,就是要挑好的产品或者模块,先把那个模块做到好,把你想表演的模式都先表演 上去,然后用开源的方式渗透到更多的产品,等这个雪球滚到一定的程度,就不需要你自 己推了,工程师们会说:“这都是我想出来的,关那些个架构师屁事”(功成身退,百姓皆 谓“我自然”)。所以做这种整体的事情,永远都是这个问题:“你要求名,还是求道”?