# 国内的云计算平台有没有不是依靠 OpenStack 搭建的？

腾讯云是自研的系统。

-------------------------------------

这正好是我在腾讯云多年以来做过的一个微小工作。

有一天，领导跟我说：中央已经决定了，由你来参与设计和建立腾讯云新的后台框架。我心想，我一个做名字服务的码农，怎么就调到虚拟机那边去了呢？正想吟诵两句诗，发现领导已经离开了。

面对突如其来的硬点，作为原教旨主义的开源信徒，我确信要采用OpenStack，正如我曾力排众议把ZooKeeper引入系统当中。

当时我已经研究OpenStack有好长一段时间了，也曾多次指手划脚吐槽现有系统的设计，倒也从来没想过这种在电视剧中活不过两集的态度竟然给我带来这样一个机会。（感谢我司的企业文化）

但是，当我真的要做这样一件事的时候，我确越来越困惑，直到最后我认为OpenStack并不适合我们的场景，甚至是公有云。（我的决定也是很重要的）

首先，我们当时的问题是什么，OpenStack的优势是什么？

正如我所说过的（在云计算公司工作是什么样的体验？ - 李力的回答），云是一个大型的系统级的工程，它看不惯过往一切无法用软件定义的基石，所以云的终极目标是同时要保证稳定与灵活。具体来看腾讯云当时的系统，流程繁琐、调用冗长，众多模块逐渐形成一个mesh的脆弱结构，容灾能力、可追溯能力、部署能力都存在极大的挑战。与之相比，OpenStack就显得先进得多：restful的接口设计、独立互不依存的模块划分、清晰有意义的分层结构以及完整而灵活的driver设计，是一个逼格满分的解决方案。

然而，经过仔细分析，OpenStack的诸多闪光点却并未照亮我们急需解决的几个问题，主要包括：

1. 可维护性

OpenStack是大而全的解决方案，不论是什么云它都希望能帮得上忙。这导致其设计极度考虑灵活性，在一切可能变化的地方都会为了扩展和改进做大量的工作。

但是，OpenStack的任何使用者都只需要使用它极小的一部分配置集合，而且其它开发者也不一定愿意在理解了它完美的层次再进行开发（参照neturon的部分厂商代码）

这导致OpenStack的部署与配置十分复杂，而且这让你感觉很疲惫，它无法非常直接地解决你的问题，而总是要正襟危坐、小心翼翼地通过各种包装、代理、驱动才接触到问题，还不一定符合期望。

而且OpenStack作为docker以前开源社区最热的项目，代表了开源项目的最高峰，有一个显著的特点：尽一切可能把开源的兄弟们拉入伙！于是你看到OpenStack会尽量与各种开源工具融合起来，这无形中增加了运维的成本。OpenStack本来就不简单，需要理解大量你可能未曾预料的巧妙，还需要学习各种其它的开源项目。

对于云的后台框架，我们必需要对其理解得十分透彻，如果光是打开代码都会导致内存不足，我是不愿意在半夜起来处理故障时面对它们的。

2. 容灾能力与高可用

跟上一条类似，早期OpenStack似乎压根没有想过高可用部署，这实在是让人匪夷所思的一个考虑。

直到我到香港参加OpenStack Summit时，有一个专场是讨论高可用部署，我才发现OpenStack的高可用方案又拉了一堆的大型的开源软件进到你的生产系统。

在腾讯，高可用是后台服务必备的能力，我们从未想过通常不需要花费太多精力的工作在OpenStack上竟然有点让人畏惧。

3. 可追溯能力与流程回滚

可追溯能力是复杂的分布式系统中非常重要的一点。在我们的『全mesh』云平台中经常会遇到一个流程突然中断，却很难找出在哪里失败，为何失败，更重要的是如何回滚。

这在早期OpenStack中我并未看到任何更先进之处。看似随意的rpc、逻辑的散落、精巧但是难以追溯的eventlet都增加了异常发生时你定位的困难和恼怒的情绪。

也许是我没入对门，即便是我看过很长时间代码，仍然很难快速定位出哪怕是因为配置错误导致的流程失败。

想到以后要天天加班到凌晨，我赶紧跟领导说：我们自己来吧！

4. 性能与稳定性

重要的事情再说一遍：随意的rpc。

消息队列受到影响，甚至无法保障通信的可靠。

凡是有用OpenStack管理过大规模宿主机的，应该都踩过这个大坑。

----------------------------

事不关己时谈笑风生，事到临头却无可奉告，眼看自己声名尽毁的速度跑得比谁都快，甚至还会被领导和同事批判一番。于是，我和我的小伙伴们闭关研究一个月、开发一个月，做了腾讯云新系统的第一版。考虑到保密性，下文姑且叫它MS-FDC（闷声-发大财）

在设计上，FDC系统主要有几下几点：

1. 尊重消息流转。可追溯性是第一优先级。

mesh结构类似于网络工程中节点互相访问的场景，如果都是点到点通信，那么节点规模的线性增长会导致信道的指数级增长。

FDC使用RabbitMQ做为统一的通信总线（类似于以太网的思路），并且明确模块监听的主题名称。强一致性的RabbitMQ保证了消息的准确送达，并且通过主题名称实现系统中的服务发现，还自带了足够稳健的负载均衡与失败重传。而且，由于模块间的通信队列是固定的，我们可直接使用RabbitMQ的已有功能对消息进行追溯、统计、监控。

