影子请求:Okcupid首个GraphQL发布疑难解答188bet金宝搏官网

正如我们在完全新的堆栈中建立我们的GraphQL API,我们希望了解它如何用真正的生产负荷衡量我们以前的RESP API,并且我们想要这样做,而不会对用户体验产生负面影响。
为此,我们发布了我们所谓的影子请求.在我们的目标页面上,用户像往常一样从REST API加载页面数据并显示页面。然后,用户从GraphQL加载相同的数据,测量调用的时间,并丢弃数据。
我们没有提出这个想法,但这是我们的游戏更换者:我们发现我们的第一个发布了GraphQL API加倍时间- REST API的1200ms与600ms。如果我们向真正的用户展示了这个版本,那么它将导致对他们的非常糟糕的经验。
要了解这个测试如何适应我们在OkCupid上发布GraphQL API的整个过程,请参阅我之前的内容188bet金宝搏官网帖子关于过渡.但是在这里,我将讨论我们在Docker和节点环境中找到的改进,GraphQL Resolvers如何在实体列表中工作,以及CORS请求。所以,让我们看看!
Docker和节点低悬挂水果
我们意识到的第一件事是我不小心发布了一个带有node_env.
设置为发展
.您总是听到不这样做,因为开发模式启用了软件包中更多的日志记录和较慢的代码路径。但现在我有经验证据说为什么不是:改变node_env.
来生产
每个请求保存34毫秒。
在这个初始部署中,我们还使用了一个未优化的Docker基础映像。从节点
来节点拉伸纤细
将图像尺寸减少600MB(850MB至250MB);虽然这并没有加速应用程序的响应时间,但它通过使构建和部署流程更快地更快地使我们的开发周期更快。
这些不是最大的胜利,但他们是最简单的两个!
天真的graphql resolvers可以是sloooow
如果您有一个返回实体列表的字段(在我们的案例中,Okcupid用户)您可能会获得有关这些用户的信息,如他们的名称或年龄。188bet金宝搏官网
我们正在转换为此部署的GraphQL的页面是Okcupid消息页面。188bet金宝搏官网在制作模式时,我们定义了一个对话
具有来自上次发送的消息的文本片段,以及用户
代表你正在谈论的人的实体。然后我们在顶级添加了一个字段用户
实体获取该用户的对话。以下是架构和解析器的相关部分:

对话
架构这工作;我们部署并庆祝!但当我们查看请求的堆栈跟踪时,我们看到的是这样的:

呃,好的......瀑布绝对不是我们正在寻找的东西。但是思考它,它有意义:我们刚刚告诉解析器有关如何获得单个用户的信息,因此它确实知道如何并使20个级联请求到后端。
但是,我们可以做得更好。我们碰巧已经有一种方法可以同时从后端获取有关多个用户的信息,因此解决方案是用包更新我们的解析器,批量批量同一实体类型的多个请求。很多人使用dataloader.,但在我发现的这个特殊例子中GraphQL解析批处理更加符合人体工程学。这是我们更新的解析器:

住人
代替GetUser.
所以在这里,我们通过包一个看起来像普通解析器的函数,而不是获得父母
作为第一个参数,包提供父母
(我们的对话列表)。然后,我们可以提取用户ID并致电我们的批量API端点,住人
.这一改变将通话时间缩短了近275毫秒,时间线看起来相当流畅:

子域+ CORS对我们没有工作
这两个变化让我们大多数人在那里,但我们的GraphQL API仍然始终如一的300ms,而不是我们的REST API。由于我们已经尽可能多地削减了服务器端,我们开始从客户的角度看。
在项目的早期,我们决定从中服务我们的APIgraphql.188bet金宝搏官网okcupid.com.
,并看到用户请求www.188bet金宝搏官网okcupid.com.
正在触发CORS预检。这是正常的,但他们正在服用像永恒的东西:300ms(那个时间响铃吗?)。我们调查了一些与我们的OPS团队的角度(它是CloudFlare?我们的负担平衡器haproxy?),但没有提出任何合理的领导。所以,我们决定尝试从中服务www.188bet金宝搏官网okcupid.com/graphql.
,300ms消失了。什么伎俩!
嘿,它的工作
在将这一系列更改释放到我们的设置后,我们达到了我们的旧休息API。我们发现并解决了我们的节点环境,GraphQL Resolvers和Cors的问题,所有都没有影响现场性能。然后,我们被定位释放一个实验,该实验使真实的用户从GraphQL加载数据与REST API。
如果您考虑向堆栈添加新技术,希望您将考虑验证Shadow请求以验证它。如果该堆栈发生才能创建GraphQL API,希望您可以避免我们击中的一些陷阱。祝你好运!
谢谢Raymond Sohn.和Okcupid188bet金宝搏官网 Web团队阅读本文的草稿。