使用GraphQL缓存,利用AWS原型化程序进行开发
首先
这篇文章是以下三篇文章系列的第二篇。
①引入背景和目的
②利用AWS原型開發計劃進行開發
③在生產發布之前解決的問題和引入所帶來的效果
本文将涵盖以下主题。
-
- GraphQLとCloudFrontの相性
-
- AWS Prototyping program
- 技術選定
GraphQL 和 CloudFront 的兼容性如何?
实际上,GraphQL和CloudFront并不是很匹配。当结合诸如“GraphQL”、“caching”、“CDN”等词进行谷歌搜索时,可以找到一些关于其他CDN产品的博客,但并没有关于在CloudFront上进行缓存的案例。在当时,我也没有看到过其他CDN的实际部署和运营案例。
为什么它们的相性不好呢?尽管我个人没有使用过GraphQL进行开发,但从基础设施角度来看,我认为GraphQL具有以下特点,与CloudFront相互之间不太匹配。
-
- URLエンドポイントは基本的に一つである。1
慣習的にPOSTメソッドを用いる。2
在CloudFront中缓存GraphQL的挑战
上述功能是GraphQL缓存在CloudFront中的挑战。
一个URL的尾点
CloudFront使用行为来控制缓存。行为可以根据请求的路径模式进行创建,因此可以灵活地控制缓存,例如根据路径模式更改缓存对象的TTL和缓存键。
然而,由于GraphQL的URL端点基本上只有一个,因此很难实现灵活的缓存控制。您将不得不使用一个行为来控制所有GraphQL请求。使用一个行为来控制意味着TTL必须根据可缓存响应中最短的时间来设置。缓存键的设计也变得困难。
另外,當執行緩存無效(Invalidation)時,所有緩存都會消失,請勿輕率刪除,因為會導致大量請求直接流向源站。我認為在想要快速反映源站更新的情況下,可能需要刪除CDN的緩存,但在這種情況下,您應該希望只刪除相關的API的緩存。然而,由於URL端點只有一個,無法部分地刪除緩存。
POST请求
CloudFront不会缓存对于POST请求的响应结果。
Amazon CloudFront能够缓存POST响应吗?
Amazon CloudFront不会缓存POST、PUT、DELETE和PATCH请求的响应。这些请求将被代理到源服务器。可以启用对OPTIONS请求响应的缓存。3
简言之,只是把CloudFront放置在GraphQL服务器之前,并不能实现将GraphQL的响应缓存到CloudFront上。
使用CloudFront的好处不仅仅是缓存,还包括通过AWS全球网络提供的通信稳定性。但对于大部分用户都在国内的网站和服务,我认为很少会仅仅为了这个目的而使用CloudFront。4
AWS原型开发计划
只使用CloudFront无法缓存GraphQL的响应。接下来,我们将讨论如何配置CloudFront以实现缓存GraphQL响应的过程。
总结起来,我们使用AWS原型设计计划,开发了一个能够利用CloudFront缓存GraphQL响应的原型,并对其进行了改进以适应LOWYA的需求,从而开发了一个缓存机制。
AWS Prototyping program是什么
AWS原型方案计划是一项免费的AWS项目,由AWS的原型工程师为AWS用户开发他们想要实现的基于AWS的机制的原型。(并不意味着完全依赖他们开发。)
以下是程序的概要,如下推文所示。如果您想了解更多关于该程序的详细信息,请咨询AWS的SA先生,而不是西谷先生。
我们得到了我们公司负责解决方案架构师的介绍,并与AWS的原型工程师一起开发了这个原型。我们一直在思考如何在AWS上实现GraphQL的缓存,但没有想到最适合用例的架构,一直感到困惑。这个介绍非常有帮助。
已完成的原型
这是已完成的原型。
如果您对这个机制有任何疑问,我建议您参阅上述存储库中的README文件。
为了解决CloudFront不会缓存POST请求响应的致命问题,我们在OriginRequest的Lambda@Edge中,将POST方法转换为GET方法,并将POST请求的主体分割后存储在头信息中作为缓存键,然后重新发送请求给CloudFront。
该特性带来的约束是可以被接受的,因为只有一个URL终点。
在第三篇文章中,我们将详细介绍LOWYA的实际运行代码和实施考虑的要点。
技术的选择
在过去的讨论中,我们讨论了如何在CloudFront中实现GraphQL缓存,但我们并不是从一开始就选择了CloudFront进行技术选定。
在技术选择中,着重考虑了以下几点。
-
- バックエンドのインフラ構成の変更を必要としないこと7
アプリケーションの改修が極力少ないこと
APIのセキュリティ対策も実現できること
LOWYA在2020年8月将旗舰店的电子商务系统从包装产品改为基于容器的自制系统进行了全面更新。虽然已经过去了两年,但运营仍然非常稳定。为了GraphQL缓存,我们进行了重大的配置更改,但我们不希望牺牲运营稳定性。
此外,我们寻找一种尽可能少进行应用程序修改的方法。如果修改的部分较多,将增加引入GraphQL缓存所需的工作量,同时可能会影响运营并损害系统的稳定性。
我同时也考虑实现保护API免受恶意请求(包括DoS和DDoS攻击)的安全措施。
满足这些要求的选择是由AWS Prototyping program开发的原型。
因为在进行技术选择时,我们制作了一张比较表,下面是该表的一部分内容。
选择 Amazon CloudFront + Lambda@Edge (AWS原型) 的决定因素如下。
The decisive factors for choosing Amazon CloudFront + Lambda@Edge (AWS原型) are as follows.
-
- 開発コストが低いこと
Cloudflare と Fastly は有償のプロフェッショナルサービスを利用してサポートを依頼する必要があったが、AWS Protoryping program は無償でプロトタイプを提供してもらえる
学習コストが低いこと
CloudFrontとLambda@Edgeはすでに利用しているため、知見がある
バックエンドのインフラ構成の変更が不要、アプリケーションの改修範囲も狭いこと
フロントエンドとバックエンドのアプリケーションの間に、CloudFront と Lambda@Edge で構成されたAPIキャッシュ層が挟まるだけなので、導入と切り戻しが容易である。結果的にはアプリケーションの改修箇所も少なく済んだ
AWS WAF, AWS ShieldAdvanced を活用することでセキュリティ強化が可能であること
这篇文章的总结
本文介绍了GraphQL缓存机制的开发过程,并结合了三个主题进行了讨论。下一篇文章将写关于如何解决在将原型应用于生产发布之前遇到的问题。主题是关于将原型适应LOWYA的艰辛经历。
如果是面向全球展开的服务,即使无法缓存,作为API加速器使用CloudFront也是有优点的。然而对于像LOWYA这样大多数用户在国内的服务,应该计算CloudFront的通信成本,并仔细调查介入所需的工作量和配置更改的影响,然后判断是否有优势。
请不要联系西谷先生,因为他已经离职AWS。
由于感染病防控的需要,我们远程实施了原型开发。原型开发按照需求调研、架构设计、构建和交付的流程进行。换句话说,我们将想要实现的内容告诉AWS原型工程师,对规范和架构进行讨论,然后由原型工程师开发原型并交付给我们,我们在自己的环境中进行验证。
请查看第一篇文章以了解LOWYA后端架构。
如果您对LOWYA旗舰店系统的内部化感兴趣,请查看Devsami 2021的演讲资料。