<개요>

- Azure IoT Hub를 사용하면 Device와 Server를 간편하게 연결하여 D2C (Device to Cloud), C2D (Cloud to Device) 메시지를 쉽게 전달할 수 있습니다.

- 디바이스의 메시지는 일반적으로 json string으로 구성되어 다양한 형태의 레이아웃을 특별한 처리없이 송수신할 수 있습니다.

- 이러한 유형의 데이터를 Telemetry 라고 합니다.

<내용>

- 디바이스와 서버가 주고 받는 데이터는 Telemetry외에도 제어정보가 있습니다.

- Azure IoT Hub 에서는 Device 제어를 위해서 크게 두 가지 방법을 제공하고 있습니다.

 

1. Device Twin

SKT ThingPlug나 AWS IoT 의 경우 Shadow 라고 부릅니다. Azure IoT Hub의 경우 Device Twin(장치쌍)이라고 부릅니다.

Device Twin은 크게 tags, desired properties, reported properties로 이루어집니다.

공유변수의 형태로 이해하면 됩니다. 디바이스와 서버가 Read/Write할 수 있는 영역이기 때문에 디바이스가 꺼져있거나 서버와 연결되어 있지 않는 상황에서도 처리가 가능합니다. (비동기) 

디바이스 On/Off, Firmware Update, 데이터 주기 조정등 다양한 목적으로 사용가능합니다.

 A. Tags

 - 일반적으로 Server Side에서 세팅하는 값으로 Device를 구분하기 위한 값으로 많이 사용됩니다. (e.g. 모델코드, 위치정보)

 - 나중에 나오는 Firmware Update시나리오에서도 Tags값을 target Condition 으로 활용합니다.

 B. Properties

 - Desired : 서버에서 Write하고 디바이스에서 Read 하는 용도로 사용됩니다. 주로 서버에서 의도하는 바를 디바이스에 전달하기 위한 목적으로 사용됩니다.

 - Reported : 디바이스에서 Write하고 서버에서 Read 하는 용도로 사용됩니다. 디바이스가 Desired값을 읽고 그에 따른 행위를 마친뒤에 서버에 Notification을 보내는 용도로 사용합니다.

 

2. Method Invoke

Device 가 데이터를 보내는 중 Direct Method요청을 받으면 바로 동작한다

일반적 RPC 사용과 동일합니다. 요청/응답 구조로 즉각적인 확인이 가능하며 연결이 되어 있지 않은 경우 실패합니다.

따라서 timeout 도 존재하며 exception 도 발생할 수 있습니다.

 

<정리>

- 결국 과거에 Remote 와 통신하기 위해서 사용했던 방식과 크게 다르지 않습니다. SDK만 별도로 존재하며 실제 내부를 살펴보면 지원하는 프로토콜에 약간의 차이만 있을 뿐 원격호출 방식은 거의 동일합니다.

- 각 방식을 비교한 자료는 다음과 같습니다.

Direct methodsTwin's desired propertiesCloud-to-device messages

Scenario Commands that require immediate confirmation, such as turning on a fan. Long-running commands intended to put the device into a certain desired state. For example, set the telemetry send interval to 30 minutes. One-way notifications to the device app.
Data flow Two-way. The device app can respond to the method right away. The solution back end receives the outcome contextually to the request. One-way. The device app receives a notification with the property change. One-way. The device app receives the message
Durability Disconnected devices are not contacted. The solution back end is notified that the device is not connected. Property values are preserved in the device twin. Device will read it at next reconnection. Property values are retrievable with the IoT Hub query language. Messages can be retained by IoT Hub for up to 48 hours.
Targets Single device using deviceId, or multiple devices using jobs. Single device using deviceId, or multiple devices using jobs. Single device by deviceId.
Size Maximum direct method payload size is 128 KB. Maximum desired properties size is 8 KB. Up to 64 KB messages.
Frequency High. For more information, see IoT Hub limits. Medium. For more information, see IoT Hub limits. Low. For more information, see IoT Hub limits.
Protocol Available using MQTT or AMQP. Available using MQTT or AMQP. Available on all protocols. Device must poll when using HTTPS.

 

