五年Skype架构师之路的感言
简介
作为架构师和设计者,我们常把手头的事情作为工作焦点,很少反思过去如何。我们应该温故而知新。我从作为skype架构组领导的55 个月经历中总结了6个经验。其中一些是技术性的,另外一些是架构师较为软性的观点。首先介绍一下Skype的背景资料。
Skype背景
Skype是让用户可以进行音频视频通话的软件,也可以拨打普通电话以及发送短消息。公司成立于2003年,从成立以后就有令人难以置信的成长曲线。公司现在有超过五亿两千万注册用户,大约650名员工。这些用户同时产生平均21万个通话,其中大约三分之一包含视频。这个数字大致上是全世界国际通话的 8%。
不用多加说明也能知道,这个通讯量产生了罕见的扩展性挑战。在Skype一直使用端对端(peer to peer)技术作为处理类似挑战的主要武器。对等网络(核心用C语言实现)主要是由C++编写的服务器端服务及Postgre数据库支持组成,并结合强大的Python脚本。Web服务使用PHP搭建。
技术方面
经验法则不适用
在作为软件工程师的职业生涯中,一些模式会慢慢浮现出来,一些经验规则会显现出来。显然,你愿意无论何时何地都一直使用这些规则。毕竟它们过去都很有效,是不是?
事实证明,即使你有好用的锤子,也不要把身边所有东西都当成钉子。在快速变更的现代科技社会,经验法则不会一直适用。例如,我们看看Skype数据库是如何架构的。
传统智慧说永远不要在数据库里面实现业务逻辑。为何这个说法传播如此广泛?大多数架构师都有类似经验,这会导致原始数据库在硬件方面如巨兽般增长,无法运行,也非常难维护。
这个假冒克苏鲁恐怖神出现的原因是主要数据库平台常常缺乏两个重要而且立等可用的特性:横向划分数据库的能力(比如根据数据实体划分数据)和纵向划分数据库的能力(不同的数据库实体放入不同数据库中)。当然,我们可以自己建立这两种特性,但是数据库管理团队以外的人常常也想处理类似问题。对于DBA来说这是赖以生存的手段而不是用于解决问题的能力。也就是说,对数据库做划分或者队列的技术常常要存在于数据库之外,使得开发者需要自己处理协议转换、多种接口、数据集成等问题。
在Skype,维护数据库的这些人恰巧也是Postgre的重要贡献者。从很早开始他们就拒绝把数据库看成是系统架构角落一个大而无当的罐子,反而以积极地态度去学习技术,解决他们遇到的扩展性、性能及可维护性方面的问题。像你猜想的一样,这些还不够,即使最好的数据库架构也会在轻率地编码中被废掉。幸运的是,Skype数据库管理员从很早开始就掌控了需要进入数据库层的开发工作,在执行了一系列非功能需求、代码实现、同事评审过程来确保实现代码适合数据库层以及其他相关部分的设计之前,Skype的DBA不放弃控制。
图一解释了他们如何使用这些工具建立Skype数据库架构。
这里由四层构成:
- 接入层提供了接入数据库的能力,而且也处理数据库分区问题(pIProxy)和连接池(pgBouncer)。并且让开发者可以透明的使用这些功能。
- 联机事务处理层,是OLTP数据库存在的地方。
- 队列层,负责层与层之间数据库传送数据和复制数据。
- 内部服务器层,包含了用于记录、统计、检视、批处理和ETL目的的数据库。
所有这些都是为了保证数据库可扩展性对于开发者不是问题。我们把必要的业务逻辑尽量贴近数据,让它最有效的工作,也就是"业务逻辑应该远离数据库”的经验法则并不适用。当然会有类似发布、调试以及单元测试之类的困难,但是我们不害怕原始数据库肆虐发威。
图一:数据库层
架构模式也是一样。在工程师之间建立通用技术词汇表、提供验证过的常见技术问题处方是非常重要的事,应该小心对待。Skype的端到端网络就是很好的例子。如果问题以“设计互联网电话”这种方式提出,多数情况下,人们会设计使用SIP来实现要求。但是如果Skype通过基于SIP实现服务就不会给通讯工业带来变化。Skype早期的工程师不愿把自己限制于这件事通常如何完成,而是找到他们能建立的最佳可能方案。
总之,略微不同的组织和技能,就可能有必要建立完全不同的架构模式的应用。你应该随时欢迎这些差异对自己的传统思维挑战。
忽视功能架构吃尽苦头
我们很少有机会在项目初期搭建阶段就作为首席设计师参与工作。大多数工作是修改已有的系统,变更管理就成为架构师工作中很重要的部分。现在我们大多数变更管理关注在技术架构和有效地设计系统,以确保在实现变化以后设计依然有意义。
可惜是这不是故事的全部。
所有技术变化来源于功能上的变化。我们很少仅仅为了重构而修改系统。通常情况下会有一些外部驱动力,需要系统在某些行为上表现得不一样。这可能是市场上有了新产品,也可能是法律变更或者是运营部门的人需要更好的扩展。无论如何,技术变更常常伴随着功能上的变化。
所以我们的系统和流程需要保证技术变化更容易,我们也希望这个管理过程比较有序,对于接手的人来说不是象意大利面条一样杂乱。可是什么是功能性变化?谁来关注系统的功能性以及确保变化不会让系统更混乱?
我用例子来说明一下。
在过去四年一直常常有人强烈要求我修改Skype的网络存储架构,即使我证明每个微小的变化都会伴随痛苦。在互联网上销售四个产品不是什么复杂的事情,大多数时间整个系统就是照常运行,即使有一些问题被发现,紧接着就解决了。
这就是原因。
图2展示所有Skype网络存储的功能组件。大约有200个。图表不是很清晰准确,只想展示整个应用系统的功能性和复杂度。这是不计其数的变化、添加、修改、法律问题、微调造成的结果。所有这些当然是都有事出有因和有价值的。
相当多的架构师没有仔细考量技术变化,结果导致意大利面条般的混乱,应用系统因为不加思考的变化在功能上变得混乱。这不意味着作为软件架构师,我有意从开始就阻止这些问题。但是如果不对系统功能性架构足够小心,就会导致功能架构的支离破碎。结果只能是凌乱的技术架构。
图2:网络存储功能架构
总而言之,应该时刻对你要维护的系统功能保持关注。修改技术架构,也要经常维护功能架构。
简单的事情有效果
简单说,任何需要超过三句话来解释给其他人的事情,都不会实际有效的工作。这就是为何REST可以实际应用而SOAP则做不到,也是为什么人们更喜欢Hibernate而不喜欢J2EE bean的原因。
PgQ[1]就是稍微简化需求会产生挺好结果的例子。对于所有消息系统来说,消息可靠性是主要性能问题之一。为不同客户端标记消息是”已使用“是很让人头疼的,需要存储这些消息而且保证它们不会阻塞还未消费的数据存储。可是当承诺每个消息至少分发一次而不是仅仅一次,这些头疼消失了一大半。这对大多数情况下的客户端应用是可以接受的,只要允许它们自由实现自己需要的校验机制。
简单解决方案的另一个效果是促使你思考,而多思多想总是好的。设计有界面的WSDL是很有趣,但是有多大程度真正关注本质问题,比如在哪些类型哪些对象应该进入其他对象以及你希望是什么样子的?就是如此。
总之,朝着让系统应用更为简单的目标去迎接所有需求、定律以及标准,毫不留情的去掉所有导致系统缓慢的多余脂肪。
非技术角度
危险的流行语
时常会有些人以这样一种“很不错”的方式构建软件:发明一个吸引人的名字,在大家知道底细之前,在PowerPoint上到处描画这个名字。不幸的是,大多数这些想法都非常复杂,很少有实用性。比如J2EE、CORBA、SOA,都不是为了解决日常问题而设计的,它们有时候能起作用,但那是很偶然的。
在Skype,我们曾经多次出现类似问题,也相当成功地处理了它们。尽管我们听说某个组织有非常不同的经历。在某些时候,我们看到不少大型应用开发商最近发现它们的整个工程管理系统被替代了。
某个专家说了这个故事。
管理高层在表面上有一些时间需要处理特定的问题,比如听从某些咨询师告诉他们的建议,定制主要产品和全面进入云计算以及SOA这些决策会帮助他们。所以他们开始跟工程领导者谈话,尽管后者报之以空洞的眼神。就跟呆波特四格漫画画出来的一样,这些不过就是一大泡骗人的万灵油。过了一阵,不可避免的事情发生了,管理层厌倦了像是傻瓜一样被蒙骗(咨询师收费是很昂贵的),当下一步都开始了,还是没人去解决开始时的问题。即使摆脱了那些不胜任且总唱反调的人,这个公司也可能无法恢复元气。
这是架构师的失败,真的。
这个故事展现了架构师责任的二元性:首先是我们需要仔细考虑这些想法,只把实际上有意义的东西放入系统,让系统继续运行。另一方面,我们不能忽略这些常常是无意义的术语,因为真实问题可能就隐藏在后面。不容易找到根源问题的原因是客户的管理层缺少一些我们能理解的词汇来表达需求。
另外,当某个概念跳出来,就好像已经解决了困扰客户很久的问题。他们捡起这根绳子就变得自以为有力量,从而在组织里面大肆使用它。从技术角度回应这些情况(比如宣称整个事情是假的)不能解决运行中碰到的根本问题,也很没有建设性。当领导发现组织有问题并且相信他找到了解决方案,而你拒绝实现这个方案甚至拒绝讨论,你也就出局了。如果你自己不让这些流行语变得有意义,就会有一堆顾问没完没了帮你定义它们。
总而言之,用户很少有意糊弄你,你也不应该糊弄用户。你应该跟用户一起找到并解决真正的问题。因为信赖你,你的总裁会有更好的事情去做,而不是丢一些听了让人发抖的无意义的广告词给你。
架构师需要配合你的组织
大多数人每天工作是为了把事情尽可能做到最好。架构师则是为了建立可无限扩展及模块化的伟大系统架构而工作。
实际这不是付钱让我们做的事情。
每个系统都存在特定的上下文环境。这个环境包括已有技术系统,也包括技能、态度和人们处理问题的企业文化。甚至更为重要的是,所有系统存在于特定商业环境中。初创企业与巨型电信运营商是不一样的,银行与政府机关是不一样的。很显然,没有一个好的或优美的架构能适合不同商业和组织结构的变化。架构需要适应组织,帮助他们达到目标(或者没有达到)。这往往意味着需要压抑自己建立优美系统的渴望,因为通常情况下你所认为优美的系统和组织需要是两回事。
现实就是,把技术负债[2]的概念放在一边,不要带着债务去工作。可能技术上不十分先进,也没有非常完美,但是能很好帮助你的组织。
在Skype的环境中,这一直是个很重要的问题。我们大量用户使用的主要服务由对等网络提供。对等网络是非常漂亮的东西,但不一定是所谓的“干净“或”简单“。对于拥有传统web应用背景的人来说端对端是非常可笑的。搭建、维护、调试、上线、测试和解释这事是比较困难的,特别是在这个量级上,我们是唯一运营对等网络的公司。而且,总有咨询师施加压力要我们回退到象其他人一样基于服务器的架构。
从技术角度来说,这个压力可以理解,而且有一堆原因说明做这种切换是合理的。当看到这个改变可能影响到我们的业务模型的时候,决定就变得困难。例如,我们的用户在视频通话流量上同YouTube的视频流量是同一数量级。由于使用了端对端架构,Skype并没有在硬件上大量投入。对端对端架构的更改很大几率上意味着免费视频电话服务的结束,也就意味着没有补贴费形式的商业模式的结束。因此,无论我如何考量和是否喜欢使用端对端架构,它都会在比较中占上风。
总之,所有你架构方面的决定都需要根据组织所处环境而不是个人喜好来制定。
沟通很重要
我们前面看到过,如何制定架构需要根据业务功能而定。因为系统架构正确与否决定了业务功能正确与否,很合理的得出结论:人们对系统架构很感兴趣,是因为商业利益的缘故。但是系着粉丝巾的市民如何了解开发者发现的错综复杂的系统,以及软件工程师如何能找到业务功能?
答案极为简单,就是沟通。两方面都需要伸手跨过文化阻隔开始交谈。架构师的工作是把业务策略翻译成技术。这正意味着沟通。
这非常不容易,要知道获得管理层的尊重是很困难的。但是如果没有彼此尊重和沟通,工程师只能忍受武断的技术决定,业务也不得不同限制其发展的系统打交道。如果没有沟通,也就没有理解,更谈不上合作。
图三:架构师组织
沟通对于架构的另一个很明显用户,也就是开发者也是很重要的。如果没有开发者尽善尽美的实现,架构就不能变成服务用户的实际代码,也就无法为业务产生价值。再重复一次,信任与互相尊重是很关键的。
图三展示了skype架构师的一般组织图,没有必须的团队或者汇报层次界定,就是非常简单的关联模型。中心部分是架构师组,主要维护关系和制定通用方向。业务部门架构师(称为解决方案架构师,非常类似分析师的角色)和开发组架构师(称为技术架构师)对他们作补充。前者负责帮助业务部门把想法整理成为技术可行的形式,以及提供解释技术合理与否的反馈。后者负责监督开发及细化架构师提供的高层设计。
这个架构师组织在不同利益关系方提供了足够的组织结构和协调,同时还有一定的自由度。当然,你需要找到适合你们组织的模型,无论解决方案如何,都需要促进你的架构师与重要客户之间的沟通。
总而言之,与人交流!
结论
像你看到的,这些年的经验教会我很多。如果你感觉熟悉和琐碎,你可能已经有过类似经验了。希望能比我经历过的好一些。总结一下架构师需要在这个时间和年龄达到成功的两个主要领悟:
- 无论你过去工作如何,比如为Facebook或者Skype这样的巨头工作,或者曾经跟你本地的CIO社区聊过天,应该只作为帮助你们组织找到解决方案的起点,不多,也不少。
- 技术技能是架构师的必备条件。你需要有技术技能来获取这个职位,但是情商和理解组织业务的能力才定义了你有多优秀。
References
[1] “Skytools page at pgfounry.”
[2] M. Fowler,“Technical debt,” August 2004. 12