Azure IoTEdge — пользовательский модуль IoTEdge не может подключиться к концентратору с ошибкой Communication_Error

Наш пользовательский модуль IoTEdge работал правильно до недавнего времени, когда он начал терять соединение, при этом наш ConnectionStatusChangeHandler сообщал о состоянии «ConnectionStatus.Disconnected» и причинах «ConnectionStatusChangeReason.Retry_Expired» и ConnectionStatusChangeReason.Communication_Error".

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

Мы проверили. Одна вещь, которая выделяется, это то, что двойник модуля EdgeHub устройства не указывает пользовательский модуль в разделе «клиенты» его сообщаемых свойств, что, по-видимому, связано с сбоем в работе. В списке указан только модуль IoTEdgeMetricsCollector, который подключен к IoTHub и работает нормально.

  }, "clients": { "$lastUpdated": "2024-05-22T06:41:40.9107753Z", "deviceId/IoTEdgeMetricsCollector": { "$lastUpdated": "2024-05-22T06:41:40.9107753Z", "status": { "$lastUpdated": "2024-05-22T06:41:40.9107753Z" }, "lastConnectedTimeUtc": { "$lastUpdated": "2024-05-22T06:41:40.9107753Z" } } }

Похоже, что локальный модуль EdgeHub игнорирует наш пользовательский модуль.

Среда

  • Хост: Debian 11, Arm64
  • азиот-окантованный: 1.4.27
  • Пограничный агент @ 1.4.35
  • Крайний хаб @ 1.4.35
  • Докер/Моби: 24.0.9-1

Шаги по воспроизведению

К сожалению, мы не можем воспроизвести проблему. Мы не уверены, что это послужило причиной, но подозреваем, что случайное изменение было сохранено в двойнике модуля EdgeHub с помощью Azure IoT Explorer.

Что мы пробовали до сих пор:

  • Удален и повторно добавлен пользовательский модуль на устройство с портала Azure, а также посредством многоуровневого развертывания.

  • Перезагрузил шлюз, перезапустил системные модули, запустил «перезагрузку системы iotedge».

  • Развернул на устройстве модуль SimulatedTemperatureSensor; он правильно регистрируется на клиентах EdgeHub и правильно работает, поэтому новые модули, кроме нашего, кажутся незатронутыми.

  • Команда «iotedge check» возвращает зеленый цвет с парой предупреждений о версиях пакета, ошибок нет.

  • После перезапуска в журналах EdgeHub или EdgeAgent нет ошибок.

Пользовательский модуль успешно развернут, запускается и работает, но не может отправить данные телеметрии в нисходящий поток, поскольку любая попытка подключения к EdgeHub завершается неудачно с вышеупомянутыми ConnectionStatus и ConnectionStatusChangeReason.

  • Мы также собрали следы внутри пользовательского модуля: мы увидели исключение WebSocket, когда модуль пытается подключиться к хабу; этого следовало ожидать, поскольку EdgeHub, который действует как прокси-сервер для пользовательского модуля, не знает о его присутствии:

