[마소 클라우드 특집] (4) 달리웍스의 클라우드 기반 IoT 개발…SaaS인 ‘씽플러스’

[마소 클라우드 특집] (4) 달리웍스의 클라우드 기반 IoT 개발…SaaS인 ‘씽플러스’


씽플러스(Thing+)는 사물인터넷(IoT) 응용서비스를 위한 서비스형 소프트웨어(SaaS)다. 사용자에게 IoT 경험을 제공하려는 서비스 파트너에게 클라우드 인프라에서 수행되는 애플리케이션뿐 아니라 임베디드 미들웨어와 클라이언트 애플리케이션까지 모두 제공해 쉽고 빠르게 서비스를 시작할 수 있도록 도와준다. 이번 글에서는 씽플러스 개발 경험을 바탕으로 클라우드 기반 응용서비스를 개발할 때 고려해야 할 점을 살펴본다.

 
필자 소개

이영수 yougsoo.lee@daliworks.net | 달리웍스의 CTO로서 달리웍스의 풀스택 개발자들과 함께 Thing+ 서비스를 개발하고 있다. 아로마소프트, 썬마이크로시스템즈, 오라클에서 Java VM 및 임베디드 분야의 제품 개발 경험을 가지고 있다.

정리| 유재석 기자 yoojs@imaso.co.kr

확장성(Scalable)과 고가용성(High availability)에 대한 고려

씽플러스는 개발환경 구성을 위해 한 대의 가상머신(VM)에서 모든 서비스를 수행할 수도 있고, 상용 서비스를 위해 수십 대 이상의 VM에서도 수행될 수 있는 확장 가능한 구조를 가진다. 또한, 장애조치(failover)를 통해 고가용성을 유지한다. 확장성과 고가용성을 만족하기 위해서 작은 기능 하나를 추가할 때에도 다음의 요소를 고민해야 한다.

– 하나의 인스턴스(instance)에서 문제가 있을 때 바로 다른 인스턴스에서 해당 기능을 수행할 수 있도록 장애조치(failover)가 가능한가

– 부하가 많이 걸리면 인스턴스를 더 늘려서 해결할 수 있도록 분산할 수 있는가. 샤딩(sharding)을 할 수 있는가. 작업큐(job queue)를 사용할 수 있나

– 여러 개의 인스턴스를 어떤 형태(active/standby, active/active, master/slave)로 수행할 것인가

풀스택 개발자의 생산성 향상을 위한 고려

