Postman如何处理庞大难以管理的网关服务

{"type":"doc","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"italic"},{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"来自Postman的服务基础(Server Foundation)团队关于Bifrost websocket网关的真实故事的分享。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"在漫威电影宇宙中,Bifrost是彩虹桥的名字,它可以在神界和人界之间进行瞬间旅行。类似地,我们的Bifrost websocket网关也同样神奇地让Postman客户端即时连接到Postman服务。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/0c\/0cc59a8d52850c78a1b629dd3d2aaf7e.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":"center","origin":null},"content":[{"type":"text","marks":[{"type":"italic"},{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"照片由 "},{"type":"link","attrs":{"href":"https:\/\/unsplash.com\/@trfotos?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText","title":null,"type":null},"content":[{"type":"text","marks":[{"type":"italic"}],"text":"Toni Reed "}],"marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}]},{"type":"text","marks":[{"type":"italic"},{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"拍摄"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"正如我之前在"},{"type":"link","attrs":{"href":"https:\/\/medium.com\/better-practices\/how-postman-engineering-does-microservices-aa026a3d682d","title":null,"type":null},"content":[{"type":"text","text":"Postman如何"}],"marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}]},{"type":"link","attrs":{"href":"https:\/\/medium.com\/better-practices\/how-postman-engineering-does-microservices-aa026a3d682d","title":null,"type":null},"content":[{"type":"text","text":"实现"}],"marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}]},{"type":"link","attrs":{"href":"https:\/\/medium.com\/better-practices\/how-postman-engineering-does-microservices-aa026a3d682d","title":null,"type":null},"content":[{"type":"text","text":"微服务"}],"marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"中所分享的那样,所有的软件架构都是一个持续进行的工作。在实际执行中意味着需要偶尔重新评估旧的思维方式以适应新的情形,这是软件设计的自然演化。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"下面是一个关于Postman的工程师们如何通过精简一个增长过大的服务来开发Bifrost websocket网关的故事。"}]},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"Postman公司的开发团队"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"Postman公司的大多数开发团队都在跨职能部门工作,专注於单一的核心领域,比如文档或"},{"type":"link","attrs":{"href":"https:\/\/learning.postman.com\/docs\/collaborating-in-postman\/version-control-for-collections\/","title":null,"type":null},"content":[{"type":"text","text":"版本控制"}],"marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"。每个小队都遵循"},{"type":"link","attrs":{"href":"https:\/\/en.wikipedia.org\/wiki\/Domain-driven_design","title":null,"type":null},"content":[{"type":"text","text":"领域驱动设计"}],"marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"的原则,为Postman用户开发内部微服务和产品功能。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"虽然大多数工程师都是以小组形式工作,但有些工程师以功能团队形式工作,这些功能团队构建用于整个工程组织共享的组件。服务基础团队就是一个Postman功能团队的例子。这些工程师创造了工具,其他小组用这些工具来构建、交付和观察自己的特性。这个团队也是AWS专家和基础设施专家们的集中地。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/6a\/6a94c7d71a9168a7df6a3e7e9f4b9f55.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"italic"},{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"服务基础团队是一个Postman功能团队的例子,他们创建和管理供整个工程组织使用的东西"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"Postman的大多数微服务都是松耦合的,因此它们可以独立于其他团队进行发展。不幸的是,服务有时候可能会变得太大,提供一些看似毫不相关的服务。这些服务让团队能够快速迭代,但可能开始表现得更像一个臃肿的庞然大物、一个大泥团或是某种笨重的生物。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"当这种情况在Postman出现时,来自不同团队的很多工程师们都会贡献代码,针对每个修改都需要非常仔细的跨团队协作。"}]},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"单体Sync服务"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"其中一个Postman服务变得过于庞大而难以有效管理,这个服务叫做Sync。它具有令人生畏的任务,与Postman服务器同步您本地计算机上的Postman客户端的所有活动。Postman中的每个用户操作,都会通过websocket连接来触发一系列的API调用,并遵循"},{"type":"link","attrs":{"href":"https:\/\/en.wikipedia.org\/wiki\/Publish%E2%80%93subscribe_pattern","title":null,"type":null},"content":[{"type":"text","text":"发布-订阅模式"}],"marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":",使得这些信息可以在用户及团队之间实时流动。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"例如,当你登录到Postman并更新一个集合时会发生以下情况:"}]},{"type":"numberedlist","attrs":{"start":null,"normalizeStart":1},"content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":1,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#292929","name":"user"}}],"text":"你向Postman集合添加一个参数"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":2,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#292929","name":"user"}}],"text":"Postman将这条更新的记录和Profile信息保存在版本控制中"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":3,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#292929","name":"user"}}],"text":"实时地在集合视图展示最新信息"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"Sync服务最初希望用于处理数据库事务,比如更新集合。然而,去年的这个时候Sync还管理了一些额外的活动,比如给所有集合订阅者通知和显示最新版本。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/74\/74582380866c82b6252495abe2f54dc2.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"承压的Sync"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"当你在制造汽车时,车架是所有其他模块依附的主要支撑结构。车架上的一个小裂缝可能看起来不是什么大问题。在低速行驶时,它很可能不被注意到。然而在速度比较高时,会产生连锁反应导致不协调升级。这个看似不起眼的裂缝将使得振动在车辆的其它部分放大,直到把它烧成残骸。"}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"“较小系统中被忽视的东西到了复杂系统将变得难以承受。”—— Postman公司的工程经理Kunal Nagpal"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"Sync是Postman公司最早的服务之一,它的单体架构使得团队可以快速发布Postman功能。随着时间的推移,它开始承担越来越多的责任。时至今日,Sync服务仍然对整个工程团队有着广泛的影响,许多工程师在Sync出现非预期行为或者定期性地宕机时都会感到异常痛苦。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"2019年,Sync同时处理websocket连接和数据库事务。随着我们的1100万用户之间产生的协作越来越多,Postman在高峰期有接近一百万并发连接。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"作为Postman实际上所有微型服务的基础,Sync的压力越来越大。"}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#292929","name":"user"}},{"type":"strong"}],"text":"反向压力带来的级联故障:"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#292929","name":"user"}}],"text":"Sync的每次部署都会导致通过websockets连接的 Postman客户端断开。当百万个套接字重新连接时,服务器资源就会被消耗从而导致更多的连接断开,造成可预见但无法避免的浪涌,需要6到8个小时才能恢复。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#292929","name":"user"}},{"type":"strong"}],"text":"影响用户体验:"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#292929","name":"user"}}],"text":"虽然这种情况不经常发生,断开连接意味着在查看团队工作区最新更新和活动时会有偶尔的延迟。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#292929","name":"user"}},{"type":"strong"}],"text":"更高的维护成本:"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#292929","name":"user"}}],"text":"由于每个小组都依赖于Sync,实际上每个Postman的工程师都必须学习如何处理连接掉线,启动新连接,然后解决数据中的所有冲突。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"基础服务团队知道他们需要提高websocket连接的效率,并且还需要将它们与Sync服务分离。虽然目标明确,但达成目标的路径却不清晰。"}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"“这是软件设计的自然演化过程。微服务开始很灵活,但会逐渐长大,它们需要被打破。为了能够引入更多功能,我们希望将套接字处理与Sync分离开来。” —— "},{"type":"link","attrs":{"href":"https:\/\/www.linkedin.com\/in\/yashishdua\/","title":null,"type":null},"content":[{"type":"text","text":"Yashish Dua"}]},{"type":"text","text":",Postman公司的软件工程师"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/2c\/2c67380ca0ed438203675cc371bd6e41.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"italic"},{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"有些内部服务过于庞大,需要团队之间仔细协作"}]},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"事情经过"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"第一步: 我们得到组织的支持"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"第一个需要解决的挑战不是技术问题。这在Postman不是首次。工程师们已经从过去的尝试中学会了如何从人开始。从2019年10月开始,服务基础团队的工程师们进行了一系列评审,旨在向更广泛的组织传达这一目标,并解释对所有依赖的服务带来的好处。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"如果这个新系统成功了,处理掉线和后续影响就不再是经常的事情了。这是其他工程团队支持和迁移到新系统的真正动机。这种公开的沟通和协调将在整个项目期间持续下去。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"第二步:我们识别未知的盲区"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"尽管工程部门知道他们的前进方向,他们还是花了一些时间来梳理所有的场景并更好的理解基本概念。工程师们安排了与其他利益相关方的研究会议以确定未知的盲区,这些不可预见的情况可能暴露更大的风险。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"即便Postman团队擅于进行研究和规划,但由于这些改变的关键性,这个过程花费的时间比正常情况要久得多。他们研究了不同的选择,考虑了辅助需求,在两个月的时间里作出了一个计划。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"第三步:我们构建了Bifrost websocket网关"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"Bifrost由两部分组成:"}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#292929","name":"user"}},{"type":"strong"}],"text":"公共网关"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#292929","name":"user"}}],"text":":网关使用Fastify web框架和Amazon AWS ElastiCache for Redis作为中央消息代理来管理所有的websocket连接。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#292929","name":"user"}},{"type":"strong"}],"text":"私有API"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#292929","name":"user"}}],"text":":API还使用Fastify作为一个低开销的web框架来代理其他内部Postman服务。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/da\/da45352976e90e2cdb4c3c9b77949e38.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"italic"},{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"Bifrost由两部分组成: 一个公共网关和一个私有API"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"第四步: 我们测试了新网关"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"当Postman工程师准备交付一个特性时,他们需要测试它以及所有相关特性。由于几乎每个Postman特性都依赖于websocket,这意味着每个特性都必须为这个发布进行测试。此外,由于Postman尚未设立websockets的"},{"type":"link","attrs":{"href":"https:\/\/www.postman.com\/automated-testing\/","title":null,"type":null},"content":[{"type":"text","text":"自动"}],"marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}]},{"type":"link","attrs":{"href":"https:\/\/www.postman.com\/automated-testing\/","title":null,"type":null},"content":[{"type":"text","text":"化测试"}],"marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"框架,因此所有测试工作在Bifrost 投入生产前都是由人工完成的。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"这是一段艰苦的旅程,但到2020年1月底,工程部已经有了一个可行的概念验证。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"第五步: 我们迁移到新网关"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"所有Postman客户端,比如Electron应用或 Web,都依赖于对另一个名为Godserver的核心服务进行初始化引导调用。这个服务负责确定客户端的访问和配置,以及如何控制进行增量产品展示。因为所有这些都是由Godserver预先决定和控制的,所以迁移到Bifrost网关不需要Postman客户端代码单独更新。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"基础服务团队总结了所有小组的迁移步骤、所需的代码更改和应用配置。在短短几个星期的过程中,依赖服务开始从依赖Sync转变为基于Bifrost的websocket连接进行处理。Godserver将越来越多的流量转移到新的websocket网关,以便观察Bifrost如何处理负载和响应边界情况。"}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"“这就像在空中更换飞机的引擎。”—— Postman公司的工程总监 "},{"type":"link","attrs":{"href":"https:\/\/www.linkedin.com\/in\/numaanashraf\/","title":null,"type":null},"content":[{"type":"text","text":"Numaan"}]},{"type":"link","attrs":{"href":"https:\/\/www.linkedin.com\/in\/numaanashraf\/","title":null,"type":null}},{"type":"link","attrs":{"href":"https:\/\/www.linkedin.com\/in\/numaanashraf\/","title":null,"type":null},"content":[{"type":"text","text":"Ashraf"}]},{"type":"text","text":" 说"}]}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"第六步: 我们对服务进行了扩展"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"Bifrost正在工作!"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"但在新网关规划和开发过程中,Postman又获得了大约一百万用户。其他的工程团队在这段时间并没有停止他们自己的工作,新添加的协作特性,如"},{"type":"link","attrs":{"href":"https:\/\/learning.postman.com\/docs\/collaborating-in-postman\/version-control-for-collections\/","title":null,"type":null},"content":[{"type":"text","text":"版本控制"}],"marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"和"},{"type":"link","attrs":{"href":"https:\/\/learning.postman.com\/docs\/collaborating-in-postman\/roles-and-permissions\/#roles-in-postman","title":null,"type":null},"content":[{"type":"text","text":"基于角色的存取控制(RBAC)"}],"marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":",都严重依赖websockets来实时更新信息。大量即将发布的产品将真正考验这个新网关。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"Bifrost已经准备好支持不断增长的需求和扩展的websocket处理。"}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#292929","name":"user"}},{"type":"strong"}],"text":"水平扩展"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#292929","name":"user"}}],"text":": 大多数时候,Postman服务通过扩展到更大容量的实例或者向集群添加更多计算实例,来应对使用量的增加。因此,Postman公司的工程师通常升级AWS EC2实例的规格和计算能力来"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#292929","name":"user"}},{"type":"strong"}],"text":"垂直"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#292929","name":"user"}}],"text":"扩展服务,例如使用AWS Elastic Beanstalk。但是对于Bifrost来说,websocket通过使用"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#292929","name":"user"}},{"type":"strong"}],"text":"更多"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#292929","name":"user"}}],"text":"的机器来进行"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#292929","name":"user"}},{"type":"strong"}],"text":"水平"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#292929","name":"user"}}],"text":"扩展。当大量使用较小规模的实例时,整体可以达到最佳效率。这种类型的超级水平扩展适用于 Bifrost,因为客户端不需要高网络吞吐并可以限制每台机器的连接数量,从而控制了故障的影响范围。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#292929","name":"user"}},{"type":"strong"}],"text":"CPU和内存的新负载因子"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#292929","name":"user"}}],"text":": 大多数Postman服务可以有效地使用单一维度的缩放指标进行扩展,比如CPU、内存或延迟。然而,对于Bifrost来说,情况会稍微有些微妙,因为内存和CPU的使用对不同吞吐量级的操作有不同的影响。为了解决这个问题,Bifrost使用了一个基于负载因子的自定义比例指标。这个负载因子是一种多维计算结果,它提供了自定义的非线性的缩放概述。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/69\/69b72a0fc0f4a445def5cf37dfda49f8.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"让我们深入研究一下Postman工程团队所做的架构和技术决策。"}]},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"Bifrost的架构和技术栈"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"Bifrost系统有两个主要组成部分——网关和API。这两部分架构是系统稳定性和可扩展性的秘密武器。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"网关服务充当所有websocket连接的末端节点。尽管可以购买商业网关,但保留多年来优化积累下来的已有业务逻辑非常重要。Postman工程师也想完全控制websockets的处理方式,例如他们想深入干预握手协议。对于Bifrost网关,他们使用了Amazon ElastiCache For Redis,可以同时通过读节点和写节点来查询Redis缓存。由于将流量分割为两个节点进行读写操作,团队可以进一步优化性能。"}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"“Bifrost是我们所有websocket连接的入口。它是所有Postman客户端的代理,并负责处理Postman内部服务的底层套接字操作。”—— "},{"type":"link","attrs":{"href":"https:\/\/www.linkedin.com\/in\/mudit-mehta-6920a2113\/","title":null,"type":null},"content":[{"type":"text","text":"Mudit Mehta"}]},{"type":"text","text":",Postman公司的软件工程师"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"Postman的大多数其他服务都使用"},{"type":"link","attrs":{"href":"https:\/\/sailsjs.com\/","title":null,"type":null},"content":[{"type":"text","text":"Sails"}],"marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"作为 Node.js的实时MVC框架。然而对于Bifrost 网关,工程师们需要一个更高性能的后端框架,能够快速处理大容量并能优化内存使用率。另外,他们还希望深入到套接字层,而不是停留在Sails上层的抽象和封装。因此,他们转向"},{"type":"link","attrs":{"href":"https:\/\/www.fastify.io\/","title":null,"type":null},"content":[{"type":"text","text":"Fastify"}],"marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":",并基于"},{"type":"link","attrs":{"href":"https:\/\/github.com\/socketio\/socket.io-adapter","title":null,"type":null},"content":[{"type":"text","text":"socketio-adapter"}],"marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"中间件,针对自己的场景进行了优化。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/cf\/cf6fef9cb032e3f0c7c6b9ca1945afe4.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"italic"},{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"Bifrost使用AWS、Redis和Fastify来处理websockets"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"除了网关服务,Bifrost的另一个组件是用来代理上行流量到其他Postman服务的私有API。它基于灵活的业务规则,因此可以不断调整流量转发规则。"}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"“简单的组件。复杂的逻辑。”—— "},{"type":"link","attrs":{"href":"https:\/\/www.linkedin.com\/in\/kunagpal\/","title":null,"type":null},"content":[{"type":"text","text":"Kunal Nagpal"}]},{"type":"text","text":",Postman公司的工程经理"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"对于这两个组件,工程团队决定使用他们自己的组件。尽管Bifrost的网关部分并不经常更新,但是团队可以完全控制websocket的底层处理过程。Bifrost的API部分是操作的核心,它将传入的实时消息转换为标准的HTTP调用。它也可以作为Sync和Bifrost网关之外的独立组件,以便进行更快的更新迭代。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"还记得那个秘密武器吗?通过将Bifrost解耦成两个分离的系统,使得两部分都能按自己的目标进行优化。"}]},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"旅程远未结束"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"就像所有有趣的工程学故事一样,这远远还不是终点。关于Postman工程团队接下来会做什么,这里我给你们留下一些悬念。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#292929","name":"user"}},{"type":"strong"}],"text":"构建附加冗余"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#292929","name":"user"}}],"text":":Redis缓存是一个中央消息代理。Websocket处理仍然依赖于有故障的单点,因此如果缓存服务器挂了,会发生什么情况呢?"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#292929","name":"user"}},{"type":"strong"}],"text":"增加带宽和吞吐"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#292929","name":"user"}}],"text":":网关目前能够处理额外10倍的并发量,但Postman社区正在快速增长,工程师正在构建更多的协作特性,随之而来的是处理更多websocket流量的工程需求。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#292929","name":"user"}},{"type":"strong"}],"text":"继续打破单体服务"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#292929","name":"user"}}],"text":":Sync服务的代码库里杂糅了一堆其他服务。从Sync服务解耦套接字处理过程,解除了和其他服务的耦合,所以现在剥离这些服务变得更加容易。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"这是Postman工程团队如何运作的幕后观察。请关注我们以获取更多来自实战的故事。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"原文链接: "},{"type":"link","attrs":{"href":"https:\/\/medium.com\/better-practices\/how-postman-engineering-handles-a-million-concurrent-connections-15c8807f6393","title":null,"type":null},"content":[{"type":"text","text":"How Postman Engineering handles a million concurrent connections"}],"marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}]}]}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章