从GitHub上可以看出,到目前为止,由腾讯微信团队发起的开源项目已经有6个,并且这其中大部分都是在2016年开源的,领域涉及移动、数据库、基础类库、框架。中国大公司的开源曾经给社区留下不好的印象,比如有人就这么说,大公司的开源,开源也就意味着结束。也有人说,大公司的开源大部分都是KPI项目,开源与业务不能相得益彰,所以根本无法持续投入。
相比来说,Facebook就是互联网公司里的开源大户,目前他们的开源项目已经有近300个。对于为什么要发布开源项目,Facebook开源项目负责人也曾经解释过,总结起来说有三点,一是开源能够帮助他人更快地开发软件,促进世界创新,主要是社会价值层面的考虑。二是开源能够倒逼Facebook的工程师写出更好的代码。三是开源能够更有效利用社区的力量,帮助Facebook一起解决难题。
那微信是如何理解开源这件事,以及他们未来准备通过哪种机制保证开源项目的健康发展,带着这些问题,InfoQ记者采访了微信终端团队的负责人赵原。
赵原认为开源不仅是一种态度,更是一种能力,微信希望通过开源打通内部团队和外部社区,一方面可以把微信的顶级技术输出给了社区,另一方面也可以把外部的优秀的思想传递到内部团队。对于开源的理解,赵原这样解释:
第一个关键词价值。微信团队通过将内部的研究成功优化、整合,并输出,以帮助更多的开发者更方便地构建他们的软件。工程师之间最好的交流媒介就是代码,通过代码,微信团队可以将他们的技术思想传递到社区,并影响更多的人。
第二个关键词优势。微信最大的优势是有海量的用户,很多外界开发者根本没有发现或者遇到过的复杂问题,微信团队都早已经解决掉了,比如在移动开发领域的系统兼容性、用户多样化的网络环境等问题。通过开源,微信不仅可以授之以鱼,还可以授之以渔。
第三个关键词活力,微信开源的项目必须来自微信,最后必须在微信落地。开源项目最怕没人维护,通过产品迭代,这些开源的项目持续的更新,给他们一个心跳的机制,使他们依然有活力。
第四个关键词易用。一个优秀程序员可以花上很多的时间研究微信开放的技术源码的技术思想和设计。但对于不是很有技术实力的开发人员,是否能从微信的开源项目中依然获益呢?答案是肯定的。他可以将微信开源的项目引入在自己的APP中,将微信很多的能力运用在自己的APP中。
而对于项目开源之后的运营问题,赵原也做了思考:
活力,不得不提起一个尖锐的问题,在大公司里面做开源项目,开源通常意味着这个项目的结束。优秀的开源项目意味着开始,和大公司里的开源项目做法天生有一些冲突。
第一大公司里面做开源项目其实是有一些短期KPI导向的短期项目,开源项目需要持续的人力投入在其中。第二个问题,每一个团队里面员工开发的精力是有限的,做技术研究的时候,需要花很多时间在供应商的开发,这是从员工方面看开发精力的冲突。第三大公司内通常有完备的开发体系,而这些开发是封闭的,很难说和外部的开源体系对接起来。
今天看这个问题,微信也想过很暴力、很简单的想法,比如说团队10个人,这10个人可以做功能开发,如果为了解决这个问题,再招10个员工砸在开源项目上,大公司可能最不缺的就是人力,问题是在大公司里面看上去是可以解决的,但放在微信上面却觉得行不通,微信讲究小团队作战,讲究精兵策略,不浪费一兵一卒。
为了解决这个问题,微信在开发Tinker项目的过程中,大概用了快一年的时间解决,其实解决问题的方法很简单。简而言之,就是将微信的开发团队改造成一个开源化的开发模式。
微信通过对内部系统的改造,使内部的开发和外部的开发模式基本没什么不同。一份代码,既可以在微信中使用,也可以在外部的开发者中使用,这科技减少额外的人力投入。
另外微信还收获了很多价值。比如外部的开发者还可以提供一些微信团队没有发现的问题,对于微信来说是一个很好的优化bug的渠道。通过与外部社区的深入交流,团队的学习能力也能得到很大提升。
下面是InfoQ编辑整理的微信现有的比较活跃的开源项目列表,欢迎交流讨论。
C/C++协程库Libco
Libco是微信后台大规模使用的C/C++协程库,2013年至今稳定运行在微信后台的数万台机器上。Libco提供了完善的协程编程接口、常用的Socket族函数Hook等,使得业务可用同步编程模型快速迭代开发。
早期微信后台因为业务需求复杂多变、产品要求快速迭代等需求,大部分模块都采用了半同步半异步模型。接入层为异步模型,业务逻辑层则是同步的多进程或多线程模型,业务逻辑的并发能力只有几十到几百。随着微信业务的增长,系统规模变得越来越庞大,每个模块很容易受到后端服务/网络抖动的影响。基于这样的背景,微信开发了Libco,实现了对业务逻辑非侵入的异步化改造。
GitHub地址:https://github.com/tencent/libco
Star数量:1043
生产级paxos类库PhxPaxos
PhxPaxos是微信后台团队自主研发的一套基于Paxos协议的多机状态拷贝类库。它以库函数的方式嵌入到开发者的代码当中,使得一些单机状态服务可以扩展到多机器,从而获得强一致性的多副本以及自动容灾的特性。PhxPaxos在微信服务里面经过一系列的工程验证和大量的恶劣环境下的测试,在一致性的保证上极为健壮。
PhxPaxos的特性包括使用基于消息传递机制的纯异步工程架构、每次写盘使用fsync严格保证正确性、支持Checkpoint以及对PaxosLog的自动清理、使用点对点流式协议进行快速学习、支持跨机器的Checkpoint自动拉取、内置Master选举功能、自适应的过载保护等。
GitHub地址:https://github.com/tencent-wechat/phxpaxos
Star数量:970
高可用、强一致的MySQL集群:PhxSQL
PhxSQL是一个兼容MySQL、服务高可用、数据强一致的关系型数据库集群。PhxSQL以单Master多Slave方式部署,在集群内超过一半机器存活的情况下、即可提供服务,并且自身实现自动Master切换、保证数据一致性。PhxSQL不依赖于ZooKeeper等任何第三方做存活检测及选主。PhxSQL基于MySQL的一个分支Percona 5.6开发,功能和实现与MySQL基本一致。
MySQL主备在主机上支持完整SQL、全局事务、以repeatable read和serializable级别的事务隔离,在金融、帐号等关键业务中有巨大的价值。但是MySQL传统主备方案也有其缺点。最明显的就是主机故障后的自动换主和新旧主数据一致性,即所谓的一致性和可用性。为了解决这个问题,并同时完全兼容MySQL,微信在MySQL的基础上应用Paxos,设计和开发了PhxSQL。
GitHub地址:https://github.com/tencent-wechat/phxsql
Star数量:1485
RPC框架:PhxRPC
PhxRPC是微信后台团队推出的一个简洁小巧的RPC框架,编译生成的库只有450K(编译只依赖第三方库Protobuf)。PhxRPC的特性如下:
使用Protobuf作为IDL用于描述RPC接口以及通信数据结构。
基于Protobuf文件自动生成Client以及Server接口,用于Client的构建,以及Server的实现。
半同步半异步模式,采用独立多IO线程,通过Epoll管理请求的接入以及读写,工作线程采用固定线程池。IO线程与工作线程通过内存队列进行交互。
提供完善的过载保护,无需配置阈值,支持动态自适应拒绝请求。
提供简易的Client/Server配置读入方式。
基于lambda函数实现并发访问Server,可以非常方便地实现Google提出的 Backup Requests 模式。
GitHub地址:https://github.com/tencent-wechat/phxrpc
Star数量:467
终端跨平台网络组件:Mars
Mars是微信官方的终端基础组件,是一个结合移动应用所设计的基于Socket层的解决方案,在网络调优方面有更好的可控性,采用C++开发。目前已接入微信 Android、iOS、Mac、Windows、WP 等客户端。
在微信中,任何网络实现的bug都可能导致重大事故。例如微信的容灾实现,如果因为版本的实现差异,导致某些版本上无法进行容灾恢复,将会严重的影响用户体验。微信研发了统一的跨平台的网络基础库Mars来满足发展的需要,一方面,基础组件可以提高研发效率,另外一方面,也可以提高系统的稳健性。
在设计上,Mars以跨平台、跨业务为前提,遵从高可用,高性能,负载均衡的设计原则。以网络的可用性为例,移动互联网有着丢包率高、带宽受限、延迟波动、第三方影响等特点,使得网络的可用性,尤其是弱网络下的可用性变得尤为关键。Mars 的STN组件作为基于 socket 层的网络解决方案,在很多细节设计上会充分考虑弱网络下的可用性。
GitHub地址:https://github.com/Tencent/mars
Star数量:5895
热补丁技术Tinker
Tinker是微信官方的Android热补丁解决方案,它支持动态下发代码、So库以及资源,让应用能够在不需要重新安装的情况下实现更新。
当前市面的热补丁方案有很多,其中比较出名的有阿里的AndFix、美团的Robust以及QZone的超级补丁方案,但它们都存在无法解决的问题,所以微信研发了自己的解决方案。总的来说,AndFix作为native解决方案,首先面临的是稳定性与兼容性问题,更重要的是它无法实现类替换,它是需要大量额外的开发成本的。而Robust兼容性与成功率较高,但是它与AndFix一样,无法新增变量与类只能用做的bugFix方案。Qzone方案可以做到发布产品功能,但是它主要问题是插桩带来Dalvik的性能问题,以及为了解决Art下内存地址问题而导致补丁包急速增大的。