씽플러스는 단순한 기능 하나를 추가하더라도, 기기 연결을 위한 임베디드 미들웨어, 클라우드 애플리케이션, 클라이언트 애플리케이션 등 다양한 코드를 수정해야 하는 경우가 빈번하다. 따라서 풀스택 개발자들이 이러한 기능을 쉽게 추가할 수 있도록 가능한 동일한 개발 언어인 자바스크립트를 이용하고 동일한 라이브러리 및 코딩 표준(coding convention)을 유지하려고 노력한다. 예를 들면 lodash(https://lodash.com/) 라이브러리를 임베디드 미들웨어, 서버 측과 웹 브라우저 클라이언트 코드에서 모두 동일하게 사용한다.

자동화, 자동화 그리고 자동화

씽플러스를 운영하기 위해서는 여러 대 서버를 관리해야 하고 새로운 버전의 애플리케이션을 적용하기 위한 릴리즈 등 다양한 작업이 필요하다. 그러므로 이러한 작업을 자동화할 수 있도록 클라우드를 구축해야 한다. 씽플러스에서는 노드 컨트롤(node control)과 셀 스크립트(shell script) 등을 사용해 자동화 코드를 직접 작성하고 있다. 앞으로도 서버 애플리케이션 및 인스턴스의 자동 배포를 위해 ansible 등과 같은 도구의 도입을 고려하고 있다.

또한, 복잡한 시스템을 항상 안정된 상태로 유지하기 위해 다음과 같은 자동화된 테스트를 수행하고 있다.

– 단위 테스트: 매 소스코드 커밋(commit) 시 CI(continous integration)가 수행되고 이때 단위 테스트를 수행한다

– 사용자 인터페이스 인터액티브 테스트: 주기적으로 사용자 애플리케이션의 인터액티브 사용자 인터페이스 테스트를 수행한다.

– 종단간(end to end) 테스트: IoT 기기에서 발생한 데이터가 서버에 저장되고 이에 의해 규칙이 수행되며 결과가 타임라인에 남는 전 과정을 지속적으로 확인한다.

클라우드 인프라에 독립적인 아키텍처와 사용 비용 최소화

특정 클라우드 인프라에 의존적인 기능은 최대한 줄이기 위해 도커(docker)등의 컨테이너 기술을 이용하여 아마존웹서비스(AWS), 애저(Azure), 사설 클라우드에서도 씽플러스의 수행이 가능하도록 한다. 그리고 클라우드 인프라의 사용 비용에 대한 과금 방식을 정확하게 이해해 최소 비용으로 씽플러스 기능이 동작하도록 구현한다. 동시에 사용자 경험을 해치지 않아야 하므로 항상 어려운 부분이다.

앞에서 명시한 고려할 점을 적용하기 위해 주키퍼(zookeeper)를 쉽게 사용할 수 있도록 도와주는 ‘zkHelper’를 개발하였고, 브라우저 테스트 자동화 도구인 ‘나이트와치(nightwatch.js)’를 활용하고 있다.

zkHelper-주키퍼를 이용한 분산처리 도우미

씽플러스 서비스는 수백 개 서버(이 글에서는 물리적 서버가 아니라, 단위 일을 처리하는 서버 측 애플리케이션)가 서로 협력해 복잡한 일을 나눠 수행한다.

분산 환경에서는 많은 서버를 관리하고 역할을 지정하기 위해 주키퍼가 널리 사용된다. 다른 대안들도 있지만 분산 환경의 조정자 역할을 하는 가장 인기 좋은 도구이기 때문이다. 주키퍼는 다음과 같은 특성이 있다.

– znode 단위로 관리된다.

– znode는 파일 시스템과 유사한 디렉토리 구조(path)를 가진다.

– znode는 부모(parent) 노드를 가져야 하며, 루트(root) 노드의 path는 ‘/’이다.

– znode는 데이터를 저장할 수 있다.

– znode는 path의 변화 또는 저장된 데이터의 변화를 통보받을 수 있다.

– znode는 Zookeeper와 클라이언트의 연결이 끊어지면 자동으로 삭제되는 Ephemeral 노드로 설정할 수 있다.

씽플러스 개발팀은 이러한 주키퍼의 특성을 사용해 분산환경에서 보다 쉽게 사용할 수 있도록 zkHelper를 오픈 소스 소프트웨어로 공개했다. 이를 사용해 실제 마스터를 선정하는 경우 znode가 어떻게 변경되는지를 살펴보겠다.

Node#1 서버 애플리케이션에서 zkHelper를 <리스트 1>의 옵션으로 초기화하면 <리스트 2>와 같이 주키퍼에 노드들이 생긴다.

node#2 서버 애플리케이션이 추가로 수행되면 /myapps/votes/n_00002로 2번 티켓을 받는다. 그러나 node#1이 1번 티켓(가장 빠른 티켓)을 가지고 있으므로 마스터 지위를 유지한다.

<리스트 1> zkHelper 초기화 옵션

{
basePath: 'myapps'
node: node#1:1234 // {hostname}:{port}
}

<리스트 2> 주키퍼에 생긴 노드

/myapps

<리스트 3> node#1 마스터 지위 유지

/myapps

마찬가지로 node#3, node#4 서버 애플리케이션이 추가로 더 수행되면 /myapps/nodes 노드와 /myapps/votes 노드에 자식 노드가 생성될 것이고 마스터도 변경되지 않는다.

장애가 발생해 마스터인 node#1 서버 애플리케이션이 주키퍼와 연결이 끊어지면 해당 노드(Ephemeral 노드로 등록돼 있으므로)는 사라진다. 이로 인하여 다시 마스터를 선출하는데, 이때 마스터 선출에 참여하는 모든 서버가 재시작한다. 따라서, 공정하게 경쟁해서 티켓을 차례로 가져가고 티켓번호가 낮은 서버가 마스터가 된다.
<리스트 4>는 node#3이 마스터가 된 경우의 znode 상태다.

<리스트 4> 마스터가 된 node#3

/myapps

이번에는 마스터 선출과 관련해 zkHelper의 규칙을 알아본다. 주키퍼의 시간 단위(tick)가 2초로 서버가 끊어졌다고 판단하는 기준시간(sessionTimeout)을 10초로 가정한다. 마스터를 선출할 상황이 되면 모든 서버는 경쟁하기 위해서 재시작한다. 단순 유지보수 목적 등으로 재시작한 경우는 기득권을 주기 위해 마스터가 10초(sessionTimeout) 내에 살아나게 되면 계속 마스터를 유지한다. 간혹 서버 간 네트워크 사정이 좋지 않아서 끊어지는 경우에는 마스터 선출과정이 빈번하게 발생한다. 이를 최소화하기 위해 일시적으로 네트워크가 끊어지더라도 5초 후에 다시 시도하도록 한다. 5초로 정한 이유는 주키퍼 시간 단위(tick)가 두 배에 50% 여유를 두었기 때문이다.

<리스트 5>를 통해 zkHelper의 사용방법을 알아본다. 주키퍼 세 대를 운용하고 있는 환경에서 마스터 서버 선출에 참여해 마스터/슬레이브를 결정하는 예제다. 직접 마스터 선출에 참여 하지 않고, 관찰자(Observer mode)가 되어 모니터링하는 예제도 있다. 서버 애플리케이션이 추가감소되는지, 마스터가 바뀌는지 점검한다.

<리스트 5> 주키퍼 3개가 운용하는 환경에서 마스터 서버 선출에 참여

var zk = require('zkHelper'),
options = {
basePath: '/myapps';
configPath: '/myapps/config',
node: require('os').hostname(),
servers: ['zk0:2181', 'zk1:2181', 'zk2:2181'], // zk servers
clientOptons: {
sessionTimeout: 10000,
retries: 3
}
};
zk.init(options, function (err, zkClient) {
var appConfiguration;
if (zk.isMaster()) {
console.info('i am master')
} else {
console.info('master', zk.getMaster() && zk.getMaster().master)
}
appConfiguration = zk.getConfig();
// do something
});

<리스트 6> 관찰자가 돼 마스터 선출을 모니터링 함

var zk = require('zkHelper'),
_ = require('lodash'),
options = {
servers: ['zk0:2181', 'zk1:2181', 'zk2:2181'], // zk servers
clientOptons: {
sessionTimeout: 10000,
retries: 3
},
observerOnly: true
};
zk.init(options, function (err, zkClient) {
var observer = new Observer('/otherApp');
observer.on('children', _.debounce(function (path, newVal, diff) {
consol.info('Master=%j', observer.getMaster());
logger.info('children:[%s] add=[%s] del=[%s]', newVal, diff.added, diff.deleted);
}, 500));
observer.on('data', function (path, newVal, oldVal) {
if (oldVal) {
logger.info('master change:' + path);
}
logger.info('Master=%j', observer.getMaster());
logger.info('[%s] data: %j

Nightwatch.js – 웹 애플리케이션 테스트 자동화

나이트와치는 웹 개발 코드에 대한 단위 테스트가 아니라 브라우저 기반에 실제 사용자의 환경과 동일하게 테스트할 수 있는 자동화 툴이다.

웹 개발에서 서버와 클라이언트의 단위 테스트에 대한 방법에는 좋은 툴과 다양한 방법이 있습니다. 씽플러스 서비스에서도 서버와 클라이언트에서 모두 사용하고 있지만 단위 테스트만으로는 사용자의 웹 환경에서 발생할 수 있는 오류를 놓치는 경우가 발생한다. 이를 방지하기 위해 사용자의 환경과 동일하게 하는 종단간 테스트가 필요하다. 나이트와치는 쉬운 문법과 설정으로 다양한 사용자 환경을 만들어 테스트를 할 수 있는 유용한 툴이다.

나이트와치 구조

나이트와치는 브라우저 기반의 테스트 프레임웍을 제공하는 오픈소스 프로젝트인 셀레니움(Selenium)을 이용한 node.js 기반 자동화 툴이다. 셀레니움은 웹 테스트를 위한 여러 프로젝트를 오픈 소스로 진행하고 있으며, 나이트와치는 그중에 셀레니움 웹드라이버(Selenium Webdriver)를 사용해 셀레니움 서버와 통신으로 브라우저를 제어한다.

나이트와치 환경 설정

먼저 node.js 설치한 후에 나이트와치를 설치한다. 전체 시스템에서 나이트와치를 사용하기 위해서는 -g 옵션을 이용한다.

$ npm install nightwatch

셀레니움 서버는 자바 기반으로 돼 있다. 자바 JDK 버전 6 이상을 설치한다. 자바 설치가 되면 셀레니움 다운로드 페이지에서 최신 버전을 다운 받는다. selenium-server-standalone-2.45.0. jar이 최신 버전이다. 다운로드 받은 jar 파일은 다음 명령으로 실행을 할 수 있다.

$ java -jar ./selenium-server-standalone-2.45.0.jar

셀레니움이 정상적으로 실행되었다는 메시지가 나오면서 대기 상태가 되면 정상 동작이다.

다음으로 브라우저 드라이버는 셀레니움 서버와 브라우저의 통신을 위한 WebDriver’s wire protocol을 지원하는 플러그인이다. 테스트를 진행할 브라우저별로 해당하는 드라이버를 설치해 줘야 한다. 전체 지원하는 브라우저 드라이버는 셀레니움 다운로드 페이지의 서드파티 드라이버 항목에서 찾을 수 있다.

나이트와치 실행

드라이버까지 설치를 완료했으면 이제 나이트와치 실행에 필요한 환경을 설정해야 하는데 나이트와치 깃허브(github)에서 제공하는 nightwatch.json 예제 파일을 참고하면 쉽게 작성할 수 있다.

nightwatch.json 파일의 작성이 완료되면 아래와 같이 나이트와치를 실행한다.

$ nightwatch –config ./nightwatch.json –env integration

–config 옵션은 nightwatch.json의 경로를 지정하고 –env 옵션은 위에서 설정한 test_settings의 리스트 중에서 하나를 입력한다. –env 옵션이 지정되지 않으면 default가 실행됩니다. –help 로 옵션에 대한 상세 정보를 확인 할 수 있다.

테스트 케이스 작성

nightwatch.json의 src_folders 설정 경로에 아래의 샘플을 파일로 저장하고 나이트와치를 실행하면 셀레니움 서버가 브라우저를 실행해 테스트 케이스를 자동으로 진행하는 것을 볼 수 있다.

<리스트 7> 테스트 샘플 파일

module.exports = {
'step one' : function (browser) {
browser
.url('http://www.google.com')
.waitForElementVisible('body', 1000)
.setValue('input[type=text]', 'nightwatch')
.waitForElementVisible('button[name=btnG]', 1000)
}
};

샘플 소스의 “step one” 함수의 “browser” 인수는 나이트와치의 Object다. 이 Object를 통해서 나이트와치에서 제공하는 API를 호출하고 필요한 테스트를 진행한다. 그리고 테스트 마지막에는 반드시 end()를 호출해 셀레니움 서버와의 세션을 종료해야 다음 테스트를 진행할 수 있다.

앨리먼트 지정 방식은 CSS selector 와 XPath 두 가지 방법을 모두 제공한다. 기본 설정은 CSS selector로 되어 있기 때문에 XPath를 사용하기 위해서는 nightwatch.json의 test_settings에 “use_xpath”: true를 추가하거나 테스트 케이스 내부에서도 다음과 같이 변경 가능하다.

<리스트 8> 테스트 케이스 코드 변경

this.demoTestGoogle = function (browser) {
browser
.useXpath() // every selector now must be xpath
.click("//tr[@data-recordid]/span[text()='Search Text']")
.useCss() // we're back to CSS now
.setValue('input[type=text]', 'nightwatch')
};

이상으로 나이트와치 환경 설정과 간단한 테스트 파일 작성을 했다. 나이트와치는 지속적인 개발이 진행되면서 안정성과 다양한 기능이 추가되고 있다. 좀 더 상세한 내용은 나이트와치 홈페이지에서 볼 수 있다.

 
INTERVIEW 이 영 수 달리웍스 CTO

Q 달리웍스의 씽플러스는 어떤 역할을 하는지 궁금하다.

A 짧게 설명하면 씽플러스는 IoT 응용 서비스를 위한 SaaS다. 자세한 설명은 달리웍스 홈페이지(www.daliworks.net)를 통해 확인할 수 있다.

Q 씽플러스를 개발하기 위해 주안점을 둔 부분은 무엇인가?

A 첫째, 다양한 IoT 기기들은 연결을 쉽게 해야 한다. 둘째, 서비스형 인프라(IaaS) 독립적이어야 한다. AWS, 애저, 사설 클라우드 등 어디서나 수행될 수 있어야 한다. 셋째, 확장성이 있어야 한다. 부하가 있을 때는 수십대의 가상머신에서 수행할 수 있고, 심지어는 가상머신 한 대에서도 모든 서비스가 수행될 수 있다.

Q 씽플러스 관련 플랫폼은 클라우드에만 올라가는지, 별도 서버에 구축돼 공장 안에서도 구축할 수 있는 건지 궁금하다.

A 현재는 클라우드에 올라가는 서비스 위주로 비즈니스 하고 있지만, 규모가 있는 경우에는 사설 클라우드 운영도 지원한다.

by 마이크로소프트웨어 유재석 기자 | yoojs@imaso.co.kr

RECENT USE CASES

건물 에너지 모니터링 서비스

건물의 에너지 사용량을 효율적으로 관리하기 위해서는 에너지의 사용에 대한 모니터링이 우선시 되어야 합니다.

설비 운영 모니터링 서비스

스마트 팩토리는 제조업의 미래이며, 설비 운영 원격 모니터링은 스마트 팩토리 구현을 위한 첫 번째 단계입니다.

지속가능한 축산업을 위한 축사 악취 모니터링

악취 민원이 증가하고 있는 가운데 축산냄새를 사전 방지하거나 저감할 수 있는 방법은 무엇이 있을까요? 더 나아가 지속가능한 축산업 발전 방향은 무엇일지 살펴보겠습니다.

제조업 AIoT의 미래, AI 모터진단 서비스

오늘날 디지털 전환을 추구하는 기업에 있어 필수 기능은 인공지능(AI)과 머신러닝(ML)이라고 할 수 있습니다. 그렇다면 국내 기업들은 AI/ML 기술을 얼마나 어떻게 도입해 어떤 업무에 활용하고 있을까요? 또한 기업들이 가장 선호하는 AI/ML 기술은 무엇이고 그것을 통해 기업은 어떤 혜택을 누리고 있을까요?

도로나 하천의 원활한 배수를 위한 IoT 서비스

보건복지예산 증가 등으로 최근 도로 부문 건설 비용은 감소 추세에 있으나, 국민 안전을 위한 유지보수 비용은 지속적으로 증가하고 있습니다. 도로 관리에 충분한 재정 투자가 어려운 현실에서 도로 투자에 대한 과학적인 의사 결정 체계(자산 관리) 도입을 고려해야 할 때입니다. 도로의 안전을 확보하고 기능을 유지하기 위한 IoT 서비스에 대해 알아보겠습니다.

RECENT BLOG POSTS

2024 DX 시장 동향 ┃ 디지털 트윈, 제조 AI, 스마트팩토리

2024년의 DX 시장 동향을 조망하고, 기술적 혁신과 기업들의 전략적 대응에 대해 자세히 살펴보겠습니다.

스마트 팩토리의 결정적 페인 포인트(Pain Point)와 해결책

씽플러스는 ‘데이터 수기 작성’을 하지 않아도 되는 스마트 팩토리를 만들고자 했습니다.

중소기업 생산 현장을 디지털 전환하는 방법

변화에 적극 대응하려면 중소기업도 자신만의 디지털 전환 계획을 세우고 적극 실행해야 합니다.

스마트 팩토리 시장 동향과 전망

스마트 팩토리 시장 현황을 알아보고 성공적인 스마트 팩토리 구현을 위해 기업들이 해결해야하는 과제와 효과적인 추진 전략를 살펴보려 합니다.

RECENT PRESS REPORTS

달리웍스, AIoT 국제전시회에서 PRIME 서비스 선보여

달리웍스는 AIoT 국제전시회에 참가해 신규 론칭한 PRIME 서비스와 다양한 산업별 솔루션을 소개했습니다.