在流星中处理长服务器端计算

时间:2016-02-29 18:25:06

标签: javascript node.js algorithm meteor

我在流星JS中使用jimp(https://www.npmjs.com/package/jimp)来生成图像服务器端。换句话说,我正在计算'使用递归算法的图像像素。该算法需要相当长的时间才能完成。

我遇到的问题是,这似乎完全阻止了流星服务器。在生成图像时尝试访问网页的用户被迫等待。因此,网站根本没有呈现。

是否有任何(流星)方法在线程或其他东西中运行繁重的递归算法,以便它不会阻止整个网站?

3 个答案:

答案 0 :(得分:2)

节点(以及因此流星)在单个进程中运行,该进程阻止CPU活动。简而言之,当你受IO限制时,节点工作得非常好,但只要你做任何计算限制的事情,你就需要另一种方法。

正如上面的评论中所建议的那样,您需要将此CPU密集型活动卸载到另一个可能位于同一服务器上的进程(如果您有多个核心)或另一个服务器。

我们在Edthena遇到类似的问题,我们需要对我们视频文件的一部分进行转码。目前我决定使用基于流星的解决方案,因为它很容易设置。这就是我们所做的:

  1. 当需要进行新的转码作业时,我们会在数据库中插入“视频作业”文档。

  2. 在单独的服务器上(我们在转码时最大化完整的CPU),我们有一个应用程序,可以这样调用observe

  3. Meteor.startup(function () {
      // Listen for non-failed transcode jobs in creation order. Use a limit of 1 to
      // prevent multiple jobs of this type from running concurrently.
      var selector = {
        type: 'transcode',
        state: { $ne: 'failed' },
      };
      var options = {
        sort: { createdAt: 1 }, limit: 1,
      };
      VideoJobs.find(selector, options).observe({
        added: function (videoJob) {
          transcode(videoJob);
        }, });
    });
    

    正如评论所示,这一次只允许调用一个作业,这可能是您想要的也可能不是。这具有进一步的限制,您只能在一个应用程序实例上运行它(多个实例调用observe将同时完成该作业)。所以这是一个相当简单的工作队列,但它可能会在一段时间内适用于您的目的。

    随着您的扩展,您可以使用更强大的机制来出列和处理亚马逊的sqs服务等任务。您还可以探索其他基于流媒体的解决方案,例如job-collection

答案 1 :(得分:1)

我相信你正在寻找Meteor.defer(yourFunction)

相关的Kadira文章:https://kadira.io/academy/meteor-performance-101/content/make-your-app-faster

答案 2 :(得分:0)

感谢您的评论和解答!它似乎现在正在运作。我所做的就是大卫所说的。我在同一台服务器上运行一个流星应用程序。这个应用程序处理图像的生成。然而,这导致应用程序仍在吞噬所有处理能力。

因此,我在PID上使用renice命令在生成算法上设置了稍低的优先级。 (https://www.nixtutor.com/linux/changing-priority-on-linux-processes/)这有效!每当用户登录网站时,其他(客户端)流星应用程序优先于生成算法。现在绝对没有任何延迟。

我现在唯一的问题是每当服务器重新启动时,我都不得不重新运行或运行(重新)好的命令。

由于我使用meteor up进行部署,因此两个应用程序都运行相同的用户和相同的命令&#39 ;: node main.js.我目前正试图弄清楚如何在meteor的启动脚本中运行nice命令。 (位于/etc/init/.conf)