Russian Qt Forum
Ноябрь 22, 2024, 07:19 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Передача данных при неустойчивом соединении  (Прочитано 7609 раз)
sergek
Гипер активный житель
*****
Offline Offline

Сообщений: 872


Мы должны приносить пользу людям.


Просмотр профиля
« : Февраль 22, 2021, 16:35 »

Коллеги,
в эксплуатации мониторинговой системы случилась неприятность В замешательстве - дежурный кипятил чайник на сервере диспетчеризации и немного залил системный блок. Сервер умер не сразу, а некоторое время помучался. В это время с сетевых узлов другие компьютеры передавали ему данные. Узлы занимаются периодическим опросом периферийных устройств через аппаратные интерфейсы, данные - текущие измерения параметров, архивы измерений и событий и т.д. Система построена так, что на узлах данные накапливаются локально и периодически отправляются на сервер (синхронизация с использованием транзакционного механизма). Узловые компьютеры соединяются с сервером по REST API с использованием QNetworkAccessManager, QNetworkRequest и QNetworkReply. Задачи передачи данных и опроса работают в разных потоках.

При анализе нештатки замечено, что в то время, когда сервер отдавал концы, на узлах образовались пробелы в архивных данных. А этого не должно было бы случиться. У меня нет других предположений, что в это время узел пытался безуспешно передать данные и занимал процессор под завязку, и на работу с железом времени просто не оставалось.

Вопросы такие - мог ли процесс передачи данных тормозить опрос устройств?
Можно ли эту проблему решить путем установки приоритетов потокам, в которых выполняются конкурирующие задачи? Или, если rest api дорвался до интерфейса, будет тыкаться до сервера до потери пульса и на железо времени не останется в любом случае?
Смоделировать ситуацию довольно сложно, поэтому и спрашиваю.

PS. Забыл указать - система работает под Linux.
PPS. Если конкретизировать, на узле три потока:
1 - опрос железа - HighPriority;
2 - формирование архива - NormalPriority;
3 - передача данных на сервер - LowPriority.
Так сработает?
« Последнее редактирование: Февраль 24, 2021, 15:50 от sergek » Записан

Qt 5.13.0 Qt Creator 5.0.1
Win10, Ubuntu 20.04
Old
Джедай : наставник для всех
*******
Online Online

Сообщений: 4350



Просмотр профиля
« Ответ #1 : Февраль 22, 2021, 17:09 »

При анализе нештатки замечено, что в то время, когда сервер отдавал концы, на узлах образовались пробелы в архивных данных. А этого не должно было бы случиться. У меня нет других предположений, что в это время узел пытался безуспешно передать данные и занимал процессор под завязку, и на работу с железом времени просто не оставалось.
Все зависит от того, как у вас это все реализовано.
Если в момент отправки лочатся какие-то структы данных, которые нужны нитке опроса, то да - нитка опроса может быть заблокирована. Если для отправки делается копия данных с кратковременной блокировкой, то потерь быть не должно.
Записан
sergek
Гипер активный житель
*****
Offline Offline

Сообщений: 872


Мы должны приносить пользу людям.


Просмотр профиля
« Ответ #2 : Февраль 22, 2021, 17:37 »

Нет, блокировок нет.
Сервис опроса сохраняет текущие данные в кэше (сделан на основе QHash). Прошу прощения за терминологию, сервис у меня - это задача, выполняющаяся в потоке по таймеру.
Архивный сервис читает данные из кэша и записывает их в БД.
Ну а сервис передачи - читает несинхронизированные данные из БД отправляет их на сервер. Получает от сервера подтверждение и помечает переданные записи в БД (так завершается транзакция).
Записан

Qt 5.13.0 Qt Creator 5.0.1
Win10, Ubuntu 20.04
qate
Супер
******
Offline Offline

Сообщений: 1177


Просмотр профиля
« Ответ #3 : Февраль 22, 2021, 23:19 »

Передаваемые данные хорошо бы подкрепить контрольной суммой, если я правильно понял проблему.
Записан
sergek
Гипер активный житель
*****
Offline Offline

Сообщений: 872


Мы должны приносить пользу людям.


