提高网关性能
学习如何调整跟踪、中间件和插件的仪器,更多内容
如果你的超级图网关使用Apollo Server与@apollo/gateway
库,本文提供了提高您的网关性能的建议。
考虑迁移到GraphOS Router
GraphOS Router是一个采用Rust编写的GraphQL Federation网关,具有高吞吐量和低延迟。其性能和一致性显著超过任何基于Node.js的网关。
从@apollo/gateway迁移到GraphOS Router
禁用或减少ftv1 内联跟踪
- 在负载测试期间,我们建议完全禁用跟踪。
关于fieldLevelInstrumentation的使用报告插件文档
更改默认的maxSockets
设置
import {ApolloGateway, RemoteGraphQLDataSource} from '@apollo/gateway';import fetcher from 'make-fetch-happen';const gateway = new ApolloGateway({buildService({name, url}) {return new RemoteGraphQLDataSource({name,url,fetcher: fetcher.defaults({maxSockets: 50})});}});
检测网关中间件和插件
如果您已安装中间件(如Express中间件)或 Apollo Server 插件,使用代码分析工具(如 Clinic.js)去探究潜在问题很有帮助,例如同步代码阻塞主线程或昂贵的插件函数。
使用 OpenTelemetry 跟踪
OpenTelemetry 是 CNCF 分配的标准分布式系统度量工具。通过追踪 @apollo/gateway
、subgraph 服务、数据源以及请求路径中任何其他系统,您可能会发现性能问题的原因超出了 @apollo/gateway
的范畴。
OpenTelemetry 在 @apollo/gateway
中
探究 subgraph 延迟
尝试直接对 subgraph 执行负载测试。您可以通过查询 _entities
字段来模拟网关的请求:
query MyQuery__subgraphA__0($representations: [_Any!]!) {_entities(representations: $representations) {... on EntityA {fieldAfieldB}... on EntityB {fieldCfieldD}}}
通过测试 _entities
查询,您可能会发现需要在自己的 参考解析器 中实现 DataLoader。
您的 subgraph 越慢,网关在跟踪并发请求上花费的时间就越多。随着 subgraph 延迟的提升,网关每秒最大请求次数将线性下降。
调整 CPU 和内存限制
您可能需要在您的 @apollo/gateway
容器上设置更高的 CPU 和内存限制。确定最佳的限制取决于许多因素:
- 操作的大小
- 操作的数量(唯一形状的数量)
- 查询计划复杂度
- 子图延迟
- 使用共享缓存
一般来说,因为 Node.js 是单线程的,它不能使用多个 CPU,所以建议您增加内存限制。但话说回来,我们建议 CPU 利用率维持在 50% 以下。在高 CPU 利用率百分比时,您可能会看到事件循环延迟相对增加。同时监控内存使用量和 CPU 使用量可以帮助提供比仅仅代码分析更清晰的瓶颈图景。
如果 CPU 降频成为一个问题,考虑移除您在前面的讨论中加入的网关容器的限制,详情请参考以下关于 Kubernetes 资源限制的博客文章:优化 Kubernetes 服务的性能,不设置 CPU 限制。
检查查询计划
查询计划(网关从多个子图中解析操作所采取的步骤)几乎总是对原始操作的良好近似。它们也很容易被缓存,因此不会带来太大的性能损失。但是,检查它们以确认其大小和复杂程度是合适的。抽象类型的使用可能导致特定情况下的不理想查询计划。
const gateway = new ApolloGateway({debug: true // print query plans to stdout});
添加更多实例
@apollo/gateway
是设计为水平扩展的。如果您已经尝试了前面的策略但性能仍不理想,请将负载分配到更多网关实例。