如何改动开源项目?

Posted 生栋说

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何改动开源项目?相关的知识,希望对你有一定的参考价值。

本文是开源软件选型相关的姊妹篇,介绍在团队里选择了某个开源软件后,如何根据需求做改动。

大忌

千万不要从内到外改一遍,这样造成严重问题:

  1. 投入太大:两个开发,投入1个月,不见得能有什么效果。因为从理解,到修改,到测试。不跑偏的难度很大
  2. 失去跟随原有项目演进的能力:上游升级怎么办?典型的例子就是狗东的某JDOS集群,到现在都是 k8s 1.5 的版本
  3. 风险不可控:好的项目,是花了长年累月的时间积累的,比如K8S, 已经发展到第7个年头了。所以在短时间内大范围的改动,是很难的。就跟吃了7年饭,胖了40斤,想在几个月内减下来一样。可以做到,但是很难。

可以开发对接原有扩展接口或者做独立的外围系统。典型例子:数据库分库分表的方案,绝大部分都是在mysql或者Redis前面加Proxy,而不是进入到组件代码里魔改。

如何修改开源代码

可以遵照以下几点:

基本原则

  1. 跟社区沟通清楚需求及实现方案,争取得到社区的认可
  2. 设计方案要保持原有接口不变,向前兼容
  3. 去扩展而不是修改原有方案:按照开闭原则,去做接口的实现,而不是直接改接口。如果没法达到,说明开源项目本身质量不好,或者是我们的思路没有迎合既有设计。
  4. 保证代码易读性、可维护性:代码风格跟上游一致、添加测试用例

遵照上述标准后,我们的修改,是完全可以贡献的社区的,社区从来不会拒绝好的PR

举例

跟电、电线、插座、灯泡一样,需要定位好开源项目的作用,最好让它成为一个灯泡,可以用其他灯泡(轮子)来代替,不要对某个特定软件有强依赖。

如果我们要添加新功能,想清楚这个功能是要加到原有代码里,还是要新增一个模块、服务、系统,然后让两者联动。典型的就是K8S里的 Aggregated API Server,它是单独的一个服务,它即能复用原有的k8s api server里的认证、鉴权、admission controller,etcd存储等通用特性,还能留出来业务逻辑实现的自由度。

大家也可以起看看这7年来K8S的演进历程,CSI,CNI,DevicePlugin等组件就是典型的不断分家的过程,原来是揉到一起的,后来由于不利于协作,社区就定义清楚接口,然后把频繁变动、跟厂商相关的东西拆出去。具体实现时让厂商、开发者去实现,进行依赖反转(IoC)。让更多人能参与进去,是K8S社区迅速强大,成为问鼎Linux,全球顶级开源社区的原因之一。

发明你要的轮子

恭喜你,一般需要发明轮子时,说明到业务到了一定体量,进入了一个新阶段:

  1. 开源方案是通用的,考虑了80%的 Happy Case。当前阶段不能完全解决我们的问题了
  2. 团队里同学已经把开源项目摸透了,长期做这个方向,熟能生巧了,有信息能搞定一套更符合业务所需的轮子
  3. 团队里有时间、人力去投入,老板也支持发明符合自己场景的轮子

可以参考《阿里技术十年》,里面都是不断在做循环:先用开源项目,等到一定阶段再另起炉灶