【问题标题】:Running multiple operations on the server在服务器上运行多个操作
【发布时间】:2011-05-25 17:11:46
【问题描述】:

在我们的网站上,我们的版主可以查看人们发布的内容。这也适用于视频,尽管需要先转换视频。这要么在晚上自动发生(通过 Windows 服务),要么在主持人手动启动时更早发生。

现在,最后一部分是我的问题的来源。起初我以为我只是编写一个单独的服务来处理转换。每当主持人开始转换时,数据库中的记录就会更新,以将其标记为单次转换。然后服务将处理其余部分。当它只是一个文件时,这一切都很好。

但是想象一下这种情况,主持人 #1 启动服务。该服务运行并开始文件的转换。在此过程中,主持人 #2 开始转换不同的文件。它将尝试启动服务,但由于它已经启动而失败。该文件将被标记为单独转换,但不会转换,因为它无法启动服务。

现在我正在寻找新的想法来解决这个问题。

  1. 是否可以运行一项服务的多个实例?
  2. 我可以让服务更有活力吗?例如,如果主持人 #2 启动转换,它将启动服务,但如果服务已经启动,是否可以将文件添加到列表中? (在服务启动时,我创建了一个列表,该列表从数据库中读取每个文件以查找单个转换标志)
  3. 我知道我一直在考虑服务,是否有另一种方法来处理服务器上的操作,可以处理版主的多个请求?

我知道这听起来可能有点模糊,所以如果您有任何问题,请尽管提问。

编辑:也许我应该提供一些额外的信息,目前我是一名正在实习的学生,我的发起人并不想几乎立即转换文件。他们希望在晚上进行转换,除非版主为单个文件手动启动它。此外,网站和文件系统位于同一台服务器上(数据库位于单独的服务器上)。基本上,工作将在网站运行所在的同一台服务器上完成(目前无法分离)。他们担心服务器的性能。

任何评论将不胜感激! 亲切的问候, 弗洛里斯

【问题讨论】:

  • 如果 asp.net 不支持某种工作队列,我会感到惊讶。您创建了固定数量的工作线程(在您的情况下可能是 1 个)来执行一个工作单元,然后继续检查要执行的新工作,直到出现某些情况。
  • 我不能 100% 确定您的特定要求,但您是否考虑过多线程和线程池?
  • 如果服务一直在运行并且只是查看一个按请求时间戳排序的表(一个简单的队列)怎么办?因此,它会定期查询这个队列表并按顺序处理项目——它甚至可以将工作发送到多个线程。我错过了什么吗?
  • @Bwawok 和 xman:我对那个领域有点陌生,但我愿意研究一下。这意味着我必须放弃我猜想的服务理念。您能否提供一些链接,让我可以了解更多信息?或者在 msdn 或 google 上可以找到足够的东西吗? @Ryan:这可行,但要做到这一点,我需要一直运行该服务,对吗?
  • @Ryan:忘记我最后的评论,你已经说过它一直在运行。

标签: c# asp.net windows-services


【解决方案1】:

IMO 处理此问题的明智方法是使用任何形式的队列。一个简单的数据库表(或 redis 列表)就足够了。您的服务应该简单地检查:有工作要做吗?我会这样做:这样做,否则睡一小段时间并重新查询。作为一个可选的附加功能,可以使用 pub/sub 之类的东西来加快唤醒速度,因此在入队和出队之间没有明显的延迟 - 但理想情况下,队列/轮询循环应该在没有这个额外的情况下工作。

然后,批处理过程很简单:将工作添加到队列中。或者,您可以允许优先级,以便版主(或其他“实时”用户)在后台处理之前获得工作。

可以将同一个 exe 作为服务多次运行(给它不同的服务名称),但每次都需要显式设置。老实说,在您的场景中这样做并不值得:更简单的选择是让多个工作线程为队列提供服务,这可以在单个进程中完成。

