2015-11-04 11 views
0

У меня есть несколько ролей, запущенных в моем веб-приложении. Они обмениваются сообщениями очереди Azure Storage Queue между ними. Это означает, что веб-ролик размещает сообщение, после того, как роль этого пользователя захватывает его и начинает выполнять.Azure Worker не удалось выполнить длительную операцию

Главным образом, рабочая роль работ с файлами. Он удаляет все пустые строки в файлах xlsx. Работник перебирает все строки и ячейки в пределах каждой строки. Поэтому, если все ячейки внутри строк пустые, я удаляю строку.

Он отлично работает для файлов с суммарными рядами менее 100 000, но один из наших загруженных пользователем файлов с 1 100 000 записей (1 098 800 пустых). Поэтому, когда обработка работника не удалась. См. Прилагаемый рисунок.

Я приложил отладчик к этому процессу. И мои контрольные точки выстрелили в первые 30-40 секунд в цикл. Но после этого отладчик отделился, и я вижу сообщение на лазурном портале, что рабочий нездоровый.

Я также попытался выполнить метод обработки файлов в отдельном потоке. Но имеют тот же результат.

Любые идеи?

enter image description here

UPDATE:

метод My Run выглядит

public override void Run() { 
    var queue = GetCloudQueue(); 
    int maxJobRetries = 10; 
    while (true) { 
     try { 
      var msg = queue.GetMessage(); 

      if (msg != null) { 
       if (msg.DequeueCount <= maxJobRetries) { 
        ImportCommand ic = JsonConvert.DeserializeObject <ImportCommand> (msg.AsString); 
        ProcessImport(queue, msg); 
       } else { 
        queue.DeleteMessage(); 
       } 
      } else { 
       Thread.Sleep(100); 
      } 
     } catch (Exception ex) { 
      //handle exception 
     } 
    } 
} 

Я действительно не думаю, что есть какие-либо необработанное исключение может быть выброшен. Я поместил весь свой код в блок catch catch.

Я думаю, что стоит упомянуть, что я использую Gembox для разбора файлов xlsx. Мой метод синтаксического анализа выглядит:

public IEnumerable <string[]> ReadLines(int sheetIndex) { 
    string[] data = null; 
    if (_file.Worksheets.Count > 0 && _file.Worksheets[sheetIndex].Rows.Count > 0) { 
     if (_headerLength == 0) { 
      _headerLength = _file.Worksheets[sheetIndex].Rows[0].AllocatedCells.Count; 
     } 
// I have great than 1 000 000 Rows 
     foreach(ExcelRow row in _file.Worksheets[sheetIndex].Rows) { 
      data = new string[_headerLength]; 
// I have 30 columns 
      for (int j = 0; j < _headerLength ; j++) { 
       ExcelCell cell = row.Cells[j]; 
       if (cell.Value != null) { 
        bool isDate = cell.Value is DateTime; 
        if (!isDate) { 
         data[j] = cell.Value.ToString(); 
        } else { 
         //if locale is null then used CurrentCulture (.net feature) 
         data[j] = ((DateTime) cell.Value).ToString(_locale); 
        } 
       } else { 
        data[j] = null; 
       } 
      } 
      yield return data; 
     } 
    } 
} 

UPDATE 2:

Благодаря Дэвид Макогон. Я меняю два размера вверх (до A2), и теперь он работает. Но моя память прошла через минуту. И его очень дорого держать A2. Любые идеи, как я могу уменьшить свой код, чтобы он работал на небольших экземплярах?

enter image description here

+0

Скорее всего, ваша роль заключается в утилизации из-за необработанного исключения. Можете ли вы включить код для метода 'OnStart' вашей роли? –

ответ

0

Там нет никакого способа, чтобы диагностировать проблему с чуть-чуть информации предоставленной вами для одна маленькая деталь за исключением: Ваши рабочие экземпляры роли являются А0, наименьший-возможный размер VM, с 768MB RAM (и общий ЦП). Поэтому очень вероятно, что ваше приложение запущено в ограничение памяти.

Обычно я бы разместил это как комментарий, но вы имеете дело с миллионными файлами xls, которые звучат как очень интенсивная память задача, и что она будет решена путем работы на больших виртуальных машинах.