Как сделать сшивание схемы в Apollo Server быстрее?

Первоначально я пытался использовать бессерверную лямбда-функцию для обработки сшивания схемы для моих API, но я начал переходить на сервер Elastic Beanstalk, чтобы избежать необходимости извлекать исходную схему при каждом запросе.

Тем не менее, запрос к моему основному серверу 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 напрямую, а не через localhost.

http://localhost:3002/graphql> http://127.0.0.1:3002/graphql

Оказалось, что для меня это вовсе не проблема Аполлона.

В моем тестировании самым большим приемником времени является makeRemoteExecutableSchema, который занимает от 400 до 600 мсек на моем 8-ядерном компьютере с использованием файла локальной схемы.

Charlie Brown 18.01.2019 19:45
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Что такое Apollo Client и зачем он нужен?
Что такое Apollo Client и зачем он нужен?
Apollo Client - это полнофункциональный клиент GraphQL для JavaScript-приложений, который упрощает получение, управление и обновление данных в...
2
1
1 091
1

Ответы 1

Я бы рекомендовал использовать движок Apollo, чтобы наблюдать, что на самом деле происходит с каждым запросом, как вы можете видеть на следующем снимке экрана:

вы можете добавить его в конфигурацию вашего сервера Apollo

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});
};

Привет, Адель, не могли бы вы поделиться ссылкой на github для проекта, содержащего информацию о том же? Я хочу выполнить сшивание схемы на уровне шлюза.

Tushar Mahajan 27.11.2019 10:10

Другие вопросы по теме