<참고사이트>

https://docs.microsoft.com/ko-kr/azure/iot-hub/iot-hub-devguide-c2d-guidance

https://docs.microsoft.com/ko-kr/azure/iot-hub/tutorial-firmware-update

https://www.xenonstack.com/blog/iot-analytics-platform/

 

 

<개요>

 - Function App 사용시 Azure에서 제공하는 Trigger를 사용할 수 있다.

 - EventHub(In) , CosmosDB(Out) Extension을 사용하였다.

 

<현상>

 - 간헐적으로 Portal내에서 비정상적으로 Extension설치시간이 길어진다.

 - 이후 Function 이 정상적으로 동작하지 않으며 503 오류가 발생한다.

 

<원인 및 조치사항>

 - 이유를 알 수 없지만 Function App 의 Extension 설치시 비정상 오류가 간혹 발생한다.

 - 콘솔에 접속하면 다음과 같은 경로에서 extensions.csproj 파일을 확인할 수 있다.

extensions.csproj

 - 그림과 같이 사용하려는 extension이 정상적으로 등록되어 있는지 확인한다.

 - https://docs.microsoft.com/ko-kr/azure/azure-functions/install-update-binding-extensions-manual

 

Azure Functions 바인딩 확장 수동 설치 또는 업데이트

배포된 함수 앱용으로 Azure Functions 바인딩 확장을 설치하거나 업데이트하는 방법에 대해 알아봅니다.

docs.microsoft.com

 해당 페이지를 참고하여 수동설치를 필요에 따라 진행한다.

 - 이전 설치가 비정상적으로 종료된 경우에는 같은 경로에 app_offline.htm파일이 생성되는 경우가 있는데 해당 파일을 삭제해야 정상적으로 동작한다.

<참고사항>

 - Function App에서 현재 제공되고 있는 extension의 종류

 - https://github.com/Azure/azure-functions-host/wiki/Updating-your-function-app-extensions

 

Azure/azure-functions-host

The host/runtime that powers Azure Functions. Contribute to Azure/azure-functions-host development by creating an account on GitHub.

github.com

 

<현상>

- Azure Resource Template을 통하여 Function App 및 App Service Plan생성

- 실제 생성된 Function App이 동작하지 않고 오류가 발생함

Host오류, 런타임오류 등등이 계속 발생함

<원인>

- Resource Template에서 Default Node version이 매우 낮게 설정되어 있음

0.10.28

 

<해결방법>

- WEBSITE_NODE_DEFAULT_VERSION 변수 추가 : 10.14.1

Function App내 Application Settings

- 템플릿에서도 추가

 

정상동작함을 확인하였다.

<현상>

- 우연히 내부 개발서버 테스트중 발견함

- "ParkUser1" 이라는 사용자가 DB에 있는데 로그인API를 "parkuser1"로 해도 로그인이 됨!

 

<이유>

- 기존에 많은 블로그에서 포스팅된 것처럼 MySQL이 대소문자가 다음과 같이 구분한다.

 VARCHAR : 대소문자 구분 안함

 VARBINARY : 대소문자 구분 함

 BINARY() 함수 : 대소문자를 구분하여 WHERE 이하 절 연산

parkuser1로 검색했는데 ParkUser1 조회완료

 

<해결방법>

1. WHERE 절에 BINARY() 함수를 사용하여 조건을 검색하면 대소문자 구분이 됩니다.

정상적으로 대소문자 구분

2. VARBINARY타입으로 테이블 생성

 

<아키텍처 보완을 위한 추가사항>

- 이번 개발계는 Spring JPA로 진행하면서 테이블이 자동생성 되었고 이때 타입이 VARCHAR로 기본생성되어 발생된 문제였다.

- 클라우드를  사용하면서 대부분의 환경을 자동화하려고 한다.

- 또한 JPA가 지향하는 바 Database 디펜던시를 낮추고 대부분의 로직은 어플리케이션으로 처리한다.

