Medium开发团队谈架构设计

标签: medium 开发 团队 | 发表时间:2016-02-21 09:15 | 作者:
出处:http://kb.cnblogs.com/

   背景

  说到底,Medium是个社交网络,人们可以在这里分享有意思的故事和想法。据统计,目前累积的用户阅读时间已经超过14亿分钟,合两千六百年。

  我们支持着每个月两千五百万的读者以及每周数以万计的文章发布。我们不想Medium的文章以阅读量为成功的依据,而是观点取胜。在Medium,文章的观点比作者的名头更重要。在这里,对话促进想法,并且很看重文字的力量。

  我是Medium开发团队的负责人,此前在Google工作,负责开发Google+和Gmail,还创立了Closure项目。业余时间我喜欢滑雪跳伞和丛林冒险。

   团队介绍

  说起团队我非常自豪,这是一群富有好奇心而且想法丰富的天才,大家凑到一块是想做大事的。

  团队以跨功能的任务驱动,这样每个人既可以专攻,又可以毫无压力的对整个架构有所贡献。我们的理念就是接触的方面越多,对团队的锻炼越大。更多关于团队的理念 见此

  在工作组织方面,我们有着很大的自由度,当然作为一个公司组成,我们还是有季度目标的,并且鼓励敏捷开发模式。我们使用GitHub进行code review和问题跟踪,用Google Apps作为邮件、文档和表单系统。跟很多团队习惯使用Trello不同,我们是Slack和slack机器人的重度用户。

   原始架构

  最开始的时候,Medium部署在EC2上,用Node.js实现,后来公测的时候迁移到了 DynamoDB

  其中有个节点用来处理图片,负责将复杂的处理工作转向 GraphicsMagick。还有一个节点用作后台的 SQS队列处理。

  我们用 SES处理邮件, S3做静态元素服务器, CloudFront做CDN, nginx作为反向代理, Datadog用来监控, Pagerduty用来告警。

  在线编辑器用了TinyMCE。上线之前我们已经开始使用 Closure编译器以及部分的 Closure库,但是模板还是用的 Handlebars

   当前架构

  虽然Medium表面看起来很简单,但是了解其后台的复杂性后,你会大吃一惊。有人会说,这就是个博客啊,用Rails之类的一周就能搞定了。

  总之,闲话不多说,我们自底向上介绍以后再做判断。

   运行环境

  Medium目前运行在 Amazon虚拟私有云,使用 Ansible做系统管理,它支持配置文件模式,我们将文件纳入代码版本管理,这样就可以随时回滚随时掌控。

  Medium的后台是个面向服务的架构,运行了大概二十几个产品服务。划分服务的依据取决于这部分功能的独立性,以及对资源的使用特性。

  Medium的主体仍然是Node.js完成,方便前端和后端的代码共享,主要是文章编辑和发布这个过程。Node大部分时候不错,但阻塞event循环的时候会有性能问题。为了缓解,我们在每台机器上启动多个Node实例,将对性能要求比较高的任务分配给专门的实例。同时我们还深入V8运行时环境查看更加细节的耗时,基本上是JSON去串行化的时候的对象具体化耗时较多。

  我们还用Go语言做了一些辅助服务。因为Go非常容易编译打包和发布。相比Java语言的冗长罗嗦和虚拟机,Go语言在类型安全方面做的很到位。就个人习惯来讲,我比较喜欢在团队内部推广强类型语言,因为这类语言能够提高项目的清晰度,不纠结。

  目前静态元素大部分是通过CloudFlare提供的,还有5%通过Fastly,5%通过CloudFront,这么做是为了让两者的缓存得到更新,用于一些紧急的情况。最近我们在应用流量上也使用了CloudFlare,当时主要是为了防止DDOS攻击,但随之而来的性能提升也是我们愿意看到的。

  我们使用Nginx和 HAProxy做反向代理和负载均衡,来满足我们所需功能的维恩图。

  我们仍然使用 Datadog来监控, Pagerduty来告警。现在又增加了ELK( ElasticsearchLogstashKibana)来进行产品问题调试。

   数据库

  DynamoDB仍然是我们的主力数据库,但是用起来也不是毫无问题。目前遇到的比较棘手的是大V用户展开和虚拟event过程中的 热键问题。我们专门在数据库前面做了一个Redis缓存集群,来缓解这些问题。到底为开发者优化还是为产品稳定性优化的问题通常会引发争执,我们也一直在尝试中和两者的矛盾。

  目前我们开始在存储新数据上使用 Amazon Aurora,它可以提供更灵活的查询和过滤功能。

  我们使用 Neo4J存储Medium网络中实体之间的关系,运行在有两个副本的主节点上。用户、文章、标签和收藏都属于图中的节点。边则是在实体创建和用户进行推荐高亮等动作时生成。我们通过在图中游走来过滤和推荐文章。

   数据平台

  早期我们对数据非常渴望,不断尝试数据分析框架来辅助商业和产品决策。最近我们则是利用同样的框架来反馈产品系统,支持Explore等数据驱动功能。

  我们采用 Amazon Redshift作为数据仓库,为生产工具提供可变存储和处理系统。我们持续将诸如用户和文章等核心数据从Dynamo导入Redshift,还将诸如文章被浏览被滚动等event日志从S3导入Redshift。

  任务通过一个内部调度和监控工具Conduit调度。我们用了一个基于断言的调度模型,只有条件满足的时候,任务才会执行。从产品角度来讲,这是不可或缺的:数据制造方应该与数据消费方隔离,还要简化配置,保持系统的可预见和可调试性。

  Redshift的SQL检索目前运行不错,但我们时不时需要读取和存储数据,所以后期增加了 Apache Spark作为ETL,Spark具有很好的灵活性和扩展能力。随着产品的推进,估计后面Spark会成为我们数据流水线的主要工具。

  我们使用 Protocol Buffers作为schema来确保分布式系统的各层次间保持同步,包括移动应用、web服务和数据仓库等。通过定制化的选项,我们将schema标记上更加细化的配置,如带有表名和索引,以及长度等校验约束。

  用户也需要保持同步,这样移动端和网页端就可以保持日志的一致性了,同时方便产品科学家们用同样的方式解析字段。我们帮助项目成员从.proto文件中生成消息、字段和文档等内容,进而利用所得数据开展研究。

   图片服务器

  我们的图片服务器现在用Go语言实现,采用瀑布型策略来提供处理过的图片。服务器使用 groupcache,是memcahce的替代品,可以帮助减轻服务器之间的重复工作。而内存级缓存则是用了一个S3的持续缓存。图片的处理是请求来触发的。这给了我们的架构设计师灵活改变图片展示的自由度,为不同平台优化,而且避免了大量的生成不同尺寸图片的操作。

  目前Medium对图片主要支持放缩和裁剪,但原始版本中还支持颜色清洗和锐化等操作。处理动图很痛苦,具体后续可以写一篇文章来解释。

   文本标注

  文本标注是个有意思的功能,用了一个小型Go服务器,跟 PhantomJS接口形成渲染进程。

  我一直想要把渲染进程换到Pango,但是在实践过程中,能在HTML中摆放图片的能力的确更灵活。而从功能的使用频率来看,这意味着更容易开发和管控。

   自定义域名

  我们允许用户为其Medium文章设置个性化域名。我们想做成单点登录且HTTPS全覆盖,因此实现起来颇有难度。我们专门准备了一批HAProxy服务器用来管理证书,并向主要应用服务器引导流量。初始化一个域的时候需要一些手动的工作,但是通过与Namecheap的定制化整合,我们将其大部分转换为自动化。证书验证和发布链接由专门服务负责。

   网站前端

  网页端这块,我们有自主研发的单网页应用框架,使用Closure标准库。我们使用Closure模板渲染客户端和服务端,然后使用Closure编译器来缩减代码并划分模块。编辑器是我们网页端应用最复杂的部分,具体参见 Nick此前的文章。

   iOS

  我们的两个应用都是原生的,尽量避免使用网页视图。

  在iOS上,我们使用了一系列的自建框架,以及系统原生组件。在网络层,我们用NSURLSession发起请求,用Mantle解析JSON并映射到模型。我们还有一层基于NSKeyedArchiver的缓冲层。对于将条目渲染为共同主题的列表,我们有一个通用方法,这让我们能够快速为不同类型的内容构建新列表。文章界面是一个定制布局的UICollectionView。我们使用共享组件来渲染全文界面和预览界面。

  应用代码的每一次提交都会编译后推送给Medium员工,这样我们能够很快尝试新版本。应用商店的版本是滞后于新版本的,但我们也一直在尝试更快的发布,虽然可能仅仅是几处小更新。

  对于测试,我们使用XCTest和OCMock。

   Android

  在Android方面,我们与当前的SDK和支持库版本保持一致。我们并没有使用任何复杂的框架,而是倾向于为重复出现的问题构建持续性的模式。我们利用 guava弥补Java中所有的缺失。另一方面来讲,我们也倾向于使用第三方库来解决特别的问题。我们还利用protocol buffers定义了API,用以生成应用中的对象。

  我们利用 mockitorobolectric。我们会开发一些高层测试来运转activity和poke:刚添加screen或要重构的时候,先创建一些基本的版本,随着我们复现bug它们也会进化。我们还会开发一些底层测试,来检测一个特定的类:随着新功能的增加我们会创建测试,这能够帮助我们思考和设计底层是如何交互的。

  每个提交都会作为alpha版本自动推送到play商店,然后到Medium员工(包括我们的Hatch,Medium内部版)。推送大部分发生在周五,我们会把alpha版本发送给 测试小组,请他们用整个周末进行测试。然后,周一我们会从beta版推进至正式产品版。因为最近一批代码总是随时可以推送,因此一旦发现很严重的bug,我们就可以立即修复正式产品版。当我们怀疑某些新功能的时候,可以给测试小组更长的时间。开发比较亢奋的时候,也可能发布地更加频繁。

   AB测试及其他

  我们所有的客户端都用了服务器端提供的功能标记,称为 variants,用于AB测试以及指导未完成功能的开发。

  剩下还有一些框架相关的内容我没有提及: Algolia让我们在搜索相关功能上快速迭代, SendGrid处理邮件, Urban Airship用来发送提醒, SQS用来处理队列, Bloomd用作布隆过滤器, PubSubHubbubSuperfeedr用作提供RSS等等。

   编译、测试和部署

  我们积极拥抱持续集成技术,随时随地准备发布,使用 Jenkins来负责相关事宜。

  我们曾经使用Make作为编译系统,但是后来迁移到 Pants

  测试方面我们采用单元测试和HTTP层面功能测试两者结合的方式。所有提交的代码都需要通过测试才能够合并。我们跟Box团队合作,利用 Cluster Runner来分布式运行测试,保证效率,而且能够和GitHub很好的整合在一起。

  我们大概不到15分钟就可以把某阶段的系统部署,顺利编译通过,留作正式产品的备选。主应用服务器通常一天要部署五次,多的时候十次。

  我们采用蓝绿部署。正式产品版本的流量发送给一个canary实例,发布进程会监控部署过程的错误率,必要时候通过调整内部DNS回滚。

   面向未来

  到此,讲了足够多的干货!为了重构产品,获得更好的阅读体验,还有很长的路要走。我们仍然在努力为作者和发布者设计更多的功能。打比方来讲,线上阅读还是一片绿地,面对它有着无限可能,我们始终抱着开放的心态设计和实现功能。未来我们会努力用各种功能为用户提供高质量内容和价值。

