Запрос занимает много времени в результате ошибки тайм-аута 504? - PullRequest
0 голосов
/ 20 октября 2018

все.В настоящее время я поддерживаю старую систему с использованием struts2 и hibernate.Есть функция, которая форматирует данные в Excel, а затем загружает их в соответствии с параметрами запроса.Обычно в день добавлялось 3000 записей, и обычно нам просто нужно проверить сегодняшние данные, что на 3000 записей меньше в формате Excel.

Работает нормально.Затем я получил новое требование, для каждой записи мне нужно получить информацию о двух позициях записи.Ну, информация о местоположении не существует в нашей базе данных.Мне нужно запросить два интерфейса, чтобы получить их.Я просто делаю это в цикле for, то есть когда я получаю данные, возвращенные из базы данных, а затем перебираю список массивов, для каждой записи запрашиваю необходимую ему информацию о двух позициях.Пока я не получил все сообщения, я форматирую их в Excel, а затем отвечаю на внешний интерфейс.

Проблема в том, что сервер отвечает слишком медленно.Когда около 200-300 записей, все работает нормально.Но когда дело доходит до 3000 записей, я получаю ошибку тайм-аута 504.

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

Редактировать: я записываю время при загрузке 200 записей с внешними запросами и без них, а также псевдокод здесь.Я думал, что внешние запросы является основной причиной. с внешними запросами с внешними запросами с внешними запросами без внешних запросов без внешних запросов без внешнихзапросы

    public byte[] methodName() {

  // 13 title
  String[] title = { "title1", "title2", "title3", ... , "title13" };
  // result is the records returned from db select
  String[][] data = new String[result.size()*20][title.length];

  int row = 0, col = 0;

  SomeEntity someEntity = null;

  System.out.println("with external requests");
  System.out.println("before loop-->" + System.currentTimeMillis() + " - " + new Date().toString());

  for (Object object : result) {
    someEntity = (SomeEntity) object;
    col = 0;
    data[row][col++] = someEntity.getTitle1();
    data[row][col++] = someEntity.getTitle2();
    // add other data
    ...
    // get location, two similar requests
    data[row][col++] = getXXXLocation(someEntity.getLongitude(), someEntity.getLatitude());
    data[row][col++] = getXXXLocation(someEntity.getMctId(), someEntity.getTerId());
    row++;
  }
  // then generate the ExcelModel
  System.out.println("after loop-->" + System.currentTimeMillis() + " - " + new Date().toString());
  ExcelModel excelModel = new ExcelModel("filename");
  excelModel.addColumnsTitle(title);
  System.out.println("before generate excel-->" + System.currentTimeMillis() + " - " + new Date().toString());
  byte[] aws = excelModel.generateExcelFile(data);
  System.out.println("after generate excel-->" + System.currentTimeMillis() + " - " + new Date().toString());

  return aws;
}

1 Ответ

0 голосов
/ 22 октября 2018

Это не настоящий ответ, но он слишком длинный для комментария.

Я думал, что главная проблема - это внешние запросы.

Очевидно, что этовнешние звонки.Почти все потраченное время составляет TTFB .Но вы все еще не знаете, куда на самом деле уходит это время.

Существует три основных вида затрат.Первый - это стоимость выполнения вашего кода, форматирования запросов и анализа ответов.Поскольку это кажется незначительным, мы можем двигаться дальше.Второе - это фиксированная стоимость выполнения вызова: отправка материала по сети.Это плата, которую вы платите 6000 раз.Третья - это стоимость извлечения данных: это также плата, которую вы платите 6000 раз, но в зависимости от источника данных стоимость может быть не фиксированной (например, кеширование базы данных может компенсировать повторяющиеся запросы).

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

Если большая часть времени затрачивается на извлечение данных, вам нужно посмотреть на запросы к базе данных (или что-то еще) и попытаться настроить их..

Очевидно, что я делаю эти предложения, ничего не зная о вашей организации или ваших обязанностях / полномочиях.Если внешняя служба действительно внешняя, вы не сможете получить улучшения.

Альтернативные решения?

  • Параллельная обработка: есть несколько потоков, вызывающих удаленный сервер.Вам нужно будет переписать свой код, но, по крайней мере, это под вашим контролем.
  • Увеличение времени ожидания: просто дайте вашей программе больше времени для завершения.Однако, если предположить, что стоимость линейная, обработка 3000 пар вызовов займет десять минут.Ваши пользователи могут не захотеть, чтобы их экран зависал так долго.Итак ...
  • Асинхронная отправка.Пользователь запускает запрос, переходит к следующему заданию, а через некоторое время готовый файл Excel попадает в папку «Входящие».
...