最初,我尝试使用无服务器Lambda函数来处理API的模式缝合,但是我开始转向Elastic Beanstalk服务器,以免需要在每个请求上获取初始模式。
即使如此,从我的子API服务器中获取一个子API服务器的结果所花费的时间大概是我的主API服务器的十倍。我不确定是什么原因使请求如此之长,但是似乎有些东西阻止了请求的快速解决。
这是我的父API代码:
import * as express from 'express';
import { introspectSchema, makeRemoteExecutableSchema, mergeSchemas } from 'graphql-tools';
import { ApolloServer } from 'apollo-server-express';
import { HttpLink } from 'apollo-link-http';
import fetch from 'node-fetch';
async function run () {
const createRemoteSchema = async (uri: string) => {
const link = new HttpLink({ uri, fetch });
const schema = await introspectSchema(link);
return makeRemoteExecutableSchema({
schema,
link
});
};
const remoteSchema = await createRemoteSchema(process.env.REMOTE_URL);
const schema = mergeSchemas({
schemas: [remoteSchema]
});
const app = express();
const server = new ApolloServer({
schema,
tracing: true,
cacheControl: true,
engine: false
});
server.applyMiddleware({ app });
app.listen({ port: 3006 });
};
run();
知道为什么这么慢吗?
更新:
对于任何试图将本地环境中的模式组合在一起的人,我都直接获取了127.0.0.1而不是通过本地主机,从而大大提高了速度。
http://localhost:3002/graphql
> http://127.0.0.1:3002/graphql
对我来说,这根本不是阿波罗问题。
答案 0 :(得分:4)
我建议使用Apollo引擎观察每个请求的实际情况,如您在下一个屏幕截图中看到的:
您可以将其添加到您的Apollo Server配置中
engine: {
apiKey: "service:xxxxxx-xxxx:XXXXXXXXXXX"
},
此外,在缓存控件上定义defaultMaxAge时,我会遇到更好的性能:
cacheControl: {
defaultMaxAge: 300, // 5 min
calculateHttpHeaders: true,
stripFormattedExtensions: false
},
另一有用的方法是,如果确实有必要,可以在缝合对象上增加更长的最大缓存寿命,您可以通过在模式缝合解析器中添加缓存提示来做到这一点:
mergeSchemas({
schemas: [avatarSchema, mediaSchema, linkSchemaDefs],
resolvers: [
{
AvatarFlatFields: {
faceImage: {
fragment: 'fragment AvatarFlatFieldsFragment on AvatarFlatFields { faceImageId }',
resolve(parent, args, context, info) {
info.cacheControl.setCacheHint({maxAge: 3600});
return info.mergeInfo.delegateToSchema({
schema: mediaSchema,
operation: 'query',
fieldName: 'getMedia',
args: {
mediaId: parseInt(parent.faceImageId),
},
context,
info,
});
}
},
}
},
最后,在启用批处理和数据加载器缓存时,使用dataLoaders可以使处理请求更快,并在其github上阅读更多内容,并且代码将如下所示:
public avatarLoader = (context): DataLoader<any, any> => {
return new DataLoader(ids => this.getUsersAvatars(dataLoadersContext(context), ids)
.then(results => new Validation().validateDataLoaderArrayResults(ids, results))
, {batch: true, cache: true});
};