我们正在使用GraphQL订阅和pubsub订阅帖子。
当超过10个订阅发生时,我们得到节点警告“MaxListenersExceededWarning:检测到可能的EventEmitter内存泄漏。”
是否可以在pubsub类中引发最大侦听器?
pubsub类位于一个单独的模块中,如下所示:
import { PubSub } from 'graphql-subscriptions';
const pubsub = new PubSub();
export { pubsub };
订阅服务器如下所示:
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,
};
答案 0 :(得分:6)
我写了你正在使用的graphql-subscriptions包的原始实现,所以我可以在这里提供一些上下文。
graphql-subscriptions中包含的简单EventEmitter pubsub库仅用于演示目的。 EventEmitters并没有真正扩展到大数字,它们在内存中,只要你只有一台服务器,它们才会工作。
对于任何试图在生产中运行GraphQL订阅的人,我强烈建议使用其他系统,例如Redis或MQTT到graphql-redis-subscriptions或graphql-mqtt-subscriptions。这样可以保持GraphQL服务器无状态(除了websockets),因此易于水平扩展。
答案 1 :(得分:1)
发现您可以更改pubsub实例的事件发射器中的最大侦听器,如下所示:
import { PubSub } from 'graphql-subscriptions';
const pubsub = new PubSub();
pubsub.ee.setMaxListeners(30); // raise max listeners in event emitter
export { pubsub };

答案 2 :(得分:0)
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});