相关 [medium 开发 团队] 推荐:

Medium开发团队谈架构设计

- - 博客园_知识库
  说到底,Medium是个社交网络,人们可以在这里分享有意思的故事和想法. 据统计,目前累积的用户阅读时间已经超过14亿分钟,合两千六百年.   我们支持着每个月两千五百万的读者以及每周数以万计的文章发布. 我们不想Medium的文章以阅读量为成功的依据,而是观点取胜. 在Medium,文章的观点比作者的名头更重要.

Medium如何在手机上复制网页版的阅读体验?

- - PingWest中文网
Medium创始人Ev Williams在发布Medium iOS版时,写了一篇题为 <. Welcome to Medium for iPhone> 的文章,讲述他对移动版Medium的想法. 总的来说,Ev Williams表达的是:Medium注重设计,在移动端做Medium所面对的挑战和付出的精力比网页版多,Medium网页版暂时不支持写文章.

软件开发团队主管易犯的十个错误

- Frank Cai - 36氪
本文是Roy Osherove在Skills Matter的一次发言,他介绍了团队领导经常会犯的十个错误,并提出了一些解决方案. Roy首先提出几个团队领袖可能遇到的一些问题:. 我如何说服的我团队做某件事情. 我该拿团队里的那个专门搞事的家伙怎么办?. 我们为什么无法远离无谓的争吵呢?. 他说这些问题其实缠绕他多年,接下来他也逐一做出解答.