虽然都用了消息队列，但FDC与OpenStack在这方面的设计原则是完全不同的。OpenStack弱化消息流转的过程，试图让你忘记你处在分布式的系统中，简化代码调用的同时鼓励了不必要的模块间调用，并且在灾难发生时你不得不面对这层外衣下的真实世界。

2. task flow的支持。异常和灾难对云是常态，但不要让用户感知到。

既然我们没有把MQ仅仅当作是一个更好用的socket，而是对消息流转有了严格的编排，那么框架就能很容易地发现异常发生的时间、模块以及模块返回的具体错误信息，实现task flow的功能。

那么框架同样也可以编排异常发生时的消息流转图。对于大部分模块，只需要它的每个原子接口都有对应的回滚接口，那么回滚的逻辑就很简单了，只需要在当前失败步骤开始，逆序调用所有步骤的回滚接口即可。

我在知乎上发招聘广告的时间，都是这样省出来的。

3. 简洁可靠闭环。『Batteries Included』，拿来就用。

为了有更多发广告的时间，我们还希望项目规模能简洁，不要有太多过早优化；能可靠，代码不多但都经得起考验；能闭环，自带电池直接就发光发热。

『Batteries Included』是Python的一个设计哲学。与外部组件的融合往往会带来大量的适配工作，而且你只需要外部组件的一个功能子集却要维护它整个组件。不能拳拳到肉的做法通常是项目偏离需求的开始。对于很多简单直接的需求，直接用几十行几百行代码来实现，至少比引入几万行代码的依赖要好得多，在你需要的时候也能完备的方法替代电池（如Python有哪些黑魔法？ - 李力的回答）。关于『Batteries Included』与『Don't Repeat』并不冲突的探讨这里就先不深入了。

FDC的task flow是自带的，回滚是自带的，通信接口是自带的，容灾和高可用也是自带的。

4. 模块解耦。逻辑上的解耦胜过形式上的解耦，对模块开发者，尽量减少约束。

每一个程序员都有关于框架的梦想，它的意义在于对使用框架者的约束，约束意味着权力，权力意味着阶级。

框架的开发者们说：快看，我找到解决xx问题的最佳实践，只要你按照我的框架，就能写出跟我一样牛逼的代码。这个思想最早体现在巴别塔建造工程上，也体现在网易评论里：如果全国人民都给我1块钱，我就有13亿了！

嗯，回到云的框架。云的框架和大部分的框架还不一样，它更复杂，更无法预料哪里未来要发生变化，毕竟software define everything，那么越是过早优化越是难以回头，越是限制太多就越容易脱离控制。就像是网络硬件厂商想要接入neturon，工程师为了早点下班，根本就不愿意像OpenStack本身的核心开发一样去理解它的庞大而且精细的类层次和设计，直接找到个入口就把代码全塞进去了。

我想起我第一次写CGI时总是理解不了，CGI代码里没有任何与web server、http相关的东西，它是怎么能被浏览器访问到的呢？

FDC的模块要求类似于CGI，模块本身不需要理解MQ，也不需要理解task flow，也不需要考虑容灾和高可用，这些都完全由框架和RabbitMQ做完了。甚至模块只有一个入口，以回调函数或者可执行文件的方式提供，框架负载输入，模块返回输出即可。模块甚至也不知道自己将会被框架attach进去，这对现有系统的接入和改造的成本也是极低的。

5. 高性能，可平行扩展。至少要支持十万级别的宿主机。

其实这点真的不难，真的。

--------------------

我写这些，并不是想抨击或贬低OpenStack，相反，我自始至终是OpenStack的狂热粉丝。一直以来我们都拿OpenStack的作为参照物，尽量地让我们的系统能吸收更多的养分。

从一开始，我们就参照了nova对libvirt的处理逻辑，RabbitMQ也是最早在nova的架构中看到，这都是我们系统的核心立足点。OpenStack吸引了全世界最优秀的工程师，有很多的具体设计都让人耳目一新，也被我逐渐地学习和在腾讯云中推广开来，比如调度的各种策略、wsgi的filter、依赖倒置的设计模式。而且随着OpenStack的发展，它的部署和运维能力越来越强、容灾和高可用已经不是那么繁琐，与业界主流的sdn和块存储方案紧密贴合，我不禁开始想象，如果是在今天再做一次决策，情况会是怎么样！

另外，OpenStack的野心也比我想象得要太得多，它现在已经不仅再是云的后台系统，而是真正的『软件定义一切』的集合体，在OpenStack Mitaka中，我们看到了大量激动人心的新项目，比如大数据分析模块、容器相关模块、搜索引擎模块，甚至是文件系统、消息队列和域名解析的支持。这些功能与主框架耦合较少、功能独立，倒是可以尝试直接使用，满足一下我这么多年对OpenStack欲求而不可得的愿望。

而最让我激动的是OpenStack的taskflow，让tm不就是我们这么多年心心念念的流程引擎吗？Openstack的taskflow和腾讯云系统中的任务管理十分相似（但显得OpenStack要完备也复杂得多），似乎是我们的系统与OpenStack在精神上又走到了一起。

面对原有系统的动员戡乱，面对OpenStack的钢铁洪流，面对某些系统的自由民主，这是我对公有云计算平台的一些微小的工作。如果说还有什么，那就是用户镜像一律不得侵入

-------------------------------

多年以后，我的鬓角已长起白发，我仍然能记起在那个外面瓢泼大雨，室内却日光灯明媚的下午，我望着领导的背影，吟诵的两句诗：狗……啊不对，是两句论语：

天下有道，丘不与易也

（完）