Просмотр профиля
« Ответ #4 : Февраль 23, 2021, 00:08 »

Контрольная сумма тут не нужна - транспорт TCP/IP, протокол HTTP.
Записан

Qt 5.13.0 Qt Creator 5.0.1
Win10, Ubuntu 20.04
qate
Супер
******
Offline Offline

Сообщений: 1177


Просмотр профиля
« Ответ #5 : Февраль 23, 2021, 09:01 »

не совсем понятно как образовались пробелы в архивных данных на узлах, которые к проблеме с серверу не имеют отношения ?

на стороне "узла":
1. все данные собраны и помещены в БД ?
2. проблемы наблюдались только при обмене с сервером ?

Записан
sergek
Гипер активный житель
*****
Offline Offline

Сообщений: 872


Мы должны приносить пользу людям.


Просмотр профиля
« Ответ #6 : Февраль 23, 2021, 10:44 »

не совсем понятно как образовались пробелы в архивных данных на узлах, которые к проблеме с серверу не имеют отношения ?
Именно это я и пытаюсь понять))
Судя по всему, во втором потоке функция, которая читает кэш и записывает данные в БД, не смогла это сделать по причине того, что в это время в третьем потоке функция передачи данных на сервер пыталась передать несинхронизированные данные. И по причине плохого самочувствия сервера, делала это неоднократно, заняв полностью процессор.
Я не знаю, каким кодом это проиллюстрировать. Вот, например, кусок функции передачи данных на сервер:
Код
C++ (Qt)
void CRestNodeController::sendRequest(const CRestRequest &request) {
 
   restClient.setBaseUrl(request.baseUrl);
   QNetworkReply *reply = nullptr;
 
   switch(request.funId) {
 
   case RestFunctions::Archives:
 
       reply = restClient.postMultipart("archives", request.values.value(0).toByteArray());
 
       if(!reply->isFinished()) {
           connect(reply, &QNetworkReply::finished, this, &CRestNodeController::archivesSlot, Qt::QueuedConnection);
       } else {
           reply->deleteLater();
           qDebug("CRestNodeController::sendRequest: Archives reply has finished or was aborted.");
       }
       break;
...
 
postMultipart - функция, которая в конечном счете использует QNetworkAccessManager::post.

Я не обрабатываю QNetworkReply::error. Но не знаю, помогло бы это в моем случае.
Записан

Qt 5.13.0 Qt Creator 5.0.1
Win10, Ubuntu 20.04
qate
Супер
******
Offline Offline

Сообщений: 1177


Просмотр профиля
« Ответ #7 : Февраль 23, 2021, 12:13 »

даже если поток передачи на 100% заел проц, то другие потоки будут работать, только медленнее
да и не должен поток передачи заедать проц на 100% - этоже легко смоделировать выключив сервер
другой вопрос как конкретно поток записи зависит (если вообще) от передающего - это только покажет код и лог

логи без метки времени мало полезны
« Последнее редактирование: Февраль 23, 2021, 12:15 от qate » Записан
sergek
Гипер активный житель
*****
Offline Offline

Сообщений: 872


Мы должны приносить пользу людям.


Просмотр профиля
« Ответ #8 : Февраль 23, 2021, 12:37 »

Если просто отключить сервер - запрос отбивается быстро и ожидания никакого нет. Все плохо, если соединение устанавливается, а процесс передачи не идет или идет плохо.
Я еще поискал в интернете, нашел-таки, что проблема есть и она, судя по всему, влоб не решается, например, http://www.prog.org.ru/topic_20683_0.html, https://forum.antichat.ru/threads/265564/.
Так что я пока решил отложить эту проблему на потом, если она вдруг станет острой. Спасибо, коллеги.
Записан

Qt 5.13.0 Qt Creator 5.0.1
Win10, Ubuntu 20.04
qate
Супер
******
Offline Offline

Сообщений: 1177


Просмотр профиля
« Ответ #9 : Февраль 23, 2021, 17:33 »

так напиши простой тест - на сервере соединение принимай, но ничего не отдавай, но и не завершай - пусть клиент висит в ожидании
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.287 секунд. Запросов: 23.