Node.js Meteor MongoDB订阅以10秒的间隔而不是实时交付数据

Node.js Meteor MongoDB订阅以10秒的间隔而不是实时交付数据,node.js,mongodb,meteor,Node.js,Mongodb,Meteor,我相信这更像是一个MongoDB问题,而不是流星问题,所以如果你对mongo了解很多,但对流星一无所知,不要害怕 在开发模式下运行Meteor,但将其连接到外部Mongo实例而不是使用Meteor的捆绑实例,会导致相同的问题。这让我相信这是Mongo的问题,不是流星的问题 实际问题 我有一个项目,它不断地将数据添加到数据库中,并在应用程序中实时显示它们。它在开发模式下工作得很好,但在构建并部署到生产环境中时会有奇怪的行为。其工作原理如下: 一个单独运行的小脚本收集广播UDP包,并将它们放入m

我相信这更像是一个MongoDB问题,而不是流星问题,所以如果你对mongo了解很多,但对流星一无所知,不要害怕

在开发模式下运行Meteor,但将其连接到外部Mongo实例而不是使用Meteor的捆绑实例,会导致相同的问题。这让我相信这是Mongo的问题,不是流星的问题


实际问题 我有一个项目,它不断地将数据添加到数据库中,并在应用程序中实时显示它们。它在开发模式下工作得很好,但在构建并部署到生产环境中时会有奇怪的行为。其工作原理如下:

  • 一个单独运行的小脚本收集广播UDP包,并将它们放入mongo集合中
  • Meteor应用程序然后发布此集合的一个子集,以便客户端可以使用它
  • 客户端订阅并实时更新其视图
这里的问题是订阅似乎每10秒只获取一次数据,而这些UDP包每秒到达并被推入数据库几次。这使得应用程序的行为怪异

它在UDP消息的收集上最为明显,但不限于此。订阅的每个集合都会发生这种情况,即使那些没有使用外部脚本填充的集合也是如此

通过MongoShell或应用程序直接查询数据库表明,文档确实按照预期添加和更新了。发布只是没有注意到,似乎默认为每隔10秒查询一次

Meteor在MongoDB上使用oplog跟踪,以了解何时添加/更新/删除文档,并基于此更新出版物

有谁比我有更多的Mongo经验,谁可能知道问题出在哪里


作为参考,这是一个非常简单的发布函数

/**
 * Publishes a custom part of the collection. See {@link  https://docs.meteor.com/api/collections.html#Mongo-Collection-find} for args
 *
 * @returns {Mongo.Cursor}      A cursor to the collection
 *
 * @private
 */
function custom(selector = {}, options = {}) {
        return udps.find(selector, options);
}
以及订阅它的代码:

Tracker.autorun(() => {
        // Params for the subscription
        const selector = {
                "receivedOn.port": port
        };
        const options = {
                limit,
                sort: {"receivedOn.date": -1},
                fields: {
                        "receivedOn.port": 1,
                        "receivedOn.date": 1
                }
        };

        // Make the subscription
        const subscription = Meteor.subscribe("udps", selector, options);

        // Get the messages
        const messages = udps.find(selector, options).fetch();

        doStuffWith(messages); // Not actual code. Just for demonstration
});

版本:

发展:

  • 节点8.9.3
  • mongo 3.2.15
制作:

  • 节点8.6.0
  • mongo 3.4.10
这是一种DDP(Websocket)心跳配置

Meteor实时通信和实时更新使用DDP(Meteor在SockJS之上实现的基于JSON的协议)执行。 客户端和服务器,它可以在其中更改数据并对其更改作出反应

DDP(Websocket)协议实现了所谓的PING/PONG消息(心跳),以使Websocket保持活动状态。服务器通过Websocket向客户机发送一条PING消息,然后客户机用PONG回复

默认情况下,heartbeatInterval配置为略多于17秒(17500毫秒)

请点击此处:

您可以使用以下命令在服务器上以毫秒为单位配置心跳时间:

Meteor.server.options.heartbeatInterval = 30000;
Meteor.server.options.heartbeatTimeout = 30000;
其他链接:


Meteor使用两种操作模式在没有任何内置实时功能的mongodb上提供实时功能轮询和差异oplog跟踪

1-Oplog跟踪

它通过读取mongo数据库用于同步辅助数据库的复制日志(“oplog”)来工作。这使得Meteor能够跨多个主机提供实时更新,并水平扩展。 它更复杂,并且跨多个服务器提供实时更新

2-民意调查和差异

poll和diff驱动程序通过反复运行查询(轮询)和计算新旧结果之间的差异(差异)来工作。每当同一服务器上的另一个客户端执行可能影响结果的写入操作时,服务器将重新运行查询。它还将定期重新运行,以从其他服务器或修改数据库的外部进程获取更改。因此,poll和diff可以为连接到同一服务器的客户端提供实时结果,但它会为外部写入带来明显的延迟。 (默认值为10秒,这是您的体验,另请参见附件中的图片)

这可能对应用程序UX有害,也可能不有害,具体取决于应用程序(例如,不适合聊天,适合TODO)

这种方法简单且易于理解缩放特性。然而,它不能很好地与大量用户和大量数据进行扩展。由于每次更改都会导致重新蚀刻所有结果,因此CPU时间和网络带宽会随着用户的变化而变化。Meteor自动消除相同查询的重复,因此,如果每个用户都执行相同的查询,则结果可以共享

您可以通过更改
pollingIntervalMs
pollingThrottleMs
的值来调整poll和diff

您必须使用
disableOplog:true
选项在每个查询的基础上选择退出oplog跟踪

Meteor.publish("udpsPub", function (selector) {
  return udps.find(selector, {
    disableOplog: true,
    pollingThrottleMs: 10000, 
    pollingIntervalMs: 10000
  });
});
其他链接:


这似乎不是原因。。。我试着先把它降到1000,然后降到100。没有区别。这也正好是10秒,而不是17.5秒或15秒,因为我最初的设置是这样的。这也不能解释为什么它可以与Meteor捆绑的mongo实例一起使用,但不能与独立的mongo服务器一起使用,所有其他事情都是一样的。DDP连接不直接与数据库通信我在heroku上有一个meteor项目连接到mlab上的mongodb。当我在mongodb中手动更改数据时。更新流星前端的实时数据只需不到18秒。你说得对。在我的本地机器上。它可以立即更新数据,不需要时间。我会检查为什么它不同于生产。请确认您正在使用oplog。10秒是轮询的默认速率。@AlexBlex除非默认打开,否则我显然不是。。。我注意到Meteor有一个MONGO_OPLOG_URL环境变量。我尝试将其设置为与我的MONGO_URL相同,但这会给出错误消息
error:$MONGO_OPLOG_URL必须设置为