<개요>

Azure WebApp을 다음과 같은이유로 잘 사용해왔다.

- Azure Devops와 연계하여 배포가 쉽다.

- 다양한 Runtime환경을 기본으로 제공한다. (node, java, C# 등)

- 통합 로깅, 모니터링, 대시보드 환경을 제공한다.

- Auto Scaling이 편리하다. (VM 단위보다 더욱 유동적이다.)

- 접속을 위한 싱글포인트를 제공한다.

 

- 이번에 AWS에서 시스템을 구축하게 되어서 비슷한 PaaS를 찾던 중 Elastic Beanstalk를 발견하고 사용하던 중 발생한 내용이다.

 

<현상>

- Elastic Beanstalk는 내부적으로 nginx 를 사용하고 있다.

- Spring Boot배포 후 접속하면 502 Bad gateway 발생

 

<상세오류 - 로그확인>

2020/03/12 06:12:07 [error] 3114#0: *3 connect() failed (111: Connection refused) while connecting to upstream, client: 100.10.0.208, server: , request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:5000/", host: "userservice-env.eba-yqakdkhm.ap-northeast-2.elasticbeanstalk.com"


<해결과정>

- 구글링을 통해서 나오는 대표적인 해결방법은 포트변경이다. (AWS Beanstalk가 기본적으로 5000포트를 사용한다고 한다.)

Beanstalk내의 환경설정에서 SERVER_PORT를 5000으로 변경

하지만 나에게는 해당하지 않는 내용이었다. 과거 connection reset을 해결할때가 떠오르기 시작한다;;

 

조금 더 관련내용들을 찾아보았다.

https://stackoverflow.com/questions/52912663/aws-elastic-beanstalk-nginx-connect-failed-111-connection-refused

 

AWS elastic Beanstalk / nginx : connect() failed (111: Connection refused

I got this message connect() failed (111: Connection refused Here is my log: ------------------------------------- /var/log/nginx/error.log ------------------------------------- 2018/10/21 06:16...

stackoverflow.com

내용을 종합해보면 결국 application이 적절하게 기동되지 않거나 하여 nginx 가 해석할 수 없는 메시지를 돌려받았을 경우 발생한다.

- Beanstalk의 설정을 천천히 검토해보았다.

 구성, 환경변수, 네트워크, 로드 밸런서 등 이상이 없음을 확인하였다.

- 그렇다면 결국 application이 제대로 기동되지 않았을 확률이 높으나 해당 로그를 확인할 수 없는 것이 아쉽다.  (로컬에서는 정상적으로 기동하니까)

 

- AWS Beanstalk의 spring-boot application 기동방식이 궁금해지기 시작한다.

샘플어플리케이션으로 사용되는 예제는 다음과 같다.

https://github.com/spring-guides/gs-accessing-data-rest.git

 

해당 프로젝트의 pom.xml을 살펴보고 문제점을 찾았다. 아주 사소한....

<build> 태그의 <spring-boot-maven-plugin> 을 빼먹고 작성하지 않았다. 

 

 

<정리>

- Azure WebApp을 사용할때는 azure-webapp-maven-plugin을 사용했었다.

- 신규 프로젝트 구성시 initializer없이 구성하다 Public Cloud관련요소 작업 중 Build plugin실수로 삭제;;

- 정확한 로그를 확인할 수 없어서 약간 힘들었음

 

<Azure WebApp과 비교>

- Azure WebApp이 생성시 매우 간단하다. 클릭 몇번으로 끝

- 배포 역시 azure-webapp-maven-plugin을 사용하여 IDE에서 바로 배포하는 것도 쉽다.

  다만 version에 따른 사용법이 매우 다르기 때문에 주의해서 사용해야 한다. 

  예전에 사용했던 버전이 1.4.0 과 1.5.3 이었는데 세부속성과 사용법이 다르고, 설정 오류시 상세한 메시지를 확인하기가 어렵다.)

 

- AWS Beanstalk역시 기본설정은 간단하지만 상세화면으로 들아가면 항목이 매우 많다. 

( Azure의 경우 후발주자이다보니 PaaS를 중심으로 발전시켜 나갔고, 

  AWS의 경우 VM기반의 선발주자이다보니 제품 여기저기에서 VM중심의 구성이 많이 보인다.)

 

 

<참고>

https://aws.amazon.com/ko/blogs/devops/deploying-a-spring-boot-application-on-aws-using-aws-elastic-beanstalk/

https://github.com/spring-guides/gs-accessing-data-rest/

https://docs.microsoft.com/ko-kr/azure/java/spring-framework/deploy-containerized-spring-boot-java-app-with-maven-plugin

 

Maven을 사용하여 Azure에 Spring Boot 앱 배포

Azure Web Apps의 Maven 플러그 인을 사용하여 Spring Boot 앱을 Azure에 배포하는 방법을 알아봅니다.

docs.microsoft.com

 

다음에는 Azure Devops와 AWS Code Pipeline의 비교사용기를 ...

<개요>

- 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/

 

 

<현상>

- 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

- 템플릿에서도 추가

 

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

<개요>

- 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 과 유사하다.

 수년간 오픈소스 기반으로 시스템을 개발하다가 이번에 Public Cloud를 사용하면서 경험했던 부분을 간단히 공유하겠습니다.

기존에 사용하던 OpenSource

기존에 처리하던 방식입니다. 대부분의 Client로부터의 요청은 Kafka로 전달됩니다. 전달받는 데이터 소스위치에 따라서 Kafka 앞에 하나의 Layer를 더 두는 것이 일반적입니다.

이렇게 개발하다보면 로직자체의 개발보다 때로는 오픈소스의 사용법, 버그패치, 운영시 발생하는 설정상 문제에 더 많은 시간을 사용하고는 합니다. 지금 개발하는 곳에서는 예전보다 개발 리소스가 더 부족한 상황이어서 과감하게 Azure PaaS 를 사용하도록 결정했습니다.

지금 개발중인 시스템은 데이터 입력채널이 대부분 IoT Device, Sensor의 영역인 것을 제외하고는 기존에 개발하던 시스템들과 구조가 90%이상 동일합니다. 

각 Layer에 해당하는 Public Cloud 및 오픈소스 현황

기존에는 Nifi -> SparkStreaming -> Druid, NoSQL, HDFS -> Grafana 를 사용하던 구조였으며 이와 매칭되는 구성요소들을 Azure 에서 찾기 시작했습니다.

 

MS Azure에 있는 다양한 PaaS 요소를 사용하여 IoT Device Data를 수집하는 간단한 예제를 만들어 보았습니다.

(소요시간은 과거 오픈소스를 사용할때와는 비교할 수 없을만큼 단축되었습니다!)

https://docs.microsoft.com/ko-kr/azure/architecture/reference-architectures/iot/

 

Azure IoT 참조 아키텍처 - Azure Reference Architectures

PaaS(platform-as-a-service) 구성 요소를 사용하는 Azure에서 IoT 애플리케이션에 대한 권장 아키텍처

docs.microsoft.com

 여기에 나오는 아키텍처와 크게 다르지 않으나 실시간 분석처리등은 간소화를 위해서 일단 제외하고 진행했습니다.

아키텍처를 그대로 진행하더라도 각 구성요소의 설정 및 구성에 따라서 동작방식이 달라지기 때문에 살펴봐야 하는 부분에 대해서 간단히 정리해봤습니다.

1. Azure IoT Hub

- 각 계정별로 무료 Hub는 1개 생성가능하고 그 외 유료 Hub의 경우 가격정책에 따라 메시지량이 정해진다. (S1 월 28000원)

- 각 Tier별로 Scale Out이 가능하지만 수작업이 필요하며, 높은 Tier를 한 개 쓸것인지 낮은 Tier에서 x times로 늘릴 것인지는 선택필요

- 자체적으로 event hub가 내장되어 있어서 별도 event hub 생성 없이 간단히 사용가능하다.

  그러나 바로 사용하는 것은 권장하지 않고 event hub로 endpoint를 연결하는 것을 권장한다.

  IoT Hub는 디바이스와의 연결을 담당하며 장애가 발생할 경우 변경할 수 도 있다. 그런데 기타 로직을 구성하는 Application이 IoTHub에 바로 연결되어 있다면 변경사항에 영향을 받기 쉽다(설계5대원칙의 OCP를 생각해보세요) 

 또한 실환경에서는 하나의 메시지큐에 여러 개의 Application 으로 확장되는 것이 일반적이며, 이 때 Consumer Group을 여러 개 두고 병렬처리를 각각 하고 파티션을 조정하는 등의 행위가 필요한데, IoT Hub는 이러한 부분에 제약사항이 있다.

- 메시지의 속성값, 내용에 따라서 Routing기능을 활용할 수 있으나 UTF-8 인코딩에 JSON String 을 사용해야만 한다.

- 개별 Device를 등록하는 방법에는 대칭키, 인증서 등의 방식이 있다.

- D2C, C2D 메시지 전송이 가능하며, 디바이스 제어를 위해서는 Device Twin 이나 Method Invoke를 사용하는 것으로 가이드한다.

 

2. Azure Event Hub

 - Apache Kafka와 유사한 구조로 만들어진 Message Queue이다.

 - IoT Hub의 경우 위치가 변경될 수 있으며 Fail over가 필요한 경우도 있다. 또한 직접적으로 Device와 연결되는 부분이기 때문에 Layer Architecture구성을 위해서 실제 메시지 소비는 Event Hub에서 이루어 지는 것을 권장한다.

 - Namespace를 생성 후 각 필요에 따라서 실제 Event Hub 를 생성하는 방식이다.

 - 보관주기를 정할 수 있으며 옵션으로 스냅샷을 Storage Account에 저장할 수 있다. (Cold Storage)

 - 필요에 따라서 파티션 수와 보관주기를 설정할 수 있다.

 - Kafka Enabled를 활성하면 기존 Kafka Consumer Application을 그대로 사용할 수 있다!

 

3. Azure App Services - Functions

 - AWS의 Lambda와 같은 Serverless이다. 지원하는 방식이나 언어가 Lambda보다는 제한적이지만 크게 사용에 어려움은 없다.

 - Azure의 PaaS 구성요소에 대해서 Trigger, Input, Output 연결이 가능해서 보다 빠르게 Application을 구성할 수 있다.

 - Azure DevOps나 Github등의 소스를 연결하여 자동배포가 가능하도록 구성할 수 있으나 현재 Trigger, Input, Output등을 사용할 경우 Extension Plugin설치가 필요한데 이러한 부분의 자동화는 아직 지원하고 있지 않다.

 - 실행 횟수에 따라 요금이 부과되지만 크게 부담되는 수준은 아니며 주요 과금은 묶여있는 App Service Plan의 사양에 따라서 결정된다.

 

4. Azure App Services - Web App

 - Web을 위한 Tomcat등의 WAS를 Managed 형태로 제공한다.

 - WAR, JAR배포를 지원하며 Spring Boot를 올리는 것도 가능하다.

 - 외부로 나타나는 EndPoint로만 접근하면 되고, 내부적으로 구성한 App Service Plan에 따라서 서버자원의 자유로운 확장이 가능하다.

 

5. Azure App Service Plan

 - Azure App Service를 이용하기 위해서 반드시 생성해야 한다.

 - Azure App Service를 위한 서버자원을 묶음형태로 정의한다고 보면 이해가 쉽다.

 - OS, CPU, Storage등의 옵션과 Tier를 설정하고 사용할 실제 App Service (Functions, Web app)를 연결하면 해당 어플리케이션들이 수행될때 지정된 만큼의 자원을 자유롭게 사용한다.

 - Linux/Windows선택에 따라서 사용하는 App Service형태에 일부 제약이 있을수도 있으니 확인이 필요하다.

 

6. Azure Database for MySQL

 - 일반적으로 사용하는 MySQL과 크게 다르지 않다.

 - AWS RDS와 유사하다.

 

7. Azure Cosmos DB

 - Azure에서 제공하는 NoSQL 이다. (AWS의 DynamoDB유사)

 - 사용할 수 있는 SQL API를 4가지 중에 선택가능하며 이론상 기존 API와 버전만 맞다면 호환이 된다.

 - 생각보다 비용이 비싸서 몇가지 고려해야 하는점이 있다.

 a. RU 및 Storage사용량에 따라서 과금이 늘어난다. https://docs.microsoft.com/en-us/azure/cosmos-db/understand-your-bill

 

Understanding your Azure Cosmos DB bill

This article explains how to understand your Azure Cosmos DB bill with some examples.

docs.microsoft.com

 b. Partition관련 Hotspot이 생기지 않도록 Key를 잡는 것이 중요하다. 선택을 잘못한다면 RU를 설정한 것보다 성능이 나오지 않는다.

    일반적인 NoSQL의 특성과 크게 다르지 않은 부분이다. 인덱스는 Collection별로 세팅이 가능하다.

 c. Multi Region 선택시 비용도 Multi로... 들어갑니다..;

 

추가로 현재 Cosmos에 Spring JPA를 사용하여 개발시 고려해야하는 부분이 몇 가지 있는데

 ㄱ. Top keyword, Custom Query

https://github.com/Microsoft/spring-data-cosmosdb/issues/144

 

Query method creation with keyword · Issue #144 · microsoft/spring-data-cosmosdb

New feature on Query Method Creation with Keyword. List the keyword and example in below. AND List findByFirstNameAndLastName(String firstName, String lastName) OR List ...

github.com

 ㄴ. page처리시 next page에 관련된 이슈 -> 이부분은 제가 지금 테스트했을때는 발생하지 않고 있습니다.(2019.08.05)

https://github.com/Microsoft/spring-data-cosmosdb/issues/225

 

Issue Spring Data Rest · Issue #225 · microsoft/spring-data-cosmosdb

Hi, Using Spring Boot 2.0.5, Spring Data Rest 2.0.5 and Spring Data CosmosDB 2.0.5 When exposing paged resources and accessing them via RestAPI, paging does not work. The first page is returned cor...

github.com

https://github.com/Microsoft/spring-data-cosmosdb/issues/363

 

Pagination and Sorting · Issue #363 · microsoft/spring-data-cosmosdb

When using Pagination with Sorting, only the first page is sorted. The rest of the pages are unsorted. For example, a list with 5 elements, starting from page1 Page page = rep...

github.com

오픈소스에 비해서 커스터마이징할 수 있는 영역이 부족하고 몇몇 기능의 부재가 있지만 개발시간은 체감상 20%도 되지 않는듯 합니다.

특히 사용량에 따른 자세한 설정이나 모니터링을 위한 다양한 도구들이 더욱 사용을 편리하게 해주고 있습니다.

 

물론 전체적인 아키텍처와 원리를 잘 이해하고 있어야 최적의 설계를 통해서 성능을 최대화하고 비용을 최소화하는 것이 가능합니다.

<참고사이트>

https://intellipaat.com/blog/tutorial/hadoop-tutorial/introduction-hadoop/

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

 가장 많이 사용하고 있는 Spring Boot + JPA 로  Azure Cosmos DB를 연결하는 작업을 진행해보았다.

https://docs.microsoft.com/ko-kr/java/azure/spring-framework/configure-spring-boot-starter-java-app-with-cosmos-db?view=azure-java-stable


1. maven pom.xml에 아래와 같이 추가하고.

<dependency>

   <groupId>com.microsoft.azure</groupId>

   <artifactId>azure-documentdb-spring-boot-starter</artifactId>

   <version>2.0.4</version>

</dependency>


2. JPA에서 제공하는 CRUD Repository를 이용해서 다음과 같이 작업했다.

public interface DeviceTelemetryRepository extends DocumentDbRepository<DeviceTelemetry, String>{

    List<DeviceTelemetry> findAll();

    @Query(value="SELECT * FROM DeviceTelemetry where deviceId= ?1 and date >= ?2 and date <= ?3", nativeQuery = true)
    List<DeviceTelemetry> findDeviceTelemetryByDeviceIdAndDateGreaterThanAndDateLessThan(@Param("deviceId") int deviceId,
                                                               @Param("from") long from,
                                                               @Param("to") long to    );

}


3. Entity클래스의 경우 테이블에 따라서 잦은 변경이 일어나기 때문에 Controller, Service Layer에서는 DTO클래스를 별도 로 사용하는 것을 권장한다. (디자인 패턴 참고)

@Service
public class DeviceTelemetryService {
@Autowired
private DeviceTelemetryRepository deviceTelemetryRepository;

@Autowired
private ModelMapper modelMapper;

public List<DeviceTelemetryDto> getDeviceTelemetry(int deviceId, long from, long to){
return deviceTelemetryRepository.findDeviceTelemetryByDeviceIdAndDateBetween(deviceId, from, to).stream()
.map(deviceTelemetry -> modelMapper.map(deviceTelemetry, DeviceTelemetryDto.class))
.collect(Collectors.toList());
}

}

4. Controller 까지 완성하여. 테스트하였는데 아래와 같은 오류가 발생한다.

@RequestMapping(path="/api/")
public class DeviceTelemetryController {

@Autowired
private DeviceTelemetryService deviceTelemetryService;


@RequestMapping(value="/{serviceId}/{deviceId}/telemetry", method= RequestMethod.GET)
public @ResponseBody
List<DeviceTelemetryDto> getAllDeviceTelemetry(@PathVariable("deviceId") int deviceId,
@RequestParam("from") long from,
@RequestParam("to") long to) {

return deviceTelemetryService.getDeviceTelemetry(deviceId,from,to);
}
}

java.lang.IllegalArgumentException: unsupported keyword: GREATER_THAN (1): [IsGreaterThan, GreaterThan]
	at com.microsoft.azure.spring.data.documentdb.repository.query.DocumentDbQueryCreator.from(DocumentDbQueryCreator.java:82) ~[spring-data-cosmosdb-2.0.3.jar:na]
	at com.microsoft.azure.spring.data.documentdb.repository.query.DocumentDbQueryCreator.and(DocumentDbQueryCreator.java:56) ~[spring-data-cosmosdb-2.0.3.jar:na]
	at com.microsoft.azure.spring.data.documentdb.repository.query.DocumentDbQueryCreator.and(DocumentDbQueryCreator.java:25) ~[spring-data-cosmosdb-2.0.3.jar:na]
	at org.springframework.data.repository.query.parser.AbstractQueryCreator.createCriteria(AbstractQueryCreator.java:122) ~[spring-data-commons-2.0.10.RELEASE.jar:2.0.10.RELEASE]
	at org.springframework.data.repository.query.parser.AbstractQueryCreator.createQuery(AbstractQueryCreator.java:95) ~[spring-data-commons-2.0.10.RELEASE.jar:2.0.10.RELEASE]
	at org.springframework.data.repository.query.parser.AbstractQueryCreator.createQuery(AbstractQueryCreator.java:81) ~[spring-data-commons-2.0.10.RELEASE.jar:2.0.10.RELEASE]
	at com.microsoft.azure.spring.data.documentdb.repository.query.PartTreeDocumentDbQuery.createQuery(PartTreeDocumentDbQuery.java:38) ~[spring-data-cosmosdb-2.0.3.jar:na]
	at com.microsoft.azure.spring.data.documentdb.repository.query.AbstractDocumentDbQuery.execute(AbstractDocumentDbQuery.java:25) ~[spring-data-cosmosdb-2.0.3.jar:na]


5. Azure Cosmos DB에 문의하니 다음과 같은 답변을 받았다.

spring-data-cosmosdb 2.0.6을 사용해야 하는데 아무리 찾아도 azure-documentdb-spring-boot-starter에 포함된 최신버전은 2.0.4가 최신버전이다!

다시 문의를 했다. 수동으로 업데이트해야하는가?

결론은 "azure-documentdb는 구 네이빙 버전입니다. 신버전을 사용하세요."


Thanks for filing issue, according to your stack trace, seems you are using version 2.0.3, if you are using Spring Boot 2.0.x, try upgrading to 2.0.6.


You can use the azure-cosmosdb-spring-boot-starter(not azure-documentdb-spring-boot-starter) version 2.0.13, which uses spring-data-cosmosdb 2.0.6. Between should have been supported in 2.0.6, check this issue. Also you can reference the integration tests in this repo for the usage.


6. pom.xml에서 azure-cosmosdb-spring-boot-starter 최신버전으로 변경하였다.

<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-cosmosdb-spring-boot-starter</artifactId>
<version>2.0.13</version>
</dependency>


7. 하지만 Spring JPA의 naming rule에 같은컬럼을 중복해서 사용하면 에러가 발생한다.

BETWEEN 쿼리로 변경!

(GREATER_THAN, BETWEEN등은 위에서 언급한 2.0.6 버전에서 정상지원한다.)



8. Repository 소스 변경(@Query는 없어도 쿼리를 자동으로 생성하여 동작한다)

public interface DeviceTelemetryRepository extends DocumentDbRepository<DeviceTelemetry, String> {

List<DeviceTelemetry> findAll();

// @Query(value="SELECT * FROM DeviceTelemetry where deviceId= ?1 and date >= ?2 and date <= ?3", nativeQuery = true)
List<DeviceTelemetry> findDeviceTelemetryByDeviceIdAndDateBetween(@Param("deviceId") int deviceId,
@Param("from") long from,
@Param("to") long to );
}

9. Azure Cosmos DB에서 정상적으로 데이터를 조회하는 것을 확인할 수 있다.

[

{ "id": "3ebd07c0-0740-466f-acb4-1e04a58cdf1a", "serviceId": 1, "deviceId": 1, "contents": "{\"temperature\":34.797642257199705,\"humidity\":79.18982439419167,\"illuminance\":100}", "date": 1552376519931 }, { "id": "9424f15a-e452-4dcc-8ff6-bc3707b7ec3a", "serviceId": 1, "deviceId": 1, "contents": "{\"temperature\":25.964463142640522,\"humidity\":73.64654000868197,\"illuminance\":100}", "date": 1552376579937 }, { "id": "c72aed1b-b4d0-4338-a21f-ae8b7e5b4eba", "serviceId": 1, "deviceId": 1, "contents": "{\"temperature\":28.32913263660401,\"humidity\":73.40374660917695,\"illuminance\":100}", "date": 1552376639938 }, { "id": "c1571a80-7eb6-49dc-be9f-32457e41f69a", "serviceId": 1, "deviceId": 1, "contents": "{\"temperature\":30.035071643495087,\"humidity\":70.52682127516005,\"illuminance\":100}", "date": 1552376699940 } ]

참고사이트)

1. 위 내용 관련하여 MS Github에서 주고 받은 내용들

https://github.com/Microsoft/spring-data-cosmosdb/issues/347


2. 현재 google 에서 조회하면 가장 상단에 Azure SDK for Java Stable 나오는 페이지

https://docs.microsoft.com/ko-kr/java/azure/spring-framework/configure-spring-boot-starter-java-app-with-cosmos-db?view=azure-java-stable




Azure Everywhere

 퍼블릭 클라우드 하면 떠오르는 세 곳이 AWS, MS Azure, GCP 입니다.

AWS가 전 세계의 시장을 점유하고 있으며, GCP는 약간은 다른 노선을 걷고 있는가운데 최근 MS Azure의 적극적인 B2B시장 공략이 눈에 보입니다.

이와 관련하여 첫번째로 summit행사가 열렸으며 그 이름이 Azure Everywhere 입니다.


<오전세션>

오전세션은 다음과 같았습니다. 

키워드는 다음과 같습니다.

 - 개발자 중심

 - AI 대중화

 - 기술변화에 따른 사업구조 변화


<GitHub : 개발자 중심의 클라우드 플랫폼 응용과 진화의 방향>

세션의 설명에 앞서서 수년간 변화해온 IT를 살펴볼 필요가 있습니다.


 과거에는 IT의 핵심가치가 <원가절감>, <생산성 향상>에 있었습니다. 전통적인 산업의 비지니스가 존재했고 그 비지니스 프로세스를 그대로 모델링하여 IT시스템을 구축하여 서포트하는 것이었습니다. EA를 설계하고 각 도메인의 SA,DA,TA위에 비지니스를 분석하여 설계하면 개발자는 그대로 개발하는 것이었습니다. 각 영역을 담당하는 전문가들이 있었으며 대부분 외부 인력이였기 때문에 공정과 절차가 중요했으며 소프트웨어도 납품받아서 사용하는 것이 일반적이었습니다.


 그러나 사업환경이 점차 급변하면서 IT자체를 상품으로 하는 새로운 비지니스들이 출현하기 시작했습니다. 산업간의 경계가 무너지고 모든 기업이 소프트웨어 기업이 되어야만 하는 세상이 다가왔습니다.

 이제는 IT의 핵심이 <가치>가 되었습니다. 끊임없이 변하는 시장환경에 전통적인 개발방법론으로는 대처하기가 어렵고, 뭔가를 개선하고자 프로젝트를 계속 진행해도 여러 한계점만 나타나게 되었습니다. 

(일정지연, SW인력의 소모품화, 요구를 충족하지 못하는 제품, 높은 시스템 유지비용 및 변경비용 등.)


 전 세계적으로 이러한 상황을 극복하기 위해서 많은 시도가 이루어졌고 애자일이 대표적인 사례입니다.

(애자일 선언문은 업종에 관계없이 꼭 한번 읽어보시기를 강추드립니다. 참여하신 분들 이름만 봐도 ㄷㄷㄷ..

다양한 영역에서 애자일하게 일하려는 시도가 있을만큼 배울점이 많습니다.)

 소규모의 팀(6~8명)이 자체적으로 기획/설계/개발/테스트를 빠르게 반복하여 고객에게 가치 있는 제품을 만드는 것을 목표로 합니다. 이러한 과정속에서 자체적으로 개발/운영을 수행하고 본인들에게 필요한 소프트웨어는 오픈소스를 기반으로 직접 만들고 개선하는 것이 일반적이 되었습니다. 특히 오픈소스 진영은 전 세계의 개발자가 함께 개발하는 만큼 그 완성도나 속도는 벤더사를 넘어선지 오래입니다.


 이제 중요한 것은 공정과 절차가 아니라 사람, 신뢰, 협업, 문화입니다. 모든 팀원이 주인정신을 가지고 일해야 합니다. 특히 개발자(과거 아키텍트,개발자,QA등으로 분리되어있던 역할 )가 자주 언급될 수 밖에 없는 것은 최종 결과물(소프트웨어)이 가장 중요하기 때문입니다. 개발자는 앞으로 더욱 주도적으로 제품개발에 참여하며 그 속에서 문제를 파악하고 해결방법을 찾아서 적용해야 하며 과거보다 훨씬 넓고 깊은 역량을 보유하고 있어야 하며 협업을 생활화해야 합니다.

 다시 돌아와서 Github세션을 살펴보겠습니다.

MS가 GitHub을 인수하고 개발자 중심의 회사로 변신한 것은 대단한 일입니다.

 과거 MS는 리눅스와 같은 오픈소스를 적대시하고 탄압했습니다. "리눅스는 암"이라는 유명한 말도 있었죠.  자신들의 비지니스의 걸림돌이었기 때문입니다. 절대로 상용제품을 대체할 수 없다고 했고 무시하며 개발자중심의 세상을 비판했습니다. 

그러나 2014년 "MS는 리눅스를 사랑한다"라고 발표했고, 현시점 오픈소스 기여자 1위는 MS입니다!

(2위가 구글입니다..)


 본 세션에서도 개발자의 생산성을 증가시키고 협업을 가속화하는 것에 집중하여 발표하고 있습니다. 많은 사람들의 우려와는 다르게 Github의 역할은 당분간 계속 변함이 없을 것으로 보입니다.



“MS는 개발자를 최우선으로 하는 기업이며

깃허브와 함께함으로써 개발자의 자유, 개방성, 혁신에 대한 우리의 의지를 강화할 것

“우리는 이번 인수 계약에 담긴 ‘공동체에 대한 책임’을 인식하고 있으며, 

모든 개발자가 시급한 문제를 해결하고 혁신할 수 있도록 돕는 데 최선을 다하겠다”

사티아 나델라 MS 회장, 발표문-



현실은 여전히 많은 개발자들이 소스코드를 작성하는데 50%미만의 시간을 쏟고 있습니다. 


Top 과 Low 의 차이입니다. 새로운 일에 할당하는 비율과, 잡무(?)에 할당하는 비율이 눈에 들어옵니다.

특히 이 그래프를 보면서 지금 아마존에서 일하고는 있는 개발자 친구들이 생각났습니다. 그 친구들의 말에 의하면 80%이상의 시간을 개발에 전념할 수 있도록 모든 절차와 제도가 마련되어 있다고 합니다.


 여러 방법과 도구, 문화를 통해서 이러한 변화를 주도하고 있음을 보여줍니다. 

(개발자들이 사용하는 모든 것이 오픈소스기반으로 Github에 모여있다고 해도 과언이 아닙니다. 누구나 가져가서 쓸수 있습니다. 그러나 쉬운 일은 아니고 공짜도 아니며 본인도 기여해야 합니다.)


최근 마이크로소프트의 행보를 보면

- Github인수등 오픈소스 적극지원

- Windows 10 리눅스 탑재

- VisualStudio Code 오픈소스화 (스크립트 부분에서는 VS Code가 점유율 90% !  )

- MS Azure의 리눅스 지원, 크로스 플랫폼, Intellij Plugin 지원등

등 시장의 반응을 봤을 때 방향은 제대로 잡고 가고 있다는 느낌을 받습니다.


<Databricks : 1% + 99% = AI 대중화>

 말이 필요없는 Databricks입니다. Spark는 Hadoop의 뒤를 이어서 거대한 생태계를 구축하고 있습니다. 

과거에는  자체적으로 클라우드 환경을 구축하고 서비스하려고 시도했지만 퍼블릭클라우드 변화에 맞춰서 MS Azure에 탑재하는 쪽으로 방향을 빠르게 전환한 듯 합니다. 

이전글: http://icthuman.tistory.com/entry/Spark-Summit-2017?category=572958


 Spark를 간단히 설명하면 대용량 병렬처리 프레임워크입니다. 

과거 Hadoop이 가지고 있던 디스크기반의 대용량처리의 한계점을 DAG의 개념을 통해서 메모리기반 처리로 바꾸어 최대 100배의 성능향상을 끌어냈습니다. 대부분의 ML에서는 반복작업이 많은데 Spark는 특히 반복문에서 성능향상이 탁월하기 때문에 ML분야에서 그 효과를 인정받았고 많은 라이브러리들이 Spark기반으로 변환되었습니다. 또한 SparkSQL을 통해서 프로그래밍 없이 SQL로 데이터를 조회할 수 있도록 사용자의 편의성을 증대시켰으며, lambda문법을 활용해서 데이터분석에 반드시 필요한 ETL의 기능까지도 흡수해버렸습니다. 추가로 Spark Streaming,(최근에는 Structured )를 활용해서 배치성 뿐만 아니라 실시간성 데이터까지도 처리합니다.

 이 모든기능을 포함하면서 다양한 분석함수들을 내장해서 누구나 쉽게 데이터분석을 할 수 있도록 하는것이 목표입니다. (Data Engineer와 Data Scientist가 같은 도구를 사용할 수 있다는 것은 큰 메리트입니다.)


Big Data를 해보신분들은 다 아시는 내용입니다. 왜 데이터 분석(AI) 가 어려울까요? 알고리즘이 어려워서? 

알고리즘은 크게 중요하지 않습니다. 아니 물론 중요하기는 합니다만 전문가들은 대부분 다음과 같은 이유를 꼽습니다.


1. (잘 전처리 된) 데이터가 없다. 

2. 무슨 도구를 써야 될지 모르겠다. (딥러닝 프레임워크는 정말 많습니다. Tensor Flow가 유명하긴 합니다.)

3. Data Scientist, Data Engineer가 없다. 혹은 협력이 어렵다.

이에 대해서 Databricks Runtime을 제공하여 ML을 돕는 환경을 Azure상에서 제공한다고 합니다.


또한 Data Preparation 부터 Model 생성/배포를 하나로 묶어주는 mlflow 역시 제공한다고 합니다. 저도 비슷한 것을 만들어봤던 경험이 있는데, Databricks가 한다니 완성도가 기대됩니다.

 각 유형에 따라서 MS Azure상에서 PaaS를 어떻게 활용하여 아키텍처를 구성할 수 있을지에 대한 가이드도 제공하고 있습니다. 다만 배치처리와 온라인처리를 동시에 하는 것이 최근의 추세인만큼 해당 내용을 반영하는 PaaS 구성요소도 빨리 제공이 되었으면 하는 바램입니다. (예를 들면 Druid라던지... )


이와 같은 시도를 통해서 AI의 대중화는 조금 더 빨리 찾아올 것으로 보입니다.


<레드햇 세미나와의 비교>

일전에 레드햇 세미나에서는 주로 클라우드로 인한 어플리케이션의 변화를 다루었습니다.

- 클라우드라는 의미처럼 인프라는 이제 구름속에서 보이지 않게 지탱해주는 존재가 되었습니다. 보다 비지니스와 어플리케이션에 집중할 수 있는 환경이 되었습니다. 또한 예전에는 각자 설치하고 사용했던 많은 환경들이 클라우드 서비스형태로 편하게 제공이 되기 때문에 이를 활용해서 더 많은 효과를 볼 수 있습니다.

- 모든 인프라의 요소들이 기능으로 제공됩니다.  이를 적절하게 활용하여 개발하면 장애복구, 배포/테스트, 릴리즈 등의 많은 작업을 자동화 시킬 수 있습니다. 소프트웨어 디파인이 가능합니다.

- Agile, Devops, CI/CD 등의 요소들도 클라우드에서 제공하기 때문에 연계가 가능합니다.


이번 MS Azure 세미나에서는 클라우드로의 통합, 활용방안, 앞으로의 방향성에 중점을 준 것으로 보입니다.

- 클라우드 도입으로 다양한 산업의 기술 / 비지니스 변화

- 클라우드로 전환할 때 정책, 비용, 도구, 고려사항

- 클라우드를 이용할 때 기존 요소들의 보완기능 (예, 오픈소스의 단점 등)

- 클라우드를 통해서 더 빠르고 쉽게 할 수 있는 것들 (AI, Data, Devops, Application)


<정리>

 여러 회사들이 주최하는 각 행사들은 알게 모르게 본인들의 강점을 어필하고 경쟁사와의 우위를 점하려는 의도들이 숨어있습니다. 대놓고 이야기하는 경우도 있고 아닌 경우도 있습니다. 그러나 여러 회사들이 동일하게 말하는 부분은 주의깊게 들을 필요가 있습니다. 세상이 변화하고 있는 방향이기 때문입니다. 

 모든 회사는 소프트웨어 회사가 될 것이다.
  우리나라 뿐 아니라 전 세계의 유명한 회사들을 보면 이를 명확히 알 수 있습니다. 기존의 도메인은 의미가 없습니다. 구글,네이버,카카오는 광고회사일까요? 애어비엔비는 숙박? 쿠팡, 카카오뱅크, 토스, 배달의 민족... 등 많은 유명한 회사들은 왜 이렇게 열심히 개발자를 뽑고 있을까요..
자체적인 소프트웨어 역량을 보유하고 산업전반의 기술변화와 더불어 사업구조도 같이 변화해야 합니다.

소프트웨어 역량, 그 중심에 개발자가 있습니다. 
 문제를 분석하고 논리적인 해결방법을 찾아서 기술을 통해서 구현하는 것이 개발자(팀)의 본질입니다. 수많은 개발자들이 오픈소스의 세상에서 다양한 제품를 만들고 공유하며 빠르게 개선해 나가고 있습니다. 과거처럼 벤더사가 주도해왔던 솔루션에 대한 종속성도 없어지고 있습니다. 또한 클라우드의 도입으로 많은 부분이 자동화되면서 인프라 또한 소프트웨어의 영역으로 넘어가고 있습니다. 개발자가 사용할 수 있는 기능들이 무궁무진합니다.

- AI는 빠르게 대중화가 될 것입니다. 
 오픈소스 그 중심에 AI가 있습니다. 더욱 넓은 분야에 활용될 것으로 보이며, 바로 가져다 쓸수 있는 데이터와 협업구조 개선, 도구의 출현들이 그 속도를 더욱 가속화 시킬것입니다. 
과거의 시스템에서는 데이터는 보존의 대상이었지만 이제는 활용의 대상이기 때문에 시스템을 만들때부터 접근을 다르게 해야 합니다. 최근 주목받는 여러 프로그래밍의 패러다임 변화역시 Control -> Data 중심으로 변화하고 있습니다.

- 전통적인 아키텍트, 개발자, QA등의 역할은 점차 사라지고 개발자로 통합됩니다.
 Product Owner/Manager등을 제외한 팀 멤버는 모두 제품(소스코드)에 관여합니다. 과거에 개발자만 소스코드를 작성했던 것과는 다르게 이제는 클라우드 배포를 위한 템플릿(인프라)부터 Layer구조/프레임워크/공통부(아키텍처), 비지니스 어플리케이션, 데이터, 테스트코드, 기술문서등 전 영역의 작업의 결과물이 소스코드로 완성되기 때문에 모든 인력이 개발자로 통합되고 있습니다. 포괄적인 문서보다 작동하는 소프트웨어를 중요시 하기 때문입니다.

<참고사이트>

https://agilemanifesto.org/iso/ko/manifesto.html

http://www.hani.co.kr/arti/economy/it/847716.html#csidx143ed953ac12498ac9e048e89f9c66a 

https://ko.wikipedia.org/wiki/%EC%95%A0%EC%9E%90%EC%9D%BC_%EC%86%8C%ED%94%84%ED%8A%B8%EC%9B%A8%EC%96%B4_%EA%B0%9C%EB%B0%9C

https://spark.apache.org/






'컨퍼런스' 카테고리의 다른 글

Red Hat Forum 2018 Seoul 후기  (0) 2018.11.07
Spark Summit 2017  (0) 2017.02.16

+ Recent posts