草庐IT

node.js - Meteor MongoDB 订阅以 10 秒的间隔而不是实时传递数据

coder 2023-10-29 原文

我认为这更像是一个 MongoDB 问题,而不是一个 Meteor 问题,所以如果您对 mongo 了解很多但对 meteor 一无所知,请不要害怕。

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


实际问题

我有一个 meteor该项目不断将数据添加到数据库中,并在应用程序中实时显示它们。它在开发模式下完美运行,但在构建和部署到生产环境时出现奇怪的行为。它的工作原理如下:

  • 一个单独运行的小脚本收集广播 UDP 包并将它们推送到 mongo 集合中
  • 然后 Meteor 应用程序发布该集合的一个子集,以便客户端可以使用它
  • 客户订阅并实时更新其 View

这里的问题是,订阅似乎每 10 秒才获取一次数据,而这些 UDP 包每秒到达并被插入数据库几次。这使得应用程序表现得很奇怪

在UDP报文的收集上最为引人注意,但不仅限于此。它发生在每个订阅的集合中,即使是那些没有被外部脚本填充的集合

直接查询数据库,无论是通过 mongo shell 还是通过应用程序,都会显示文档确实按预期添加和更新。该出版物只是没有注意到并且似乎默认以 10 秒的间隔进行查询

Meteor 在 MongoDB 上使用 oplog tailing 来找出何时添加/更新/删除文档并根据此更新发布

谁比我有更多 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
});

版本:

发展:

  • Node 8.9.3
  • 蒙戈 3.2.15

生产:

  • Node 8.6.0
  • 蒙戈 3.4.10

最佳答案

Meteor 使用两种操作模式在没有任何内置实时功能的 mongodb 之上提供实时。 poll-and-diffoplog-tailing

1 - Oplog-tailing

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

2 - 轮询和差异

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

这可能会或可能不会对应用程序的用户体验产生不利影响,具体取决于应用程序(例如,不适合聊天,适合待办事项)。

这种方法很简单,并且提供易于理解的缩放特性。但是,它不能很好地适应大量用户和大量数据。由于每次更改都会导致重新获取所有结果,因此 CPU 时间和网络带宽与用户的比例为 O(N²)。不过,Meteor 会自动删除相同的查询,因此如果每个用户都执行相同的查询,则可以共享结果。

您可以通过更改 pollingIntervalMspollingThrottleMs 的值来调整 poll-and-diff。

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

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

附加链接:

https://medium.baqend.com/real-time-databases-explained-why-meteor-rethinkdb-parse-and-firebase-dont-scale-822ff87d2f87

https://blog.meteor.com/tuning-meteor-mongo-livedata-for-scalability-13fe9deb8908

How to use pollingThrottle and pollingInterval?

关于node.js - Meteor MongoDB 订阅以 10 秒的间隔而不是实时传递数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48336790/

