防止负载均衡器在长时间运行期间超时 [英] keep load balancer from timing out during long operation

查看:273
本文介绍了防止负载均衡器在长时间运行期间超时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用ASP.NET MVC 4接受最大30 mb的视频上传.将视频上传到站点后,然后使用HttpWebRequest将视频发布到第三方Web服务.必须先完成向第三方服务的上传,然后返回响应,然后我的网站才能向浏览器返回响应.在Rackspace Cloud Sites上,负载均衡器有30秒的超时时间.如果30秒钟内没有通过负载平衡器从我的站点返回任何响应,则负载平衡器将超时错误返回到浏览器,并且请求被终止.

I'm using ASP.NET MVC 4 to accept a video upload of up to 30 mb in size. Once the video is uploaded to the site, the video is then posted to a 3rd party web service using a HttpWebRequest. This upload to the 3rd party service must complete and return a response before my site can return a response to the browser. On Rackspace Cloud Sites, the load balancer has a 30 second timeout. If no response is returned from my site through the load balancer for 30 seconds, then load balancer returns a timeout error to the browser and the request is terminated.

因此,我被告知需要发生的事情是,在我的站点将视频发送到第三方系统时,我的站点需要通过将数据发送回浏览器来保持连接状态,以便负载均衡器不会t超时.您将如何完成这项任务?

So what I've been told needs to happen is that my site needs to keep the connection alive by sending data back to the browser while my site is sending the video to the 3rd party system, so that the load balancer doesn't timeout. How would you accomplish this task?

我正在寻找两件事-上传时我该如何将数据作为数据发送回浏览器?我的实际响应是JSON,因此,如果我可以在结尾保留常规的JSON响应,那将是理想的选择.

I'm looking for 2 things - What do I send back as data to the browser while the upload is happening? My actual response is JSON, so if I can keep my regular JSON response at the end, that would be ideal.

最后,如何在同时发送保持活动数据的同时将我的HttpWebRequest上传到第三方?

And finally, how do I execute my HttpWebRequest upload to the 3rd party while sending the keep-alive data at the same time?

-

作为参考,这是来自机架空间云的负载平衡器连接超时文档: http://www.rackspace.com/knowledge_center/article/connection-timed-out-error-message-1

For reference, this is the load balancer connection timeout doc from rackspace cloud: http://www.rackspace.com/knowledge_center/article/connection-timed-out-error-message-1

他们没有为这个问题提供任何具体的解决方案.

They don't offer up any concrete solutions for this problem.

推荐答案

这是我解决问题的方式.此解决方案应适用于使用负载平衡器且超时不合理的任何.net托管. Rackspace Cloud站点的负载均衡器有30秒的超时时间. Amazon和Azure的超时时间更长,但是如果您碰巧需要长时间运行,那么这仍然可能是一个有用的解决方案.

Here's how I solved my problem. This solution should be applicable to any .net hosting that uses a load balancer with an unreasonable timeout. Rackspace Cloud Sites have a 30 second timeout on their load balancer. Amazon and Azure have longer timeouts, but this still might be a useful solution if you happen to have a long-running operation.

在asp.net mvc 4中,您可以将控制器更改为从AsyncController继承.这使您可以剥离异步任务,然后等待它们完成.此解决方案创建了一个保持活动"任务,该任务每10秒钟通过asp.net响应将数据发送回去,以便负载平衡器能够检测到活动并且不会超时.该任务将一直运行,直到看到uploadFinished变量设置为true为止.

In asp.net mvc 4 you can change your controller to inherit from AsyncController. This allows you to spin off async tasks and then await their completion. This solution creates a "keep alive" task which sends data back through the asp.net Response every 10 seconds so that the load balancer detects activity and doesn't timeout. This task runs until it sees that the uploadFinished variable is set to true.

另一个任务执行长时间运行的上载,或者在asp.net mvc控制器结束正在处理的Web请求之前需要完成的任何任务.长时间运行的操作完成后,将uploadFinished变量设置为true.

The other task performs the long-running upload, or whatever task needs to be completed before the asp.net mvc controller ends the web request it is handling. After the long-running operation is completed it sets the uploadFinished variable to true.

最后,我将围绕实际的json响应手动构造一个容器json对象,以便我可以将保持活动"数据作为有效json的一部分,并将其发送回浏览器.有点难看的骇客,但行得通!

Finally, I'm manually constructing a container json object around the actual json response so that I can have the "keep alive" data be part of valid json that gets sent back to the browser. A slightly ugly hack, but it works!

using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;
using System.Web.Script.Serialization;

namespace MvcApplication4.Controllers
{
    public class ExampleController : AsyncController
    {

        [HttpPost]
        public string Upload(UploadModel model, HttpPostedFileBase videoFile)
        {
            // when using jquery ajax form for upload
            // IE requires text/plain content type
            // otherwise it will try to open the response as a file
            // instead of pass the response back to your javascript
            if (Request.AcceptTypes.Contains("application/json"))
            {
                Response.ContentType = "application/json";
            }
            else
            {
                Response.ContentType = "text/plain";
            }

            // start json object
            Response.Write("{\"keepalive\":\"");
            Response.Flush();

            Task[] tasks = new Task[2];
            tasks[0] = Task.Factory.StartNew(() => DoKeepAlive());
            tasks[1] = Task.Factory.StartNew(() => DoUpload(model, videoFile));
            Task.WaitAll(tasks);

            // end keepalive json property
            Response.Write("\",\"data\":");

            // insert actual response data
            JavaScriptSerializer json = new JavaScriptSerializer();
            Response.Write(json.Serialize(uploadResponse));

            // end json object
            Response.Write("}");

            return "";
        }

        public bool uploadFinished = false;
        public UploadResponseModel uploadResponse = null;

        public void DoUpload(UploadModel model, HttpPostedFileBase videoFile)
        {
            // do upload to 3rd party
            MyServiceClient c = new MyServiceClient();
            uploadResponse = c.UploadVideo(model, videoFile);
            uploadFinished = true;
        }

        public void DoKeepAlive()
        {
            // send . every 10 seconds
            while (!uploadFinished)
            {
                Response.Write(".");
                Response.Flush();
                Thread.Sleep(10000);
            }
        }
    }
}

此解决方案取决于.Net 4来进行异步处理.如果您拥有.Net 4.5,则可以在不依赖于AsyncController类的mvc控制器中使用更新的方法来进行异步操作.

This solution depends on .Net 4 to do the async stuff. If you have .Net 4.5 there are newer ways to do async in your mvc controllers that don't depend on the AsyncController class.

此站点很有帮助,并说明了如何在.net框架的各种版本中的asp.net mvc中执行异步操作:

This site is helpful and explains how to do async operations in asp.net mvc in various versions of the .Net framework:

http://dotnet.dzone.com/news/net-zone-evolution

这篇关于防止负载均衡器在长时间运行期间超时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