无服务器和 Go 之旅:Capital One Credit Offers API 的演变

作为一家技术驱动的金融公司,我们在 Capital One 的最大目标之一是使用技术轻松、快速、直接地与我们的客户互动。潜在的 Capital One 客户与我们互动的一种重要方式是通过我们的会员渠道。Credit Sesame、  CreditCards.com和 Bankrate等附属合作  伙伴与 Capital One 建立了特殊的合作伙伴关系,他们展示可用的信用卡选项并引导潜在客户使用适合他们的信用卡。对于我们的附属合作伙伴,这是通过 Credit Offers API完成的。我们喜欢认为它可以帮助人们做出更明智的信用卡选择。我们也喜欢认为它展示了我们对技术的尖端使用。

什么是信用优惠 API?

它是如何工作的?Credit Offers API 公开了 Capital One 信用卡优惠的完整列表,我们的附属合作伙伴可以向他们的客户展示这些优惠,以及奖励信息和产品评论等详细信息。它具有资格预审功能,可以个性化卡产品,为客户匹配正确的卡(不影响他们的信用评分!)。它还有一个很好的预填功能,可以提供完整的预填申请,使申请 Capital One 信用卡的体验更加顺畅。

2015 年构建 1.0 版时,Credit Offers 是用 Java 构建的。API 的当前版本 3.0 版已经过重建,因此它是完全无服务器的并用 Go 编写。这是两种非常酷的技术,它们结合起来是一种快速而强大的方式来展示和展示我们的信用卡产品。

为什么是Go?

2016 年年中,我们在 API 中添加了一个额外的端点,用于确认已向客户显示了一个报价。Go 在 Capital One 开始获得非常巨大的、令人印象深刻的势头,并且基于我的团队整合的 POC,我们看到了与 Java 相比的巨大性能提升。这些结果很清楚,因此我们决定将其用于这个新端点。

当时,没有一个团队成员知道 Go,但在一个月内,每个人都在用 Go 编写代码,我们正在构建端点。正是灵活性、易用性以及 Go 背后真正酷的概念(Go 如何处理本机并发、垃圾收集,当然还有安全性+速度。)帮助我们在构建过程中参与其中。还有,谁能打败那个可爱的吉祥物!

在 Go 中重写 Credit Offers API 的整个过程比预期的要简单得多。作为技术主管,我是最后一个批准一段代码何时合并并准备发布的人。所以我必须更深入地了解 Go,不仅要理解代码,还要理解业务逻辑。一个更令人满意的惊喜是,将业务逻辑与像 Go 这样的简单语言混合意味着很容易进入这个角色并且不会成为发布的瓶颈。

我们想要探索的下一个技术是无服务器。根据定义,Go 既快速又简单,这也是定义 lambda 的方式。事实上,我们不想在没有 Go 的情况下使用无服务器。这让我们……

为什么选择无服务器?

在另一轮分析中,我们意识到我们的用例非常适合无服务器方法。去年我参加了 AWS re:Invent,主要关注无服务器会议,并对 Credit Offers API 如何与无服务器协同工作有了所有这些想法。2018 年 1 月初发布对 Go 的 lambda 支持后,  我们开始进行迁移,我们开始分析工具,我们开始将代码封装在 lambda 中并添加额外的警报,以便我们可以完全无服务器。我们在今年 10 月初完成了这次迁移。

我们被无服务器所吸引是因为它结合了四个主要支柱:

由于附属渠道和 Credit Offers API 影响我们的合作伙伴和潜在客户的方式,能够在不中断服务的情况下无缝扩展我们的 API 非常重要。无服务器不仅让我们能够摆脱服务器,而且让我们变得更快、更有弹性。最大的“胜利”之一是我们的开发人员无需停下来担心基础设施,可以将更多时间用于创建和交付与业务相关的功能。

