使用开源项目的正确姿式,都是血和泪的总结!

摘要:
开源精神是技术发展的源动力之一,受到工程师们的热烈欢迎。可是开源项目如此之多,哪个最适合本身?如何更好利用开源项目,甚至作二次开发?今天,阿里资深无线开发专家李运华,总结多年与开源项目打交道的经验,讲述如何正确利用开源项目,但愿对你们有所启发。


aff5567eb72f5331c0d21b333c0d20c0d22837d9

导读:软件开发领域有一个流行的原则:DRY,Don’t repeat yourself,咱们翻译过来更形象通俗:不要重复造轮子。开源项目主要目的是共享,其实就是为了让你们不要重复造轮子,尤为是在互联网这样一个快速发展的领域,速度就是生命,引入开源项目,能够节省大量的人力和时间,大大加快业务的发展速度,何乐而不为呢?

然而现实每每没有那么美好,开源项目虽然节省了大量的人力和时间,但带来的问题也很多,相信绝大部分同窗都踩过开源软件的坑,小的影响多是宕机半小时,大的问题多是丢失几十万数据,甚至灾难性的事故是所有数据都丢失。

除此之外,虽然DRY原则摆在那里,但实际上开源项目反而是最不遵照DRY原则的,重复的轮子好多,尤为是歪果仁,一看哪一个开源方案不爽,本身就吭哧吭哧搞一个差很少的:你有MySQL,我有PostgreSQL;你有MongoDB,我有Cassandra;你有memcached,我有redis;你有Gson,我有Jackson;你有Angular,我有React。总之放眼望去,其实类似的轮子不少!类似轮子太多,选择就是让人头疼的问题了。

怎么办?彻底不用开源项目几乎是不可能的,咱们须要更加聪明的去选择和使用开源项目。形象点说:不要重复发明轮子,但要找到合适的轮子!你开的是保时捷,可别找个拖拉机的轮子。

接下来我将根据加入UC,5年与开源项目有关的经历,总结出一些“如何正确使用开源项目”的经验和教训。有的项目是我亲身经历,有的是我接触到的,有的是我观察的,其中部分描述细节可能并不彻底准确,你们能够结合本身的经历一块儿探讨。

如下内容主要分3个部分进行描述,分别是“选”、“用”、“改”。

选:如何选择一个开源项目?

聚焦是否知足业务?

咱们在选择开源项目的时候,一个头疼的问题就是类似的开源方案较多,并且后面的老是要宣称比前面的更加牛逼。咱们在选择的时候有点无所适从,老是会担忧选择了A方案而错过了B方案,或者反过来。这里咱们的经验是聚焦因而否知足业务,而不须要过于关注开源方案是否牛逼。

案例:当时尝试一个社交类业务时,咱们发现了TT(Tokyo Tyrant)这个开源方案,以为既可以作缓存取代Memcached,又有持久化存储功能,能够取代MySQL,很牛逼,很高大上,因而就在业务里面大量使用了。但后来的使用过程让人很蛋疼,主要表现为:

一、不能彻底取代MySQL,所以有两份存储,设计的时候每次都要讨论和决策。

二、功能上看起来很高大上,但相应的bug也很多,并且有的bug是致命的,例如全部数据不可读,后来是本身研究源码写了一个工具才恢复了部分数据。

三、功能确实牛逼,但须要花费较长时间熟悉各类细节。

后来咱们反思和总结,其实当时的业务Memcached + MySQL彻底可以知足,且你们都熟悉,当时的业务彻底不须要引入TT。

简单来讲:若是你的业务要求1000 TPS,那么一个20000 TPS 和50000 TPS的方案是没有区别的。有的人可能会担忧我TPS不断上涨怎么办?其实不用担忧,咱们的架构会不断演进的,等到真的须要这么高的时候咱们再来架构重构,记住:不要过早优化,过早优化是万恶之源 —— 《UNIX编程哲学》。

聚焦是否成熟

不少新的开源项目每每都会声称本身比之前的项目更加牛逼:性能更高、功能更强、引入更多新概念。看起来都很诱人,但实际上都有意无心的隐藏了一个负面的问题:都更加不成熟!无论多牛逼的程序员写出来的项目都会有bug,千万不要觉得做者牛逼就没有bug,Windows、Linux、MySQL的开发者都是顶级的开发者吧,同样不少bug。

