C# Azure上的MongoDB连接问题

C# Azure上的MongoDB连接问题,c#,mongodb,azure,C#,Mongodb,Azure,我们在Azure网站上部署了一个ASP.NET MVC应用程序,该网站连接到MongoDB并执行读写操作。应用程序以迭代方式执行此操作。每分钟几千次 我们使用Autofac初始化C#驱动程序,并将MaxConnectionIdleTime设置为45秒,如和其他一些地方所建议的那样 我们仍然收到大量以下错误: 无法从传输连接读取数据:连接 尝试失败,因为关联方没有正确响应 一段时间后,或建立的连接失败,因为 连接的主机无法响应。方法 消息:“:{”ClassName:“System.IO.IOEx

我们在Azure网站上部署了一个ASP.NET MVC应用程序,该网站连接到MongoDB并执行读写操作。应用程序以迭代方式执行此操作。每分钟几千次

我们使用Autofac初始化C#驱动程序,并将MaxConnectionIdleTime设置为45秒,如和其他一些地方所建议的那样

我们仍然收到大量以下错误:

无法从传输连接读取数据:连接 尝试失败,因为关联方没有正确响应 一段时间后,或建立的连接失败,因为 连接的主机无法响应。方法 消息:“:{”ClassName:“System.IO.IOException”,“消息”:“无法” 从传输连接读取数据:连接尝试失败 因为关联方在一段时间后未作出适当回应 时间,或建立的连接失败,因为连接的主机已 没有回应

我们在连接Azure上同一数据中心/区域的VM上部署的MongoDB实例时,以及连接外部PaaS MongoDB提供程序时,都会出现此错误

我在本地计算机上运行相同的代码并连接到相同的数据库,但我没有收到这些错误。只有在我将代码部署到Azure网站时才会收到这些错误。
有什么建议吗?

您是否在VM中使用mongoDB?这似乎是一个网络问题。应该会发生这种暂时性故障,因此您最好实现重试模式或使用Polly之类的lib来实现:

Policy
    .Handle<IOException>()
    .Retry(3, (exception, retryCount) =>
    {
        // do something 
    });
策略
.Handle()
.重试(3,(异常,重试计数)=>
{
//做点什么
});

每分钟几千个请求是一个很大的负载,唯一正确的方法是控制和限制任何时候可以运行的最大线程数

由于没有太多关于你是如何实现这一点的信息,我将介绍一些可能的情况


实验时间到了。。。 常数:

  • 要处理的项目:
    • 每秒50,换句话说
    • 每分钟3000,还有一种方式来看待它
    • 每小时18万
变量:

  • 数据传输速率:

    • 无论我们做什么,每秒可以传输多少数据都将起到一定作用,这将随时间的不同而变化

      我们唯一能做的就是从不同的cpu发出更多的请求,以分配我们来回发送的流量的权重

  • 处理能力:

    • 我假设你在
      WebJob
      中有这个,而不是在MVC站点中自己编码。它效率很低,不适合你试图达到的目的。通过使用WebJob,我们可以将工作项排队等待其他
      WebJob
      处理。所讨论的队列是

      Azure队列存储是用于存储大量消息的服务 可以通过认证从世界任何地方访问 使用HTTP或HTTPS进行呼叫。单个队列消息最多可达64 KB 一个队列可以包含数百万条消息,最多可达 存储帐户的容量限制。存储帐户最多可包含 到200 TB的blob、队列和表数据。请参阅Azure存储 存储帐户详细信息的可扩展性和性能目标 容量

      队列存储的常见用途包括:

      • 创建要异步处理的积压工作
      • 将消息从Azure Web角色传递到Azure工作角色
问题:

  • 我们正在尝试每秒完成50个事务,因此如果我们使用50个线程,则每个事务应在1秒内完成。我们的45秒超时在这一点上没有任何意义
  • 我们预计50个线程将同时运行,并且在一个cpu上每秒不到一秒地完成。(我在这里夸大了一点,只是为了说明一点……但想象一下,每秒钟下载50个文本文件。处理它,然后尝试将其发送回同事,希望他们甚至准备好捕获它)
  • 我们需要有一个重试逻辑,如果在3次尝试后项目没有得到处理,则需要将它们放回队列中。理想情况下,我们应该为服务器提供更多的时间来响应,而不是每次失败一秒钟,假设我们在第一次失败时给它2秒钟的中断,然后是4秒钟,然后是10秒钟,这将大大增加ase是我们保存/检索所需数据的可能性
  • 我们假设我们的MongoDb每秒可以处理这个数量的请求。如果你还没有,开始考虑扩展它的方法,问题不在于它是一个MongoDb,数据层可以是任何东西,而是我们从单个源发出这个数量的请求最有可能的原因是你的问题
解决方案:

  • 设置
    WebJob
    并将其命名为
    EnqueueJob
    。此
    WebJob
    只有一个目的,即将要在
    队列存储中处理的工作项排队
  • 创建一个名为
    WorkItemQueue
    队列存储容器
    ,此队列将作为下一步的触发器,并启动我们的向外扩展操作
  • 创建另一个名为
    DequeueJob
    WebJob
    。此
    WebJob
    还有一个唯一的目的,将工作项从
    WorkItemQueue
    中出列,并向数据存储发出请求
  • 配置
    DequeueJob
    <!-- Increase timeout to five minutes -->
    <httpRuntime executionTimeout="300" />
    
    string html = string.Empty;
    string uri = "http://google.com";
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
    request.Timeout = TimeSpan.FromMinutes(5);
    
    using (HttpWebResponse response = (HttpWebResonse)request.GetResponse())
    using (Stream stream = response.GetResponseStream())
    using (StreamReader reader = new StreamReader(stream))
    {
        html = reader.ReadToEnd();
    }