HasStack="True" ThreadID="6,006" ProcessorNumber="0" thisOrContextObject="ErrorDelegatingHandler#34683734"memberName="ExecuteWithErrorHandlingAsync" message="Обнаружено исключение: System.Net.WebSockets.WebSocketException (0x80004005): невозможно подключиться к удаленному устройству server ---> System.Net.Http.HttpRequestException: не удалось установить SSL-соединение, см. внутреннее исключение ---> System.IO.IOException: получен неожиданный EOF или 0 байтов из транспортного потока в System. Net.Security.SslStream.ReceiveBlobAsync[TIOAdapter](адаптер TIOAdapter) в System.Net.Security.SslStream.ForceAuthenticationAsync[TIOAdapter](адаптер TIOAdapter, логическое значение полученияFirst, Byte[] reAuthenticationData, логическое значение isApm) в System.Net.Http.ConnectHelper .EstablishSslConnectionAsync(SslClientAuthenticationOptions sslOptions, HttpRequestMessage request, Boolean async, Stream Stream, CancellationToken cancelToken) --- Конец внутренней трассировки стека исключений --- в System.Net.Http.ConnectHelper.EstablishSslConnectionAsync(SslClientAuthenticationOptions sslOptions, Запрос сообщения, логическая асинхронность, Поток потока, CancellationToken cancelToken) в System.Net.Http.HttpConnectionPool.ConnectAsync (запрос HttpRequestMessage, Boolean async, CancellationToken cancelToken) в System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync (запрос HttpRequestMessage, Boolean async, CancellationToken cancelToken) в System .Net .Http.HttpConnectionPool.AddHttp11ConnectionAsync(запрос HttpRequestMessage) в System.Threading.Tasks.TaskCompletionSourceWithCancellation1.WaitWithCancellationAsync(CancellationToken cancellationToken) at System.Net.Http.HttpConnectionPool.GetHttp11ConnectionAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken) at System.Net.Http.HttpConnectionPool.SendWithVersionDetectionAndRetryAsync(HttpRequestMessage request, Boolean async, Boolean doRequestAuth, CancellationToken cancellationToken) at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken) at System.Net.WebSockets.WebSocketHandle.ConnectAsync(Uri uri, CancellationToken cancellationToken, ClientWebSocketOptions options) at System.Net.WebSockets.WebSocketHandle.ConnectAsync(Uri uri, CancellationToken cancellationToken, ClientWebSocketOptions options) at System.Net.WebSockets.ClientWebSocket.ConnectAsyncCore(Uri uri, CancellationToken cancellationToken) at Microsoft.Azure.Devices.Client.Transport.AmqpIot.AmqpIotTransport.CreateClientWebSocketAsync(Uri websocketUri, CancellationToken cancellationToken) at Microsoft.Azure.Devices.Client.Transport.AmqpIot.AmqpIotTransport.CreateClientWebSocketTransportAsync(CancellationToken cancellationToken) at Microsoft.Azure.Devices.Client.Transport.AmqpIot.AmqpIotTransport.InitializeAsync(CancellationToken cancellationToken) at Microsoft.Azure.Devices.Client.Transport.Amqp.AmqpIotConnector.OpenConnectionAsync(CancellationToken cancellationToken) at Microsoft.Azure.Devices.Client.Transport.Amqp.AmqpConnectionHolder.EnsureConnectionAsync(CancellationToken cancellationToken) at Microsoft.Azure.Devices.Client.Transport.Amqp.AmqpConnectionHolder.OpenSessionAsync(IDeviceIdentity deviceIdentity, CancellationToken cancellationToken) at Microsoft.Azure.Devices.Client.Transport.AmqpIot.AmqpUnit.EnsureSessionIsOpenAsync(CancellationToken cancellationToken) at Microsoft.Azure.Devices.Client.Transport.AmqpIot.AmqpUnit.OpenAsync(CancellationToken cancellationToken) at Microsoft.Azure.Devices.Client.Transport.Amqp.AmqpTransportHandler.OpenAsync(CancellationToken cancellationToken) at Microsoft.Azure.Devices.Client.Transport.ProtocolRoutingDelegatingHandler.OpenAsync(CancellationToken cancellationToken) at Microsoft.Azure.Devices.Client.Transport.ErrorDelegatingHandler.<>c__DisplayClass27_0.<<ExecuteWithErrorHandlingAsync>b__0>d.MoveNext() --- End of stack trace from previous location --- at Microsoft.Azure.Devices.Client.Transport.ErrorDelegatingHandler.ExecuteWithErrorHandlingAsync[T](Func1 asyncOperation)"

Мы думали полностью удалить и переустановить среду выполнения IoTEdge на устройстве, но нам хотелось бы исчерпать все другие варианты, прежде чем приступать к этому.

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

Добавьте к приведенному выше вопросу ссылку, которую вы использовали для добавления модулей в Azure IoT Edge.

Sampath 30.05.2024 17:02

Как указано в вопросе, мы использовали два способа развертывания наших модулей на устройстве: вручную с помощью функции «Установить модули» на портале Azure и посредством многоуровневого развертывания. Образ модуля уже создан и опубликован в нашем реестре контейнеров, доступ к которому осуществляется при ручном и многоуровневом развертывании. Похоже, проблема в том, что модуль EdgeHub на устройстве не регистрирует пользовательский модуль в качестве одного из своих клиентов. Мы ищем способ заставить это произойти без необходимости удалять и переустанавливать среду выполнения IoTEdge устройства.

user1483086 04.06.2024 11:56
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
Как установить LAMP Stack 1/2 на Azure Linux VM
Как установить LAMP Stack 1/2 на Azure Linux VM
В дополнение к нашему предыдущему сообщению о намерении Azure прекратить поддержку Azure Database для MySQL в качестве единого сервера после 16...
0
2
74
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Проблему, из-за которой ваш пользовательский модуль IoT Edge не может подключиться к IoT Hub из-за ошибок связи, можно решить, выполнив следующие шаги:

  • Проверьте раздел modulesContent, чтобы убедиться, что ваш пользовательский модуль указан правильно и нужные свойства правильно установлены.
  • Используйте команду iotedge check, чтобы проверить конфигурацию развертывания.