不成熟的开源项目应用到生产环境,风险极大。轻则宕机,重则宕机后重启都恢复不了,更严重的是数据丢失都找不回了。仍是以上面提到的TT为例:咱们真的遇到异常断电后,文件被损坏,重启也恢复不了的故障,还好当时天天作了备份,因而只能用1天前的数据进行恢复,但当天的数据所有丢失了。后来咱们花费了大量的时间和人力去看源码,本身写工具恢复了部分数据,还好这些数据不是金融相关的数据,丢失一部分问题也不大,不然就有大麻烦了。

因此在选择开源项目的时候,尽可能选择成熟的开源项目,下降风险。

能够从如下几个方面考察是否成熟:

1)版本号:通常建议除非特殊状况,不然不要选0.X版本的,至少选1.X版本的,版本号越高越好。

2)使用的公司数量:通常开源项目都会把采用了本身项目的公司列在主页上,公司越大越好,数量越多越好。

3)社区活跃度:看看社区是否活跃,发帖数、回复数、问题处理速度等。

聚焦运维能力

咱们在选择开源项目的时候,基本上都是聚焦于技术指标,例如性能、可靠性、功能这些方案,而几乎不会去关注运维方面的能力。但若是要将方案应用到线上生产环境,运维能力是必不可少的一环,不然一旦出问题,运维、研发、测试都只能干瞪眼,求菩萨保佑了!

能够从如下几个方案去考察运维能力:

1)开源方案日志是否齐全:有的开源方案日志只有寥寥启动中止几行,出了问题根本没法排查。

2)开源方案是否有命令行、管理控制台等维护工具,可以看到系统运行时的状况。

3)开源方案是否有故障检测和恢复的能力,例如告警、倒换等。

用:如何使用开源方案?

深刻研究,仔细测试

不少人用开源项目,实际上是完彻底全的“拿来主义”,看了几个Demo,把程序跑起来就开始部署到线上应用了。就好像看了一下开车指南,知道了方向盘是转向、油门是加速、刹车是减速,而后就开车上路了,实际上是很是危险的。

案例:咱们有团队使用了elasticsearch,基本上是拿来就用,倒排索引是什么不太清楚,配置都是用默认值,跑起来就上线了,结果就遇到节点ping时间太长,剔除异常节点太慢,致使整站访问挂掉。

案例2:不少团队最初使用MySQL的时候,也没有怎么研究过,常常有业务部门抱怨MySQL太慢了,其实通过定位,发现最关键的几个参数(例如innodb_buffer_pool_size, sync_binlog,innodb_log_file_size等)都没有配置或者配置错误,性能固然会慢。

能够从以下几方面进行研究和测试:

1)通读开源项目的设计文档或者白皮书,了解其设计原理;

2)核对每一个配置项的做用和影响,识别出关键配置项;

3)进行多种场景的性能测试;

4)进行压力测试,连续跑几天,观察cpu、内存、磁盘io等指标波动;

5)进行故障测试:kill,断电、拔网线、重启100次以上、倒换等。

‌当心应用,灰度发布

假如咱们作了上面的“深刻研究、仔细测试”,发现没什么问题,是否就能够放心大胆的应用到线上了呢?别高兴太早,即便你的研究再深刻,测试再仔细,也仍是要当心为妙,由于再怎么深刻的研究,再怎么仔细的测试,都只能下降风险,但不可能彻底覆盖全部线上场景。

案例:仍是以TT为例吧,其实咱们在应用以前专门安排一个大牛看源码、作测试,作了大约1个月,但最后上线仍是遇到各类问题。线上生产环境的复杂度,真的不是测试可以覆盖的,必须当心谨慎。

因此,无论研究多深刻、测试多仔细、自信心多爆棚,时刻对线上要有敬畏之心,当心驶的万年船。咱们的经验就是先在非核心的业务上用,而后有经验后慢慢扩展。

作好应急,以防万一