Windows 8 VS Windows 7:开发团队对比

- 洞箫 - cnBeta.COM
微软已经公布Windows 8系统的35个开发团队,我们不妨对比一下Windows 7系统的25个开发团队,看其中有何变化. 微软Windows/Windows Live部门总裁史蒂文・辛诺夫斯基(Steve Sinofsky)在博客中表示,Windows 8的每个团队有25-40名开发人员.

Sony Ericsson 将提供手机协助 FreeXperia 团队开发 CyanogenMod 7.1

- NOir - Engadget 中国版
看来 Sony Ericsson 似乎终于理解,Android 并非是个可轻易套用于所有设备的系统. 而在 FreeXperia 团队努力不懈的将 CyanogenMod 7.1 带到 SE 设备上时,该公司也注意到了此团队所展现的惊人实力,打算提供此开发计划实质支持(想必是受到 Samsung 的启发吧 XD).

我在谷歌管理一个开发团队

- - 博客园_新闻
上图为本文的作者:Matt Welsh. 英文原文: Running a software team at Google. 自从我离开哈佛后,经常有人问我现在在谷歌工作是什么样的情况. 我猜想很多人会认为从一个终身教授到一个软件工程师的转变存在很大的身份落差. 但除了这个头衔外,我工作的还是很高兴的,而且在这个新角色上,我的工作效率比以前在哈佛任教的 8 年中的任何时候都高——尽管当一名教授和管理一个开发团队在很多方面都有非常相似的地方.