Я настроил среду разработки, создал модуль IoT Edge, обновил его с помощью специального кода, собрал и отправил модуль в реестр контейнеров и, наконец, развернул модуль на устройстве IoT Edge.

  • Откройте код Visual Studio, откройте палитру команд (Ctrl+Shift+P) и запустите Azure IoT Edge: New IoT Edge Solution. Выберите папку для создания решения и введите имя вашего решения. Выберите шаблон модуля (например, C#, Node.js, Python) и введите имя вашего модуля.
  • Предоставьте репозиторий изображений модуля. Например, <registry_name>.azurecr.io/<module_name> Обновите модуль с помощью пользовательского кода:
    async Task<MessageResponse> FilterMessages(Message message, object userContext)
          {
              var counterValue = Interlocked.Increment(ref _counter);
              try
              {
                  var moduleClient = (ModuleClient)userContext;
                  var messageBytes = message.GetBytes();
                  var messageString = Encoding.UTF8.GetString(messageBytes);
                  Console.WriteLine($"Received message {counterValue}: [{messageString}]");
    
                  var messageBody = JsonConvert.DeserializeObject<MessageBody>(messageString);
    
                  if (messageBody != null && messageBody.machine.temperature > temperatureThreshold)
                  {
                      Console.WriteLine($"Machine temperature {messageBody.machine.temperature} exceeds threshold {temperatureThreshold}");
                      using (var filteredMessage = new Message(messageBytes))
                      {
                          foreach (var prop in message.Properties)
                          {
                              filteredMessage.Properties.Add(prop.Key, prop.Value);
                          }
    
                          filteredMessage.Properties.Add("MessageType", "Alert");
                          await moduleClient.SendEventAsync("output1", filteredMessage);
                      }
                  }
    
                  return MessageResponse.Completed;
              }
              catch (Exception ex)
              {
                  Console.WriteLine($"Error in sample: {ex.Message}");
                  return MessageResponse.Abandoned;
              }
          }
    
    Обновите файл deployment.template.json:
    {
      "modulesContent": {
        "$edgeAgent": {
          "properties.desired": {
            "modules": {
              "tempSensor": {
                "type": "docker",
                "settings": {
                  "image": "<registry_name>.azurecr.io/tempSensor:1.0",
                  "createOptions": "{}"
                },
                "env": {
                  "SimulatedData": {
                    "value": "true"
                  }
                }
              },
              "filtermodule": {
                "type": "docker",
                "settings": {
                  "image": "<registry_name>.azurecr.io/filtermodule:0.0.1",
                  "createOptions": "{}"
                }
              }
            }
          }
        },
        "$edgeHub": {
          "properties.desired": {
            "routes": {
              "sensorTofiltermodule": "FROM /messages/modules/tempSensor/outputs/temperatureOutput INTO BrokeredEndpoint(\"/modules/filtermodule/inputs/inputFromSensor\")",
              "filtermoduleToIoTHub": "FROM /messages/modules/filtermodule/outputs/output1 INTO $upstream"
            }
          }
        },
        "filtermodule": {
          "properties.desired": {
            "TemperatureThreshold": 25
          }
        }
      }
    }

  • Щелкните правой кнопкой мыши файл deployment.template.json в обозревателе кода Visual Studio и выберите Build and Push IoT Edge Solution.

  • При этом образ Docker будет создан и отправлен в реестр контейнеров Azure.

Ответ принят как подходящий

Решено. Проблема возникла из-за ошибочного удаления базового развертывания, которое помещает системные модули на устройство, а затем последующего многоуровневого/ручного развертывания. Модули EdgeAgent и EdgeHub работали, но не видели новых развернутых пользовательских модулей. Как ни странно, EdgeHub с радостью зарегистрировал бы другие нестандартные модули с рынка, например, Имитированный датчик температуры. Восстановление базового размещения вернуло все в рабочее состояние.

Другие вопросы по теме

Похожие вопросы

Azure Synapse «Содержимое каталога по пути '.../_delta_log/*.*' невозможно отобразить
Развертывание приложения логики (стандартное) через конвейер DevOps — служба kudu недоступна 503
New-AzAutomationSchedule — ссылка на объект не установлена ​​на экземпляр объекта
Аутентификация в Azure с использованием управляемого удостоверения с помощью Terraform
В моем интерфейсе Az Cli для развертывания бицепса в области управления не отображаются изменения во вложенной группе управления
Скрипт Powershell, предназначенный для получения электронных писем всех пользователей и электронных писем менеджеров, принадлежащих к определенной группе безопасности в AD, создает пустой CSV-файл
Поддерживает ли API Microsoft Graph свойство createddatetime для контактов?
GetConnectionStringOrSetting устарел? Какая лучшая замена?
Пользователи не могут пройти проверку подлинности в зоне доступности с помощью ConnectToAzure
Невозможно создать рабочую область машинного обучения Azure с помощью CLI