BuzzFeed如何从Perl单体应用迁移到Go和Python微服务
\
本文要点
\\
- BuzzFeed近日从一个单体Perl应用程序迁移到了大约500个使用Python和Go编写的微服务。\\t
- 起初,他们的路由逻辑是在CDN中实现的,但事实证明,这很难测试和维护。他们后来改成使用NGINX路由。\\t
- 网站路由服务被设计成在BuzzFeed自己的Rig平台上运行,这便于他们部署到他们运行的每一个Amazon弹性容器服务环境(ECS)(测试、过渡、生产)中的每个服务上。\\t
- BuzzFeed构建了一个抽象层,让他们可以使用YAML配置路由服务。\
\\
2016年,BuzzFeed启动了一个重构项目,把使用Perl编写的一个单体应用程序转换成一组微服务。他们之所以这样做,主要是因为Perl应用程序被证明很难扩展,使buzzfeed.com独自服务于每月大约70亿次页面访问,而且,组织还要向大约30个不同的社交平台发布内容,包括不同的语言版本。
\\
除了扩展问题外,BuzzFeed发现,寻找懂Perl并且希望使用它开发的工程师越来越难。最后,他们希望自己能够在有了新产品想法时可以更快速地迭代。
\\
从一个很高的层面上来说,新架构包含一个CDN,指向一个路由服务,该服务位于AWS上,使用了ECS容器化服务:
\\
\\
新的微服务是以Python作为主要语言开发的,对于性能比较敏感的组件则使用了Go。BuzzFeed的工程团队发现,这两种语言可以很好地互补,对于开发人员而言,根据需要从一种切换到另一种也相对简单。
\\
在本文写作时,他们在AWS上的过渡环境和生产环境中已经有大约500个微服务。他们在分解服务时使用了听上去和SCS类似的东西;buzzfeed.com的首页是一个服务,新页面是单独的服务,作者页面也是,诸如此类。
\\
团队面临的一项挑战是把请求路由到正确的后台应用程序。他们的CDN提供商Fastly具有在边缘通过编程定义行为逻辑的能力,使用的是一种基于C的编程语言VCL,工程团队最初就是直接使用VCL编写他们所有的路由逻辑。
\\
不过,他们发现,随着配置越来越复杂,修改变得越来越困难,充分测试这些配置的能力愈发重要。BuzzFeed资深软件工程师Mark McDonnell告诉InfoQ:
\\
\
我们在CDN中有大量的逻辑,只有少数几名工程师真正了解它是如何工作的。另外,CDN还被有意锁定,因为缓存层对我们而言特别重要,我们需要防止工程师意外修改,那可能会对我们的缓存策略产生不利影响,或者会导致进入的请求被路由到错误的源服务器。
\
\\
此外,Fastly还有自己的Varnish HTTP加速器实现。BuzzFeed发现,这让工程师很难启用一个本地开发环境,并通过它运行他们的VCL逻辑,因此,VCL代码测试就成了问题。为此,工程团队决定实现一个新的路由服务来代替VCL路由,把大部分路由逻辑从CDN提取到一个单独的路由器微服务中。
\\
网站路由服务被设计成在BuzzFeed自己的Rig平台上运行,这便于他们部署到他们运行的每一个Amazon弹性容器服务环境(ECS)(测试、过渡、生产)中的每个服务上。
\\
对于反向代理,他们考虑了包括HAProxy在内的多个选项,但最终决定使用NGINX。McDonnell 说,“我们选择NGINX,因为我们平台基础设施团队中的大部分人都有使用经验,所以,我们得到了SRE的支持,我们其中的一个卖点是,它很容易提升速度”。如你所想,向系统添加NGINX确实会给单个请求带来额外的延迟,但按照McDonnell的说法,这可以“忽略不计”。
\\
虽然把简单易用和熟悉度作为选择NGINX的其中两个原因,但BuzzFeed还是构建了一个配置该服务的抽象层。该服务是用Python编写的,它会从YAML动态生成所需的nginx.conf文件。它广泛使用了YAML特有的特性,如“锚和别名(Anchors and Aliases)”和“合并键(Merge Key)”,据BuzzFeed技术博客介绍,“这让我们可以跨环境块重用配置,而且很容覆盖特定的键,不需要重复大量的配置工作。我们主要把这种方法用于‘上游’和‘超时’区域,因为我们通常会希望覆盖那些特定于环境的值。”
\\
起初,路由服务是使用NGINX的开源版本构建的,但后来转到了商业版本NGINX Plus。按照McDonnell的说法,可以获得付费支持是一个原因,但团队也需要只有付费版本中才有的某些特性,尤其是DNS监控;BuzzFeed的服务器区域相当复杂,那样,当AWS负载均衡改变IP地址时,NGINX Plus能够保证DNS条目也更新。BuzzFeed技术博客上有一篇博文是这样解释的:
\\
\
在NGINX启动的时候,它会为我们在配置文件中定义的下游解析DNS。也就是说,它会把主机名转换成IP(或者一组IP,和使用AWS Elastic负载均衡器一样)。然后,NGINX会缓存这些IP,我们的问题在这里开始出现了。
\\
你可能不熟悉负载均衡器,它们会检查多个服务器,看看它们是否健康,如果不健康,服务器会被关闭,并有一个新实例启动。我们发现的问题是,每个服务器实例的IP都在不断变化。如前所述,NGINX在启动时会缓存IP,而因为ELB[Elastic负载均衡器]的原因,新进来的请求会被代理到不再有效的缓存IP。
\\
一种解决方案是热重载NGINX配置。那是个手动过程,我们不知道什么时候该那样做,因为我们无法知道服务器实例何时会停止服务。
\\
NGINX文档中有几个设法变通解决这个问题的选项;不过,除了一个选项外,其他所有选项都意味着我们需要重新设计我们的整个架构,因为它们不支持NGINX的upstream指令(作为配置抽象的一部分,我们对它的依赖度很高)。
\\
允许我们利用接口设计的那个解决方案只有NGINX Plus提供。采用商业版本的成本是合理的:我们不需要从头重写我们的整个服务,后续我们也可以利用额外的特性(其中有一部分我们已经考虑过)。一旦切换,该解决方案只需要增加一行resolver指令,为缓存的DNS解析结果定义一个TTL。
\
\\
VCL逻辑用于帮助BuzzFeed在他们推出新服务时根据用户的地理位置分类用户,那样,他们就可以从一个类似新西兰这样的小国家开始。McDonnell解释说:
\\
\
对于任何geoip.country_code是NZ的用户,他们会设置一个X-BF-SiteRouter头。然后,在VCL代码中,如果X-BF-SiteRouter头已经设置(取决于请求哪个路由),我们会把后端切换到Site Router。
\\
一旦我们满意,我们就会把服务区域扩展到AU、GB、OC、EU、SA(南美),最终,我们会把所有东西都指向Site Router(实际上,北美是最后一个区域)。
\\
我们还使用了Vary头保证来自不同区域、还没准备好访问Site Router的用户不会意外从中获得缓存的响应。
\
\\
迁移到新架构已经在团队生产率方面为我们带来了益处,McDonnell告诉我们:
\\
\
工程师可以根据自己的意愿自由启动服务,我们每天部署很多次。周遭有各种流行的术语,如持续集成、持续交付和持续部署,它们只有稍微的不同。最终,我们有了一个非常棒的交付管道,但是,我们特有的平台实现无法自动把变更推送到生产环境,目前我们还得手动选择,那对于我们的应用场景而言是合理的(例如,并不是我们构建的所有东西都必须自动存在于生产环境中)。
\
\\
BuzzFeed有一个富A/B系统,用于测试单个的“特性”,规模较大的基于A/B测试的上线在他们的方法中反而变得比较简单(综合运用VCL逻辑和Site Router特有的“override”配置来处理请求路由)。
\\
新基础设施监控(以及日志聚合和分析)是使用DataDog实现的。他们还在评估Honeycomb.io。
\\
关于作者
\\
Charles Humble 于2014年3月成为InfoQ.com编辑团队负责人,指导我们的内容创作,包括新闻、文章、著作、视频演讲和采访。在承担InfoQ的这个全职角色之前,Charles负责我们的Java报道,并且是薪酬研究公司PRPi Consulting的CTO,该公司2012年7月被PwC收购。他已经从事企业级软件工作将近20年,做过开发,当过架构师和开发经理。在业余时间,他从事音乐创作,是伦敦氛围科技舞曲团Twofish的三名成员之一。
\\
查看英文原文:How BuzzFeed Migrated from a Perl Monolith to Go and Python Microservices
BuzzFeed如何从Perl单体应用迁移到Go和Python微服务相关推荐
- MVC设计模式、单体架构、前后端分离、微服务
萌新程序员在学习web开发时一定对单体架构.前后端分离架构.MVC.微服务这几个名词不陌生,想要搞清它们之间的关系,但互联网的信息分散杂乱,有些文章之间甚至还互相冲突. 我也迷迷糊糊,但本着刨根问底的 ...
- 单体、集群、分布式、微服务概念理解
单体: 单独的一个项目,所有的模块都会写在一个项目中,并且单独部署在一台服务器上,这就是一个最简单的单体架构的一个模型 集群: 单机处理到达瓶颈的时候,把单机复制几份,分别部署在多台服务器上,集群中每 ...
- 微服务系列(七):将单体应用改造为微服务
编者的话|本文来自 Nginx 官方博客,是「Chris Richardson 微服务」系列的第五篇文章.第一篇文章介绍了微服务架构模式,并且讨论了使用微服务的优缺点:第二和第三篇描述了微服务架构模块 ...
- 单体系统如何拆分为微服务
当单体系统越来越大,并难于维护时,很多企业开始有意把单体系统拆分为微服务风格架构.这么做很有意义,但不容易.要做好这件事情我们必须学习,我们从一个简单的服务开始,另一方面拉出以垂直功能为基础的服务,这 ...
- 分布式与微服务——Iaas,Paas和Saas、单体应用和缺点、微服务概念、传统 分布式 SOA 架构与微服务架构的区别、微服务实战、什么是RPC、CAP定理和BASE理论、唯一ID生成、实现分布式
文章目录 1-什么是Iaas,Paas和Saas 一 IaaS基础设施服务 二 paas平台即服务 三saas软件即服务 四 总结 2-单体应用和缺点 一 单体应用 二 单体应用的缺陷 3-微服务概念 ...
- 单体架构-->SOA架构-->微服务架构
上诉架构图采用了分层架构,按照调用顺序,从上到下为表示层.业务层.数据访问(DAO)层.DB层.表示层负责用户体验,业务层负责业务逻辑,包括电影.订单和用户三个模块.数据访问层负责DB层的数据存取,实 ...
- 走出微服务误区:避免从单体到分布式单体
最近社区频繁出现的对微服务的各种质疑和反思的声音,甚至放弃微服务回归单体.本文从"分布式单体"问题出发,介绍通过引入非侵入式方案和引入Event/EDA 来走出微服务实践误区:从单 ...
- 如何拆分大型单体系统为微服务
单体系统如何拆分为微服务 购物优惠券 https://www.cqfenfa.com/ 当单体系统越来越大,并难于维护时,很多企业开始有意把单体系统拆分为微服务风格架构.这么做很有意义,但不容易.要做 ...
- 我们最终还是放弃迁移到微服务,为什么?
点击上方"后端技术精选",选择"置顶公众号" 技术文章第一时间送达! 经过一个月的准备和调查,我们取消了迁移,仍然使用单体模式.对我们而言,微服务不仅帮不上忙, ...
- jboss4 迁移_JBoss BPM Travel Agency的微服务迁移故事
jboss4 迁移 不久前,我们启动了一个规模较大的JBoss Travel Agency演示项目,以展示JBoss BPM Suite的一些更有趣的功能. 我们提供了一系列视频 ,不仅向您展示了如何 ...
最新文章
- 大数据竞赛平台——Kaggle 入门篇
- Servlet Listener
- Flutter开发者必备手册 Flutter Go
- PHP基础入门(五)---PHP面向对象实用基础知识
- 2019届宝鸡理数质检Ⅰ解析版
- Android之解决多语言适配部分TextView内容左对齐和内容一行不排满就到第二行问题
- Codeforces Round #655 (Div. 2) E. Omkar and Last Floor 区间dp + 巧妙的状态设计
- 如果有一天生你养你的两个人都走了
- SparkStreaming - 自定义数据源(自定义采集器)
- 核心期刊投稿经验(遥感信息)
- 最近在做中文的全文检索(中文搜索引擎)
- resin 配置java_resin安装与配置
- 联想拯救者2020 Y7000安装Ubuntu16.04
- c语言int doubt,c语言错误error: incompatible types in assignment
- 教你如何用PS轻松制作ico图标
- Matplotlib填充色Colormap
- php 2010excel,Excel2010 工作薄文件扩展名是什么?
- Linux常见面试题,一网打尽!
- PMP知识点(十、采购管理)
- 域对抗(域适应)训练
热门文章
- BaseAdapter的逗逼、普通、文艺写法
- Oracle PL\SQL 基础学习一
- Error creating object Microsoft Data Access Components 2.1 (or later) have been properly installed
- [导入]使用ASP.NET AJAX的注意事项
- (十二)random模块
- 2018.09.23 bzoj1076: [SCOI2008]奖励关(期望+状压dp)
- Spring Security 入门(1-4-1)Spring Security - 认证过程
- 6个强大的AngularJS扩展应用
- 移植 Qt4.8.5到Tiny210
- Android下异步扫描视频文件缩略图