在这张图片中,您可以看到架构是多么简单。我们如何与 Amazon CloudWatch集成 以监控系统的运行状况。我们选择 DynamoDB 是因为它的转义能力和灵活的模式;对于长期存储,我们使用 S3 存储桶。我们还使用 Amazon 的 SNS 在出现问题时发出警报。您还可以看到我们如何整合外部监控系统 ——New Relic

同样,lambda 听起来很简单,但我们确实有一些复杂的过程,包括调用作为资格预审流程一部分的外部 API。Go goroutines 和 lambda 是天作之合。

我们无服务器解决方案的另一个关键部分是我们如何进行部署。 金丝雀部署 允许我们部署任何 lambda 更新(版本控制)的 5%,设置特定的金丝雀部署警报,如果出现故障,无需任何干预即可自动回滚。在第一个 5% 的发布成功后,我们确定要测试多长时间,并从那里开始逐步发布新版本的 lambda。Canary 部署对我们来说非常强大。就像我提到的,我们与附属公司有依赖关系,并且随着我们的扩展和增长,我们的新版本不会下降。通过使用带有金丝雀部署的可靠管道,他们不会。

我们的无服务器和 Go 之旅的经验教训

那么我们从这个无服务器和 Go 之旅中学到了什么?

#1 无服务器并不意味着你失去了控制。

恰恰相反,你有更多的控制权。是的,扩展是无缝的,性能更好,但是有限制,你必须检查它们。您不能只是抛出数十亿个请求而不知道如果您没有正确计划它可能会破坏您的服务。为了弥补这一点,您可以扩展到不同的区域、不同的可用区,并计划扩展您的应用程序。

#2 测试是基础。

社区最大的担忧之一是如何测试 lambda,因为 lambda 依赖于一个事件?好吧,我们实际上使用 SAM local 进行了探索——这是用于进行本地测试的无服务器应用程序模型。在开发人员笔记本电脑上,他们可以模拟事件并全面测试 lambda。

#3 注意你的数据和数据库。

无服务器数据库有多种选择,具体取决于您的用例、需要保留哪些数据、需要保留多长时间等。在我们的案例中,最直接的选择是选择一个能够为我们提供所需灵活性和功能的数据库对于这个 API。

#4 保持简单。

Lambda 不应该是一大段代码。适当调整您的功能——让它们保持简单的是/否。

#5 启用分布式跟踪。

我们使用 AWS X-Ray。这是 AWS 环境的自然选择,让您全面了解系统的运行情况。这不仅适用于 lambda,还适用于数据库、Route 53s、网关等。您可以通过 X-Ray 获取应用程序的每个联系点,包括其他微服务。

#6 在设计无服务器管道时考虑金丝雀部署。

经过良好测试的增量部署使我们的 API 更具弹性。通过使用金丝雀部署,我们可以 24x7 全天候发布,而不会中断我们的附属公司的服务。

#7 微服务思维。

在设计您的解决方案时,请尝试使其简单,识别进出的依赖关系,并且在您可以在您的生态系统中创建平滑耦合之前不要离开白板。最后,完全控制您的事件源。

结果

我们在无服务器的性能提升、成本节约和团队速度方面看到了一些很好的结果。从 lambda 获取请求到它回复的时间,70% 的性能提升非常令人印象深刻。更令人印象深刻的是我们在成本方面的巨大成就——通过移除 EC2、ELB 和 RDS 节省了 90%。作为技术负责人,我们通过不花时间修补、修复和维护服务器而获得的 30% 的团队速度提高是我们现在可以花时间创新、创建和扩展业务需求的时间。

现在 API 是 100% 无服务器的,我们有一个可靠的路线图,说明我们还想用该技术做什么。我们希望合并 AWS CodeBuild 来为多个构建过程创建一个简单的管道,我们希望使用 AWS Step Functions 来添加更好的重试机制,并且我们希望将 ELK 合并到我们的日志记录中,以便我们可以将一些业务仪表板添加到我们的解决方案中。但我们会将其保存到另一篇文章中。