停止需要很长时间使负载均衡器超时的操作
Posted
技术标签:
【中文标题】停止需要很长时间使负载均衡器超时的操作【英文标题】:Stop action that takes a long time timing out load balancer 【发布时间】:2017-10-13 11:45:04 【问题描述】:我正在尝试为发送电子邮件操作寻找解决方案,该操作可能需要很长时间并且会使 Rackspace 上的负载均衡器超时。我能找到与这个特定问题相关的唯一问题是:
keep load balancer from timing out during long operation
据我了解,我需要在主要慢动作完成时运行另一个动作以不断轮询并返回以保持活动状态。我的电子邮件操作包含以下内容:
var sendto = db.Users
.Where(b => b.Id == model.SentTo |
((model.SelectedRoles.Any(s => b.Roles.Select(h => h.RoleId).Contains(s)))
&& ((b.enrollment.Any(h => h.cohort.CourseID == model.CourseID) | model.CourseID == null))
&& (b.OrgID == model.OrgID | model.OrgID == null))).ToList();
foreach (var address in sendto)
string Body = "message goes here";
EmailConfig.SendMessageViaMailGun(filestoattach, address.Email, null, email.Subject, Body);
因此,创建了一个列表,然后循环发送电子邮件给列表中的每个人。上述问题中的 Async 方法答案似乎可以解决问题,但在 cmets 中我可以看到这被认为是一个坏主意。就最新 MVC 版本中的异步工作方式而言,它也已过时。
我的问题是,在负载均衡器完成时防止此操作超时的最佳方法是什么?
【问题讨论】:
您应该将该逻辑移到 Web 服务器之外。基本上,您的 Web 服务器应该排队一个请求(例如到 RabbitMQ),然后在其他地方运行的单独服务应该将它出列并发送电子邮件。 【参考方案1】:这实际上与异步无关,这是一个基础架构问题。
有两种方法可以执行长操作:
正确的方法:有一个后端服务器和一个在那里运行的进程+通过排队(或数据库轮询)与这个后端进程通信,然后客户端根据进度更新(存储在某个数据库中)并更新Web 服务器上的 UI。您还需要跟踪后端的进度,以便在意外关闭的情况下继续。
便宜的方法:在 Web 服务器上旋转一个不同的线程(或任务),让它执行操作,并从 javascript 轮询该线程的进度。但是,这可能会随时关闭(网络服务器回收)并且您会丢失操作(如果您对此感到满意),那么您需要继续操作并继续。一个粗略的方法是用 Task.Run 包装你所有的东西,然后立即返回,然后从 Javascript 中查询进度,但正如我上面所说,这很容易中断。
【讨论】:
您好,感谢您的回答。因此,例如,如果我进行设置,以便将电子邮件列表放入一个表格中,然后在发送电子邮件时更新该表格,并且当操作开始时,我使用 signalR 每 5 秒检查一次并将消息发送回页面一旦可以看到没有消息要结束,就在停止操作之前更新进度,这实际上就是您在 1 中所说的?这也可以防止负载均衡器超时?以上是关于停止需要很长时间使负载均衡器超时的操作的主要内容,如果未能解决你的问题,请参考以下文章
使用 Terraform 关闭/打开 Elastic Beanstalk 负载均衡器?