打造最佳开发团队的几点建议-转载

- - 人月神话的BLOG
原文: http://www.csdn.net/article/2013-03-21/2814583-the-best-developer-team-structure. 在灭火时,有一种“水桶阵型”——队伍中所有人排成一列或几列,将水桶从水源处传递到火灾现场. 这样在团队协作时甚至不需要语言交流,但显然不适用于软件开发.

Twitter创始人分享创业团队开发经验

- - InfoQ cn
Twitter、Blogger的创始人之一Evan Williams最近把精力放在了线上出版平台Medium上,经过八个月的准备,目前Medium初具雏形. Evan Williams也分享了在此过程中的 开发经验. 他认为“团队太大会放慢你前进的脚步”:. 在Medium初期,我们有能力招聘优秀的工程和设计团队.

谈谈产品开发团队的配置管理规则

- - CSDN博客研发管理推荐文章
作者:张克强    作者微博: 张克强-敏捷307. 在《 源代码管理的新15条建议 》中的第7条建议提到:每个团队应当对代码配置项和非配置项有所说明,不要假设每个团队新人都是代码配置管理达人,小心自以为是的新手加入一些自以为是的垃圾. 虽然可以删除,但发现再删除,其本身就是成本. 在《 高效组织的配置管理计划》也提到了产品线层面的配置管理,那么产品开发团队的配置管理到底应该是什么样呢.