Sup*_*pen 3 mongodb node.js meteor
我相信这更像是一个MongoDB问题,而不是一个流星问题,所以如果你对mongo有很多了解,但对流星一无所知,不要害怕.
在开发模式下运行Meteor,但将其连接到外部Mongo实例而不是使用Meteor的捆绑实例,会导致同样的问题.这让我相信这是一个Mongo问题,而不是流星问题.
我有一个流星项目,它不断地将数据添加到数据库中,并在应用程序中实时显示它们.它在开发模式下完美运行,但在构建和部署到生产时具有奇怪的行为.它的工作原理如下:
这里的问题是订阅似乎只获得大约每10秒一次的数据,而这些UDP包到达并每秒数次被推入数据库.这使得应用程序表现得很奇怪
UDP消息的收集最为明显,但不限于此.它发生在订阅的每个集合中,即使那些没有被外部脚本填充的集合也是如此
通过mongo shell或通过应用程序直接查询数据库,表明文档确实按照预期添加和更新.该出版物没有注意到,并且似乎默认以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);
}
Run Code Online (Sandbox Code Playgroud)
和订阅它的代码:
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
});
Run Code Online (Sandbox Code Playgroud)
版本:
发展:
生产:
Meteor使用两种操作模式在mongodb之上提供实时,而mongodb没有任何内置的实时功能.poll-and-diff和oplog-tailing
1 - Oplog-tailing
它的工作原理是读取mongo数据库的复制日志,它用于同步辅助数据库('oplog').这使得Meteor可以跨多个主机提供实时更新并进行水平扩展.它更复杂,并提供跨多个服务器的实时更新.
2 - 民意调查和差异
poll-and-diff驱动程序通过重复运行查询(轮询)并计算新旧结果(差异)之间的差异来工作.每次同一服务器上的另一个客户端执行可能影响结果的写入时,服务器将重新运行查询.它还将定期重新运行,以从其他服务器或修改数据库的外部进程中获取更改.因此,poll-and-diff可以为连接到同一服务器的客户端提供实时结果,但它会为外部写入带来明显的延迟.(默认值为10秒,这就是您所遇到的情况,另请参阅附图).
这可能会也可能不会对应用程序UX产生不利影响,具体取决于应用程序(例如,聊天不好,待办事项罚款).
这种方法很简单,并且易于理解缩放特性.但是,它不能很好地适应大量用户和大量数据.由于每次更改都会导致重新获取所有结果,因此CPU时间和网络带宽会与用户缩放O(N²).但是,Meteor会自动重复删除相同的查询,因此如果每个用户执行相同的查询,则可以共享结果.
您可以通过更改pollingIntervalMs和的值来调整poll-and-diff pollingThrottleMs.
您必须使用disableOplog: true选项在每个查询的基础上选择退出oplog尾部.
Meteor.publish("udpsPub", function (selector) {
return udps.find(selector, {
disableOplog: true,
pollingThrottleMs: 10000,
pollingIntervalMs: 10000
});
});
Run Code Online (Sandbox Code Playgroud)
其他链接:
https://blog.meteor.com/tuning-meteor-mongo-livedata-for-scalability-13fe9deb8908
如何使用pollingThrottle和pollingInterval?