- 확장에 열려있고 변경에는 닫혀있는 디자인 원칙을 적용하는 것은, 설계레벨 뿐만 아니라 아키텍처 레벨에서도 적용되어야 한다. (OCP)

 

UserDetailsService에 다음과 같은 로직을 추가하였다.

대소문자 구분을 하지 않아서 로그인에 성공하더라도 Real값과 일치하는지 한번더 비교한다.

 

테스트 결과 MySQL을 사용할 때 Column Type을 VARCHAR로 사용해도 문제가 없었다.

<개요>

- Azure Cosmos 의 경우 RU 단위로 과금을 한다.

<내용>

- 400RU 가 최소단위이다.

- Partition Key를 잘 설정하지 않으면 HotSpot이 발생하여 RU만큼의 성능을 못 느낄 수도 있다.

- RU는 결국 초당 Read/Write를 위해서 접근하는 데이터의 양이라고 볼 수 있는데, 최적화를 잘못할 경우 기대한 한큼은 Throughput이 나오지 않을 수 있다.

- RU는 database 레벨에서 설정할 수도 있고 개별 Collection 단위로도 설정이 가능하다.

- 물리 1파티션당 10기가 용량제한이 있어서 이를 염두해야 한다.

 

<Scale설정화면>

Collection 내의 RU 설정화면

- 개별 Collection 의 사용빈도나 데이터가 다르다면 별도로 세팅하는 것이 좋다.

 

Database 내의 RU설정화면

 

database 레벨에서 RU를 설정할 경우 각 컨테이너의 RU는 별도설정이 불가능하고 database RU를 공유하는 방식이 된다.

컨테이너 RU 설정 공유화면

전체 사용량이 많지 않다면 공유하는 방법을 추천한다. (과금은 RU단위로 되기 때문)

<결론>

-400RU 로만 사용하면 월 5만원 안쪽으로 부담이 크지 않다.

-그러나 지역중복을 체크하면 x로 비용이 추가된다.

-RU를 초과하는 요청에 대해서는 즉시 응답이 오지 않으며 대기하다가 처리하는 방식으로 이루어진다.

-timeout이 발생하는 경우는 명시적으로 exception 이 발생한다.

-전체 data가 많을 경우 스캔해야하는 범위가 늘어나므로 RU최적화를 위해서는 data tts를 조정하는 것도 하나의 방법이 될 수 있다.

-파티션키 조정을 통해서 HotSpot발생을 줄이고 퍼포먼스를 증가시키는 것은 일반적인 NoSQL 과 유사하다.

기존에 Spring Boot 를 잘 사용중이었는데 어느날 신규API를 추가한 뒤로 기존 API에서 404 Not Found가 발생하기 시작했다.

{

"timestamp": "2019-09-02T02:09:12.322+0000",

"status": 404,

"error": "Not Found",

"message": "No message available",

"path": "/api/devicetelemetry/1/TestDevice1"

}

maven 빌드를 다시 해보기도 하고 API depth를 바꿔보기도 했다. 대소문자도 다시 확인하고.. 

대략 30분정도 삽질을 하다가 예전에 프레임워크 작업할 때 생각났던 component scan 옵션을 찾아봤다!

 

아무 패키지도 설정하지 않으면 기본적으로 최상위 패키지부터 순차적으로 찾아가는데 신규 API를 추가하면서 패키지구조가 약간 틀어졌다.

     <기존> org.apache.telemetry

-> <변경> org.apache.service.telemetry

<신규> org.apache.status

 

이렇게 수정이 되니 신규로 추가된 최상위 패키지인 org.apache.status 만 읽게 되고 org.apache.service 하위는 읽지 않는 문제가 발생한 것이다.

org.apache.service.telemetry

org.apache.service.status 

와 같은 형태로 맞추어주니 다시 동작하지만 동일한 상황이 재발하는 것을 방지하기 위해서 명시적으로 다음 선언을 추가하였다.

@ComponentScan(basePackages="org.apache.service")

'Rest API' 카테고리의 다른 글

Spring HttpPutFormContentFilter  (0) 2017.03.16

+ Recent posts