【问题标题】:How to write scaleable code in Meteor如何在 Meteor 中编写可扩展的代码
【发布时间】:2015-02-09 00:22:52
【问题描述】:

我找到了一些关于 Meteor 及其扩展功能的文章,但没有一篇文章完全解释了如何做到这一点。他们中的大多数都在推广 Oplog Tailing,但这不是我作为程序员在编写代码时需要考虑的事情,对吧?

当我查看 modulus.io's pricing modal 时,他们为我提供了我的应用程序将使用的不同数量的伺服器,并声称“每个伺服器运行您的应用程序的一个实例”。运行多个实例是扩展 Meteor 应用程序的方式,对吧?

但是这会带来什么问题呢?可能会发生与数据库的竞争条件,对吗?我该如何处理这些?我是否需要设计我的应用程序以使竞争条件永远不会发生,或者我可以在它们发生时处理它们吗?

在考虑扩展之前,我曾经使用setInterval 来运行后台任务(例如,每小时向我发送一封包含一些数据的电子邮件)。但是,我不希望我的应用程序的每个实例都这样做,而只是一个。有什么办法解决这个问题? Meteor 可以吗?

【问题讨论】:

    标签: meteor


    【解决方案1】:

    要拥有一个可扩展的 Meteor 应用程序,您需要认真考虑几件事情。这里只是设计注意事项,代理技术或负载平衡方法较少。

    1) 避免写入或读取文件系统。 Meteor 的设计决定是只为生产中捆绑的文件提供Assets.getText/getBinary,但由于这个原因没有直观的方式来读取或写入文件。如果您有多个发电机,您可以获得一个请求,该请求只能在一个服务器上包含数据,而不能在另一个服务器上包含数据。使用 S3 或 GridFS 存储无人机上传的所有文件。

    2) 如果您的代码中有 Meteor.setInterval,它将与其他“无人机”同时触发,因此请确保您将其编码为通过 cron 作业与应用程序本身分开工作,或确保仅你的应用程序的一个无人机就可以做到这一点。

    3) 如果您在服务器端代码中任何与客户端实例无关的位置有myCollection.find().observe..,请避免使用它。这可能会产生竞争条件,因为他们都会同时获得信息。考虑创建一个单独的应用程序或确保只有一架无人机可以运行这些应用程序,否则它们将运行多次。

    4) 避免使用存储用户状态的变量。例如,您有一个像 UsersOnline = [] 这样的全局变量,您可以使用 Meteor 方法或发布方法进行更改。考虑将状态存储在 mongo 或 redis 上,以便每个无人机可以访问彼此的状态。

    5) 确保每架无人机都使用 oplog 而不是轮询间隔系统。否则,当另一架无人机更改数据时,您的应用程序的另一架无人机会出现延迟。

    小心使用查询以确保它们支持 oplog 拖尾。并非所有查询类型都受支持,尤其是在涉及观察者的情况下。您可以使用facts 包来确定这一点。

    6) 考虑只将无人机用于 websocket/ddp 服务器连接。那就是在你的应用程序前面使用WebAppInternals.setBundledJsCssPrefix('https://xxx.cloudfront.net');(如果你使用cloudfront,任何其他cdn 都可以正常工作)作为CDN。这可以确保您的应用程序加载速度很快,但每架无人机都不会一次又一次地提供静态资产。它还减少了它们的每个负载

    7) 小心您添加的任何软件包,并确保它们也遵循上述规定。

    关于 cron 作业/观察者

    您可以使用单独的 Meteor 应用程序,或者确保您的 Meteor 应用程序的单个实例执行此操作。如果您可以访问可以确定哪些无人机在线的 api,则可以让具有最低端口的无人机执行任务。请注意不要让一个人在一个固定端口上执行任务,因为考虑到冗余,那架无人机可能会离线。

    【讨论】:

    • 不错的答案!我要补充一点,synced-cron 可以用来代替setInterval。我不知道setBundledJsCssPrefix。有人应该写一篇关于如何设置的博客文章。
    • Collection.deny的回调呢?在允许插入评论之前,我想确保评论所属的帖子存在。这里可能会出现竞争条件,因为在我检查了帖子是否存在并且评论被插入数据库之前,帖子可能会被删除。我想这是一个普遍的问题,不仅限于Collection.denyDatabase transaction 是解决方案,对吗?可以在 Meteor 中使用它吗?
    • @PeppeL-G TLDR:目前我不知道解决并发问题的好方法。你是对的,在这种情况下它有点棘手,问题可以通过文档级锁或数据库事务来解决。问题是,由于这些发生在 mongodb 级别,我认为它们可以通过 oplog(尽管我不确定)——理论上,如果这是真的,观察者甚至可以在锁定的文档上看到数据。目前对此几乎无能为力,您可以使用集合级锁,但存在性能成本,文档级锁刚刚在 2.8 中引入。
    猜你喜欢
    • 2010-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-07
    • 2013-04-16
    • 2019-12-09
    • 2010-09-13
    相关资源
    最近更新 更多