【讨论】:

  • 所以基本上我只是用时间戳更新数据表(当它被请求时)并让服务运行并检查数据表是否按时间间隔。换句话说,服务一直在“运行”,但在没有工作时会休眠。如果一个服务一直在运行,它会不会大大降低服务器的性能?
  • @Floris 几乎没有。下次你在任务管理器中,启用“显示所有用户的任务”,看看有多少事情是无声无息的。只要确保您使用被动等待(即 Thread.Sleep、计时器或等待句柄),而不是主动等待 (while (DateTime.Now < nextRun) {} // very bad)
  • 如果你使用队列,我建议使用持久队列。您创建的数据库管理队列,或使用现有的队列,如 MSMQ(内置于 Windows)或 Rhino Queues 等。
  • @hemp - 刚刚意识到这是模棱两可的 - 绝对是的,它应该是持久的。我的意思是说数据库表。虽然我现在喜欢 redis,所以对于我自己的代码,我可能会使用 redis 列表。这也让我免费获得 pub/sub :)
【解决方案2】:

我会删除版主手动启动服务的选项(只是我的偏好)并启动一个线程来轮询您的数据库以查找需要转换的文件。

如果您有服务中的代码,您可以在下面的函数中运行它。如果不是,则将该函数保持在单个线程之下,并以编程方式在该函数中启动服务以执行转换。这个问题的答案可能会发生巨大变化,具体取决于您是否拥有服务代码并且可以进行更改。如果您可以修改它,您可以将这种相同类型的逻辑放入服务中。

在您的 Global.asax.cs 的 Application_Start 事件中,我将启动一个新线程,该线程不断循环并检查您的数据库

using System.Threading;


   void Application_Start(object sender, EventArgs e)        
   {
        Thread VideoConversionThread = new System.Threading.Thread(new ThreadStart(VideoConversion));
        VideoConversionThread.Name = "VideoConversion";
        VideoConversionThread.IsBackground = true;
        VideoConversionThread.Start();
    }
    private void VideoConversion()
    {
        while (true)
        {
            //Get Count of records that need conversion.
            if(Count > 0)
            {
                 var records = //GetRecords from database that require conversion
                 foreach(var record in records)
                 {
                     //either spawn a seperate worker thread for each record or perform tasks here

                     //perform conversion
                     //update database to mark item as completed
                     // or 
                     //in this single thread, you could also start the service
                     //(does the service Stop when it's finished?) 
                     //(if so, you can monitor and wait for it to be stopped for each record)
                 }
             }
             Thread.Sleep(5000); //sleep
         }
      }

【讨论】:

  • 您的意思是删除版主手动开始转换的选项吗?如果是这样,您的意思是每个视频将在同一天上传后的某个时间进行更新。如果每个视频在上传后一段时间都会更新,则可能会消耗服务器的性能。还是我在这里弄错了?如果我仍然保留版主手动启动转换的选项,您的情况可能会奏效(但只需让他们通过请求更新数据库并让它检查您的方法)。
  • 嗯,这个想法是这个过程不断转换文件,无需手动转换请求。不过我明白你在说什么。如果您只想能够处理多个手动请求,则可以使用相同类型的逻辑,您只需要有一个表来跟踪手动请求转换的文件。然后,该过程应该循环并针对每个文件运行。
  • 确实,同样的逻辑也可以。这将是说服我的发起人这样做的问题。只要在代码未运行(休眠)时不会消耗网站性能。
  • 睡眠会占用任何 CPU,但其想法是在开始循环之前让睡眠仅暂停一小会儿(这样经常检查数据库)。数据库检查将占用 little cpu,这就是为什么我首先在​​那里检查记录的 COUNT,这应该是一个非常快速且轻松的查询。这一切都取决于您的数据库/硬件,但我无法想象检查记录数的循环每隔几秒就会执行超过 1% 的 cpu。您可以通过编写一个测试应用程序来轮询数据库并每隔几秒计算一次记录来快速测试...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-25
  • 1970-01-01
  • 1970-01-01
  • 2013-04-21
  • 2018-05-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多