Russian Qt Forum

Qt => Работа с сетью => Тема начата: sergek от Февраль 22, 2021, 16:35



Название: Передача данных при неустойчивом соединении
Отправлено: sergek от Февраль 22, 2021, 16:35
Коллеги,
в эксплуатации мониторинговой системы случилась неприятность :-\ - дежурный кипятил чайник на сервере диспетчеризации и немного залил системный блок. Сервер умер не сразу, а некоторое время помучался. В это время с сетевых узлов другие компьютеры передавали ему данные. Узлы занимаются периодическим опросом периферийных устройств через аппаратные интерфейсы, данные - текущие измерения параметров, архивы измерений и событий и т.д. Система построена так, что на узлах данные накапливаются локально и периодически отправляются на сервер (синхронизация с использованием транзакционного механизма). Узловые компьютеры соединяются с сервером по REST API с использованием QNetworkAccessManager, QNetworkRequest и QNetworkReply. Задачи передачи данных и опроса работают в разных потоках.

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

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

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


Название: Re: Передача данных при неустойчивом сединении
Отправлено: Old от Февраль 22, 2021, 17:09
При анализе нештатки замечено, что в то время, когда сервер отдавал концы, на узлах образовались пробелы в архивных данных. А этого не должно было бы случиться. У меня нет других предположений, что в это время узел пытался безуспешно передать данные и занимал процессор под завязку, и на работу с железом времени просто не оставалось.
Все зависит от того, как у вас это все реализовано.
Если в момент отправки лочатся какие-то структы данных, которые нужны нитке опроса, то да - нитка опроса может быть заблокирована. Если для отправки делается копия данных с кратковременной блокировкой, то потерь быть не должно.


Название: Re: Передача данных при неустойчивом сединении
Отправлено: sergek от Февраль 22, 2021, 17:37
Нет, блокировок нет.
Сервис опроса сохраняет текущие данные в кэше (сделан на основе QHash). Прошу прощения за терминологию, сервис у меня - это задача, выполняющаяся в потоке по таймеру.
Архивный сервис читает данные из кэша и записывает их в БД.
Ну а сервис передачи - читает несинхронизированные данные из БД отправляет их на сервер. Получает от сервера подтверждение и помечает переданные записи в БД (так завершается транзакция).


Название: Re: Передача данных при неустойчивом сединении
Отправлено: qate от Февраль 22, 2021, 23:19
Передаваемые данные хорошо бы подкрепить контрольной суммой, если я правильно понял проблему.


Название: Re: Передача данных при неустойчивом сединении
Отправлено: sergek от Февраль 23, 2021, 00:08
Контрольная сумма тут не нужна - транспорт TCP/IP, протокол HTTP.


Название: Re: Передача данных при неустойчивом сединении
Отправлено: qate от Февраль 23, 2021, 09:01
не совсем понятно как образовались пробелы в архивных данных на узлах, которые к проблеме с серверу не имеют отношения ?

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



Название: Re: Передача данных при неустойчивом сединении
Отправлено: sergek от Февраль 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. Но не знаю, помогло бы это в моем случае.


Название: Re: Передача данных при неустойчивом сединении
Отправлено: qate от Февраль 23, 2021, 12:13
даже если поток передачи на 100% заел проц, то другие потоки будут работать, только медленнее
да и не должен поток передачи заедать проц на 100% - этоже легко смоделировать выключив сервер
другой вопрос как конкретно поток записи зависит (если вообще) от передающего - это только покажет код и лог

логи без метки времени мало полезны


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


Название: Re: Передача данных при неустойчивом сединении
Отправлено: qate от Февраль 23, 2021, 17:33
так напиши простой тест - на сервере соединение принимай, но ничего не отдавай, но и не завершай - пусть клиент висит в ожидании