2011-05-25 25 views
2

在我们的网站上,我们的版主可能会审阅用户发布的内容。这也适用于视频,但视频需要先转换。这可以在夜间自动发生(通过Windows服务),也可以在主持人手动启动时立即发生。在服务器上运行多个操作

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

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

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

  1. 是否可以运行一个服务的多个实例?
  2. 我可以使服务更具动态性吗?例如,如果版主#2开始转换,它将启动服务,但是如果服务已经启动,是否可以将文件添加到列表中? (在服务开始时,我创建一个列表,从数据库中读取每个文件,寻找单个转换标志)
  3. 我知道我一直在想服务,是否有另一种方式来处理服务器上的操作可以处理版主的多个请求?

我意识到它可能听起来有点模糊,所以如果你有任何问题请问。也许我应该提供一些额外的信息,目前我是一名在实习中工作的学生,我的发起人并不真的想要一个文件几乎立即转换。他们希望在晚上进行转换,除非主持人手动为单个文件启动转换。此外,网站和文件系统位于同一台服务器上(数据库位于单独的服务器上)。基本上,这些工作将在网站运行的同一台服务器上完成(它目前不能分开)。他们担心服务器的性能。

如有任何意见,将不胜感激! 各种问候, 弗洛里斯

+0

我会感到惊讶,如果asp.net不具备某种支持工作队列。你创建一个固定数量的工作线程(可能是1个),完成一个工作单元,然后继续检查新工作,直到出现问题。 – bwawok 2011-05-25 17:16:13

+0

我不是100%确定您的特定要求,但您是否考虑过多线程和线程池? – 2011-05-25 17:22:19

+2

如果服务始终在运行,并且只查看由请求时间戳(简单队列)排序的表,该怎么办?因此,它会定期查询这个队列表并按顺序处理这些项目 - 它甚至可以将这些工作发送给多个线程。我错过了什么吗? – 2011-05-25 17:22:40

回答

2

国际海事组织的理智的方式来处理这是任何形式的队列。一个简单的数据库表(或一个redis列表)就足够了。你的服务应该简单地检查:有工作要做吗?我会这样做:做,否则睡一会儿,然后重新查询。作为一个可选的额外的东西,像pub/sub这样的东西可以用于更快的唤醒,所以在入队和出队之间没有可察觉的延迟 - 但理想情况下,队列/轮询循环应该没有额外的工作。

然后,批处理过程很简单:将工作添加到队列中。或者,您可能会优先考虑,以便主持人(或其他“现场”用户)在进行后台处理之前获得工作。

可能多次运行同一个exe作为服务(给它不同的服务名称),但每个都需要显式设置。说实话,在你的情况下它是不值得的:一个更简单的选择是让多个工作线程服务队列,这可以在一个进程中完成。

+0

所以基本上我只是用一个时间戳(当它被请求时)更新数据表并让一个服务运行并检查数据表是否在定时间隔。换句话说,服务一直在“运行”,但在没有工作时会睡觉。如果服务一直运行,服务器性能是否会大幅降低? – 2011-05-25 17:52:20

+0

@弗洛里斯根本没有。下一次您进入任务管理器时,启用“由所有用户显示任务”并查看有多少事情默默无闻。只要确保你使用被动等待(即任意Thread.Sleep,一个计时器或等待处理),而不是主动等待('while(DateTime.Now 2011-05-25 18:33:46

+0

如果你确实去了有一个队列,我会建议使用一个持久队列。无论是您创建的数据库管理队列,还是使用MSMQ(内置于Windows)或[Rhino Queues](http://ayende.com/blog/3480/rhino-queues)等现有的队列。 – hemp 2011-05-25 20:29:41

0

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

如果你有服务中的代码,你可以在下面的函数中运行它。如果不是,则将该函数保留在单个线程下方,然后以编程方式在该函数内启动该服务以执行转换。这个问题的答案可以根据您是否拥有服务代码并可以进行更改而发生重大变化。如果您可以修改它,您可以将相同类型的逻辑放入服务中。

在你的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 
     } 
     } 
+0

你的意思是删除手动启动版主转换的选项吗?如果是这样,你的意思是每个视频在当天上传一段时间后都会更新。 如果每个视频在上传一段时间后都会更新,它可能会耗尽服务器的性能。或者我在这里弄错了吗? 如果我仍然保留主持人手动启动转换的选项(但让他们用请求更新数据库并让它检查您的方法),您的情况可能会有效。 – 2011-05-25 18:03:06

+0

嗯,这个想法是,这个过程不断地转换文件,消除手动转换请求的需要。我明白你说的是什么。如果您只是希望能够处理多个手动请求,则可以使用相同类型的逻辑,您只需要拥有一个表来跟踪手动请求转换的文件。然后,该过程应循环并运行每个文件。 – Jemes 2011-05-25 18:53:58

+0

事实上,相同的逻辑将起作用。这将是一个说服我的推销员这样做的问题。只要它不会在代码未运行(睡眠)时耗尽网站性能。 – 2011-05-25 20:39:47

相关问题