加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net – 保持负载均衡器在长时间运行期间超时

发布时间:2020-12-16 03:27:58 所属栏目:asp.Net 来源:网络整理
导读:我正在使用ASP.NET MVC 4来接受最大30 mb的视频上传.将视频上传到网站后,视频将使用HttpWebRequest发布到第三方Web服务.此上传到第三方服务必须完成并返回响应,然后我的网站才能向浏览器返回响应.在Rackspace Cloud Sites上,负载均衡器有30秒超时.如果我的站
我正在使用ASP.NET MVC 4来接受最大30 mb的视频上传.将视频上传到网站后,视频将使用HttpWebRequest发布到第三方Web服务.此上传到第三方服务必须完成并返回响应,然后我的网站才能向浏览器返回响应.在Rackspace Cloud Sites上,负载均衡器有30秒超时.如果我的站点没有通过负载均衡器返回响应30秒,则负载均衡器会向浏览器返回超时错误并终止请求.

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

我正在寻找两件事 – 在上传过程中,我将什么作为数据发送回浏览器?我的实际响应是JSON,所以如果我能在最后保持我的常规JSON响应,那将是理想的.

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

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

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

解决方法

这就是我解决问题的方法.此解决方案应适用于任何使用负载均衡器且具有不合理超时的.net主机. Rackspace Cloud Sites在其负载均衡器上有30秒超时.亚马逊和Azure有更长的超时时间,但如果你碰巧有一个长时间运行的操作,这仍然可能是一个有用的解决方案.

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

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

最后,我在实际的json响应周围手动构建一个容器json对象,这样我就可以将“keep alive”数据作为有效json的一部分发送回浏览器.一个稍微丑陋的黑客,但它的作品!

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,则有更新的方法可以在mvc控制器中执行异步,而不依赖于AsyncController类.

这个站点很有用,并解释了如何在各种版本的.Net框架中在asp.net mvc中进行异步操作:

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读