GraphQL订阅:最大侦听器超出警告

Loc*_*0_0 6 subscriptions node.js graphql graphql-subscriptions

我们使用GraphQL订阅和pubsub订阅帖子.

当超过10个订阅发生时,我们得到节点警告"MaxListenersExceededWarning:检测到可能的EventEmitter内存泄漏".

是否可以在pubsub类中引发最大侦听器?

pubsub类位于一个单独的模块中,如下所示:

import { PubSub } from 'graphql-subscriptions';

const pubsub = new PubSub();

export { pubsub };
Run Code Online (Sandbox Code Playgroud)

订阅服务器如下所示:

import { SubscriptionManager } from 'graphql-subscriptions';
import { createServer } from 'http';
import { SubscriptionServer } from 'subscriptions-transport-ws';

import { pubsub } from './subscriptions';
import executableSchema from './executableSchema';

const WS_PORT = 8080;

const websocketServer = createServer((request, response) => {
  response.writeHead(404);
  response.end();
});

websocketServer.listen(WS_PORT, () => console.log(
  `Websocket Server is now running on http://localhost:${WS_PORT}`
));

const subscriptionManager = new SubscriptionManager({
  schema: executableSchema,
  pubsub: pubsub,
  setupFunctions: {
        newPost: (options, args) => {
         return {
            newPostChannel: {
               filter: (post) => {
                  return args.publicationId === post.relatedPublication.id;
               }
            },
         };
      },
  },
});

const subscriptionServer = new SubscriptionServer({
  subscriptionManager: subscriptionManager
}, {
  server: websocketServer,
  path: '/',
});


export {
  subscriptionServer,
};
Run Code Online (Sandbox Code Playgroud)

hel*_*fer 7

我编写了你正在使用的graphql-subscriptions包的原始实现,所以我可以在这里提供一些上下文.

graphql-subscriptions中包含的简单EventEmitter pubsub库仅用于演示目的.EventEmitters并没有真正扩展到大数字,它们在内存中,只要你只有一台服务器,它们才会工作.

对于任何试图在生产中运行GraphQL订阅的人,我强烈建议使用不同的系统,例如Redis或MQTT,通过graphql-redis-subscriptionsgraphql-mqtt-subscriptions.这样可以保持GraphQL服务器无状态(除了websockets),因此易于水平扩展.

  • "...我强烈建议使用不同的系统......"谢谢,我很感激信息. (2认同)
  • 这应该真正添加到graphql-subscriptions自述文件中.我没有意识到这一点,并且已经在生产中运行默认的EventEmitter设置几个月了!(并一直在获得内存泄漏警告) (2认同)

小智 5

ee是 的受保护成员PubSub,因此直接设置它会导致 TypeScript 项目出现错误。但是,您可以将EventEmitter调整后的MaxListener计数传递给PubSub构造函数:

import { PubSub } from 'apollo-server-express';
import { EventEmitter } from 'events';

const biggerEventEmitter = new EventEmitter();
biggerEventEmitter.setMaxListeners(30);
const pubSub = new PubSub({eventEmitter: biggerEventEmitter});
Run Code Online (Sandbox Code Playgroud)


Loc*_*0_0 4

发现您可以更改 pubsub 实例的事件发射器中的最大侦听器,如下所示:

import { PubSub } from 'graphql-subscriptions';

const pubsub = new PubSub();
pubsub.ee.setMaxListeners(30); // raise max listeners in event emitter

export { pubsub };
Run Code Online (Sandbox Code Playgroud)