即便咱们前面的工做作得很是完善和充分,也不能认为就万事大吉了,尤为是刚开始使用一个开源项目,运气很差的话就可能遇到一个以前全世界的使用者历来没遇到的bug,致使业务都没法恢复,尤为是存储方面,一旦出现问题没法恢复可能就是致命的打击。

案例(此案例是据说的):某个业务使用了MongoDB,结果宕机后部分数据丢失,没法恢复,也没有其它备份,人工恢复都没办法,只能接一个用户投诉处理一个,致使DBA和运维今后之后都反对咱们用MongoDB,即便是尝试性的。

虽然由于一次故障就彻底反对尝试是有点反应过分了,但确实故障也给咱们提了一个醒:对于重要的业务或者数据,使用开源项目时,最好有另一个比较成熟的方案作备份,尤为是数据存储。例如:若是要用MongoDB或者Redis,能够用MySQL作备份存储。这样作虽然复杂度和成本高一些,但关键时刻可以救命!

改:如何基于开源项目作二次开发?

‌保持纯洁,加以包装

当咱们发现开源项目有的地方不知足咱们需求的时候,天然会有一种去改改的冲动,可是怎么改是个大学问。一种方式是投入几我的从内到外所有改一遍,将其改形成彻底符合咱们的业务需求。但这样作有几个比较严重的问题:

1)投入太大,通常来讲,redis这种级别的开源方案,真要本身改,至少要投入2我的,搞1个月以上;

2)失去了跟随原方案演进的能力:改的太多的话,即便原有开源项目继续演进,咱们也没法合并了,由于差别太大。

因此咱们的建议是不要改动原系统,而是要开发辅助系统: 监控,报警,负载均衡,管理等。以Redis为例,若是咱们想增长集群功能,不要去改动Redis自己的实现,而是增长一个proxy层来实现,Twitter的Twemproxy就是这样作的,而Redis到了3.0后自己提供了集群功能,原有的方案简单切换到Redis 3.0便可。详细可参考(http://www.cnblogs.com/gomysql/p/4413922.html )

若是实在想改到原有系统,怎么办呢?咱们的建议是直接给开源项目提需求或者bug,但弊端就是响应比较缓慢,这个就要看业务紧急程度了,若是实在太急那就只能本身改了,不过不是太急,建议作好备份或者应急手段便可。

发明你要的轮子

这点估计让不少人大跌眼镜,怎么讲了半天,最后又回到了“重复发明你要的轮子”呢?

其实选与不选开源项目,核心仍是一个成本和收益的问题,并非说选择开源项目就必定是最优的方案,最主要的问题是:没有彻底适合你的轮子!

软件领域和硬件领域最大的不一样就是软件领域没有绝对的工业标准,你们都很尽兴,想怎么玩怎么玩,不像硬件领域,你造一个尺寸不同凡响的轮子,其它车都用不上,你的轮子工艺再高,质量再好也是白费;软件领域能够造不少类似的轮子,也基本上能处处用,例如你把缓存从Memcached换成Redis,不会有太大的问题。

除此之外,开源项目为了可以大规模应用,考虑的是通用的处理方案,而不一样的业务其实差别较大,通用方案并不必定完美适合具体的某个业务。好比说Memcached,经过一致性hash提供集群功能,可是咱们的一些业务,缓存若是有一台宕机,整个业务可能就被拖慢了,这就要求咱们提供缓存备份的功能,但Memcached又没有,而Redis当时又没有集群功能,因而咱们投入2~4我的花了大约2个月时间基于LevelDB的原理,本身作了一套缓存框架支持存储、备份、集群的功能,后来又在这个框架的基础上增长了跨机房同步的功能,很大程度上提高了业务的可用性水平。若是彻底采用开源方案,等开源方案来实现,是不可能这么快速的,甚至都有可能开源项目彻底就不支持咱们的需求。

因此,若是你有钱有人有时间,投入人力去重复发明完美符合本身业务特色的轮子也是很好的选择!毕竟,土豪们(BAT、Facebook、Google......等)不少都是这样作的,不然咱们也就没有那么多好用的开源项目了 :)

做者: 云效平台

原文连接html

相关文章
相关标签/搜索