有关node.js - Meteor MongoDB 订阅以 10 秒的间隔而不是实时传递数据的更多相关文章

  1. ruby - rails 3 redirect_to 将参数传递给命名路由 - 2

    我没有找到太多关于如何执行此操作的信息,尽管有很多关于如何使用像这样的redirect_to将参数传递给重定向的建议:action=>'something',:controller=>'something'在我的应用程序中,我在路由文件中有以下内容match'profile'=>'User#show'我的表演Action是这样的defshow@user=User.find(params[:user])@title=@user.first_nameend重定向发生在同一个用户Controller中,就像这样defregister@title="Registration"@user=Use

  2. ruby-on-rails - 如何生成传递一些自定义参数的 `link_to` URL? - 2

    我正在使用RubyonRails3.0.9,我想生成一个传递一些自定义参数的link_toURL。也就是说,有一个articles_path(www.my_web_site_name.com/articles)我想生成如下内容:link_to'Samplelinktitle',...#HereIshouldimplementthecode#=>'http://www.my_web_site_name.com/articles?param1=value1¶m2=value2&...我如何编写link_to语句“alàRubyonRailsWay”以实现该目的?如果我想通过传递一些

  3. ruby - 在 Ruby 中按名称传递函数 - 2

    如何在Ruby中按名称传递函数?(我使用Ruby才几个小时,所以我还在想办法。)nums=[1,2,3,4]#Thisworks,butismoreverbosethanI'dlikenums.eachdo|i|putsiend#InJS,Icouldjustdosomethinglike:#nums.forEach(console.log)#InF#,itwouldbesomethinglike:#List.iternums(printf"%A")#InRuby,IwishIcoulddosomethinglike:nums.eachputs在Ruby中能不能做到类似的简洁?我可以只

  4. 【Java 面试合集】HashMap中为什么引入红黑树,而不是AVL树呢 - 2

    HashMap中为什么引入红黑树,而不是AVL树呢1.概述开始学习这个知识点之前我们需要知道,在JDK1.8以及之前,针对HashMap有什么不同。JDK1.7的时候,HashMap的底层实现是数组+链表JDK1.8的时候,HashMap的底层实现是数组+链表+红黑树我们要思考一个问题,为什么要从链表转为红黑树呢。首先先让我们了解下链表有什么不好???2.链表上述的截图其实就是链表的结构,我们来看下链表的增删改查的时间复杂度增:因为链表不是线性结构,所以每次添加的时候,只需要移动一个节点,所以可以理解为复杂度是N(1)删:算法时间复杂度跟增保持一致查:既然是非线性结构,所以查询某一个节点的时候

  5. ruby - 如何将 Puma::Configuration 传递给 Sinatra? - 2

    这是我的网络应用:classFront我是这样开始的(请不要建议使用Rack):Front.start!这是我的Puma配置对象,我不知道如何传递给它:require'puma/configuration'Puma::Configuration.new({log_requests:true,debug:true})说真的,怎么样? 最佳答案 配置与您运行的方式紧密相关puma服务器。运行的标准方式puma-pumaCLI命令。为了配置puma配置文件config/puma.rb或config/puma/.rb应该提供(参见examp

  6. jquery - 如何将 AJAX 变量从 jQuery 传递到他们的 Controller ? - 2

    我有一个电子邮件表格。但是我正在制作一个测试电子邮件表单,用户可以在其中添加一个唯一的电子邮件,并让电子邮件测试将其发送到该特定电子邮件。为了简单起见,我决定让测试电子邮件通过ajax执行,并将整个内容粘贴到另一个电子邮件表单中。我不知道如何将变量从我的HAML发送到我的Controllernew.html.haml-form_tagadmin_email_blast_pathdoSubject%br=text_field_tag'subject',:class=>"mass_email_subject"%brBody%br=text_area_tag'message','',:nam

  7. ruby-on-rails - 只有当不是 nil 时才执行映射? - 2

    如果names为nil,则以下中断。我怎样才能让这个map只有在它不是nil时才执行?self.topics=names.split(",").mapdo|n|Topic.where(name:n.strip).first_or_create!end 最佳答案 其他几个选项:选项1(在其上执行map时检查split的结果):names_list=names.try(:split,",")self.topics=names_list.mapdo|n|Topic.where(name:n.strip).first_or_create!e

  8. 由于 libgmp.10.dylib 的问题,Ruby 2.2.0 无法运行 - 2

    我刚刚安装了带有RVM的Ruby2.2.0,并尝试使用它得到了这个:$rvmuse2.2.0--defaultUsing/Users/brandon/.rvm/gems/ruby-2.2.0dyld:Librarynotloaded:/usr/local/lib/libgmp.10.dylibReferencedfrom:/Users/brandon/.rvm/rubies/ruby-2.2.0/bin/rubyReason:Incompatiblelibraryversion:rubyrequiresversion13.0.0orlater,butlibgmp.10.dylibpro

  9. ruby - ri 有空文件 – Ubuntu 11.10, Ruby 1.9 - 2

    我正在运行Ubuntu11.10并像这样安装Ruby1.9:$sudoapt-getinstallruby1.9rubygems一切都运行良好,但ri似乎有空文档。ri告诉我文档是空的,我必须安装它们。我执行此操作是因为我读到它会有所帮助:$rdoc--all--ri现在,当我尝试打开任何文档时:$riArrayNothingknownaboutArray我搜索的其他所有内容都是一样的。 最佳答案 这个呢?apt-getinstallri1.8编辑或者试试这个:(非rvm)geminstallrdocrdoc-datardoc-da

  10. ruby-on-rails - Rails 格式验证——字母数字,但不是纯数字 - 2

    什么是测试格式验证的最佳方法让我们说一个用户名,使用字母数字的正则表达式,但不是纯数字?我一直在我的模型中使用以下验证validates:username,:format=>{:with=>/^[a-z0-9]+[-a-z0-9]*[a-z0-9]+$/i}数字用户名(例如“342”)通过了验证,这是我不想要的。 最佳答案 您想“向前看”一封信:/\A(?=.*[a-z])[a-z\d]+\Z/i 关于ruby-on-rails-Rails格式验证——字母数字,但不是纯数字,我们在Sta

随机推荐