500 - время запроса истекло

У меня есть script, который работает около 4 минут 30 секунд, и я изменил время ожидания по умолчанию на 3600 секунд на странице конфигурации моей веб-страницы aspx.

Он не вернул 500 - ошибка времени ожидания запроса на версию разработки и загруженную версию на IIS 8.

Однако, когда я загрузил его на сайт live на azure, он возвращает 500 - Ошибка времени ожидания запроса.

Заменяет ли Azure эти параметры?

Configs:

<configuration>
  <system.web>
    <httpRuntime executionTimeout="3600" />
    <sessionState timeout="360" />
    <compilation debug="false" targetFramework="4.0">
      <assemblies>
        <add assembly="System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>
        <add assembly="System.Web.Extensions.Design, Version=4.0.0.0, Culture=neutral/>
      </assemblies>
    </compilation>
  </system.web>
</configuration>

EDIT:

Я добавил SCM_COMMAND_IDLE_TIMEOUT в параметры приложения azure со значением 3600, но он не исправил ошибку, пытаясь улучшить производительность моего кода сейчас:

Оригинал:

Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();

Dictionary<int, Dictionary<DateTime, float>> d_PhoneNo_DateDataList = new Dictionary<int, Dictionary<DateTime, float>>();

string sqlcommand = "SELECT ---- FROM ---- INNER JOIN ---- ON ---- = ---- WHERE [email protected] AND date BETWEEN @Date1 AND @Date2";
string strConnectionString = ConfigurationManager.ConnectionStrings["---"].ConnectionString;

using (SqlConnection conn = new SqlConnection(strConnectionString))
{
    Dictionary<DateTime, float> d_DateTime_Data;

    using (SqlCommand cmd = new SqlCommand(sqlcommand, conn))
    {
        cmd.Parameters.Add("@PhoneNo", SqlDbType.Int);
        cmd.Parameters.AddWithValue("@Date1", dateStart);
        cmd.Parameters.AddWithValue("@Date2", dateEnd.AddDays(1));
        conn.Open();

        for (int i = 0; i < phoneNo.Count; i++)
        {
            d_DateTime_Data = new Dictionary<DateTime, float>();
            cmd.Parameters["@PhoneNo"].Value = phoneNo[i];
            cmd.ExecuteNonQuery();
            using (SqlDataReader reader = cmd.ExecuteReader())
            {
                while (reader.Read())
                {
                    d_DateTime_Data.Add(DateTime.Parse(reader["Date"].ToString()), float.Parse(reader["Data"].ToString()));
                }
            }
            d_PhoneNo_DateDataList.Add(phoneNo[i], d_DateTime_Data);
        }
        conn.Close();
    }
}

Я попытался использовать concurrentDictionary с Parallel.For, но он создает проблемы с DataReader

ConcurrentDictionary<int, Dictionary<DateTime, float>> d_PhoneNo_DateDataList = new ConcurrentDictionary<int, Dictionary<DateTime, float>>();

string sqlcommand = "SELECT ---- FROM ---- INNER JOIN ---- ON ---- = ---- WHERE [email protected] AND date BETWEEN @Date1 AND @Date2";
string strConnectionString = ConfigurationManager.ConnectionStrings["----"].ConnectionString;

using (SqlConnection conn = new SqlConnection(strConnectionString))
{
    Dictionary<DateTime, float> d_DateTime_Data;

    using (SqlCommand cmd = new SqlCommand(sqlcommand, conn))
    {
        cmd.Parameters.Add("@PhoneNo", SqlDbType.Int);
        cmd.Parameters.AddWithValue("@Date1", dateStart);
        cmd.Parameters.AddWithValue("@Date2", dateEnd.AddDays(1));
        conn.Open();

        Parallel.For(0, phoneNo.Count, (index) =>
        {
            d_DateTime_Data = new Dictionary<DateTime, float>();
            cmd.Parameters["@PhoneNo"].Value = phoneNo[index];
            cmd.ExecuteNonQuery();
            using (SqlDataReader reader = cmd.ExecuteReader())
            {
                while (reader.Read())
                {
                    d_DateTime_Data.Add(DateTime.Parse(reader["Date"].ToString()), float.Parse(reader["Data"].ToString()));
                }
            }
            d_PhoneNo_DateDataList.TryAdd(phoneNo[index], d_DateTime_Data);
        });
        conn.Close();
    }
}

Ответ 1

Если ваше веб-приложение имеет какой-либо фрагмент кода, который занимает много времени, то вместо этого переместите его в веб-задачу, по крайней мере, чтобы не повлиять на масштабируемость приложения.

1- Создайте веб-задание и переместите код, который занимает много времени.

2- Сделать веб-задачу прослушиванием очереди

3- В своем веб-приложении после отправки пользователя вставьте сообщение с необходимыми сведениями в очередь

4- Если вам нужно уведомить пользователя о завершении процесса, используйте SignalR, подключитесь к концентратору со своего JavaScript и опубликуйте сообщение вверху из кода веб-задания, это немедленно сообщит об этом пользователю

Ответ 2

Скорее всего, вы работаете с 230-секундным тайм-аутом, жестко запрограммированным в App Service.

Подробнее см. этот вопрос:
Azure ASP.net WebApp Истекло время ожидания запроса

Попробуйте выполнить эту долговременную задачу как WebJob и отправьте результаты в очередь или таблицу. Или отправьте сообщение в таблицу /Blob (возможно, даже Redis, если вы многократно используете данные) и передайте сообщение с очередью.

Ответ 3

У нас была та же проблема с Azure, когда мы использовали более старую версию SDK (2.3) и балансировщик нагрузки, делающий вызовы webservice. Возможно, это не то же самое для вас, потому что вы выполняете запрос к базе данных. Тайм-аут по умолчанию для балансировки нагрузки составляет 4 минуты. Обновление до новой версии SDK и использование параметра конечной точки idleTimeoutInMinutes позволяет до 30 минут максимум (я думаю) до истечения времени ожидания.

Действие:

У вас есть облачная служба в Azure

Результат:

У вас есть клиенты, которые звонят в ваш облачный сервис, и если вызов облачного сервиса длится более 4 минут, ваши клиенты висят, пока не получат тайм-ауты на стороне клиента.

Причина:

Тайм-аут простоя TCP-соединений по умолчанию в балансировщике нагрузки Azure Cloud Service равен 4 минутам.

Разрешение:

Вам нужно будет обновить, по крайней мере, до 2,4 Azure SDK, а затем вы можете включить атрибут idleTimeoutInMinutes файла CSDEF, чтобы контролировать, как долго балансировщик нагрузки Azure позволяет этим простоям TCP-соединения оставаться в живых до сброса этого соединения.

<Endpoints>
  <InputEndpoint name="Endpoint1" protocol="http" port="80" idleTimeoutInMinutes="6" />
</Endpoints>

Новое: настраиваемый тайм-аут ожидания для балансировки нагрузки Azure http://azure.microsoft.com/blog/2014/08/14/new-configurable-idle-timeout-for-azure-load-balancer/

Ответ 4

если вы используете Azure Web App и получили это ошибка. Это связано с тем, что по умолчанию время ожидания, установленное для веб-приложения на балансировке нагрузки в Azure, составляет 230 секунд, то есть 3,8 минуты. Если вашему приложению требуется больше времени, чтобы ответить на запрос, вы получите эту ошибку.

Чтобы устранить проблему, проверьте, не занимает ли логическая обработка много времени для завершения, и верните ответ в своем коде.