AWS는 인스턴스의 생성과 삭제, S3로의 이미지 업로드, DynamoDB로의 스트림 업데이트, 이미지 분석, 문서 변환등 다양한 서비스를 제공한다. AWS 기반으로 서비스를 개발할 경우, AWS의 자원 변동상황을 트리거 해서 적절한 작업을 수행해야 한다. S3에 이미지가 업로드가 끝나면 섬네일을 만들거나, 이미지 업로드를 기다리는 다른 사람에게 이벤트를 발생하는 등의 기능이 그것이다.
보통은 별도의 서버를 만들어서 이런 일들을 하기 마련인데, 예를 들어 셈네일의 경우
파일 업로드가 끝나면
작업해야 할 파일의 이름을 message queue에 적재
이미지 처리 프로그램이 message queue로 부터 파일이름을 읽어와서 섬네일을 제작
섬네일 처리가 끝나면 다시 메시지를 만들어서 유저에게 전송
하는 방식으로 작동한다. AWS 람다 서비스를 이용해서 이 과정을 아래와 같이 단축할 수 있다.
S3에 def A라는 함수를 등록 한다.
def A는 이미지 업로드 완료 이벤트가 발생하면, 업로드된 파일을 읽어서 섬네일로 만든다.
섬네일 만드는 작업이 끝나면, 유저에게 작업 완료 메시지를 전송한다.
IFTTT 등 다른 서비스와 연동해서 트위터, 구글메일, 페이스북 등에 메시지를 보낼 수도 있다.
다른 추가적인 서버의 준비 없이 이런 일을 할수 있다. 코드를 정의하는 것으로 자유로운 확장이 가능하다는 장점이 있다. 특히 코드를 정의 할 수 있다는 점이 맘에 든다. IFTTT와 같은 서비스를 구축할 수 있지 않을까 ?
내가 관심있는 건 AWS 람다 서비스가 아니다. 람다 서비스의 IoT 응용이다. IoT 환경에서 기기들은 다른 기기, 유저, 웹 서비스와 연결 될 수 있다. IFTTT와 비슷한 서비스라고 보면 되겠다. 기기에서 어떤 이벤트가 발생하면, 내가 올린 코드를 실행하게 하는 방식.
인프라 구축등 해결해야 할 문제들이 많을 건데, 여기에서는 "개발 언어"에 대한 고민을 해보려고 한다. 일반사용자(그게 파워 유저라고 하더라도) 루비나 파이슨 코드를 올려라고 할 수 없는 노릇 아니겠는가.
루비 DSL을 이용해서 이 문제를 풀 수 있는지 확인해 보려 한다.
DSL은 Domain Specific Language 의 줄임말이다. 범용적으로 사용하는 언어가 아닌 특수한 (좁은)영역에 사용하는 언어를 통칭한다. 별로 사용하지 않는 언어라고 생각할 수 있겠는데, 이미 여러 영역에서 사용하고 있다. awk, 빌드 환경을 정의 하기 위한 make, ant, 스프레드쉬트에 내장된 매크로등이 DSL이다.
이들 DSL은 C와 같은 또 다른 언어를 이용해서 만드는데, 루비를 이용하면 좀 더 쉽게 DSL을 만들 수 있다. 실제 루비를 이용한 DSL은 여러 소프트웨어에서 응용되고 있다. Chef는 시스템관리를 위한 특수한 목적에 사용하는 언어인데, 시스템관리 목적에 맞는 DSL을 개발해서 사용하고 있다. 아래는 디렉토리를 관리하기 위해서 사용하는 chef 문법이다.
파이선의 문법 규칙을 따라야 하기 때문에, 표현에 제한이 생긴다. 루비 시나트라가 훨씬 직관적임을 알 수 있다.
DSL 적용 대상이 정해지면, 해당 대상을 묘사할 수 있는 제한된 스펙을 가지는 언어의 개발이 가능해지기 때문에, 개발자는 직관적으로 소프트웨어를 개발할 수 있다.
IFTTT도 특수한 목적의 서비스 이므로 DSL로 IFTTT의 서비스 엔진을 구현할 수 있지 않을까 ? ()현재 정리가 덜 된 생각이라서 물음표를 붙였다. 될 수도 있을 것 같은데, 세부적인 기술문제로 안될 수도 있다. 혹은 부분적인 기능만 구현이 가능할 수도 있고 아직은 잘 모르겠다.
먼저 어떤 방식으로 작동할지를 정의 해야 겠다. 단순한 전구를 기반으로 시나리오를 만들어 본다. 이 전구는 On, Off의 기능만을 가진다. 나는 On, Off 이벤트가 발생 했을 때, 어떤 코드를 실행하려고 한다. IF Then은 아래와 같이 구성할 수 있을 것이다.
전구 서비스를 사용하고 있다고 가정하자.
전구가 on 했을 때, gmail로 메일을 보내고 싶다.
IF는 "ON" 이고, Then은 "action sendmail"이다.
전구가 켜지면 "ON" 메시지가 발생하고, action sendmail을 실행한다.
시간도 IF 조건이 될 수 있다. 10분 후에 불을 켜라! 라거나 (산업용이라면) 매일 저녁 7시가 되면 불을 키고, 새벽 6시가 되면 불을 켜라. 라는 식으로 사용할 수 있을 거다. 일종의 스케쥴러인 셈이다. 스케쥴러는 독립적으로 만들어서 timer 이벤트를 만들도록 하면 될테다. 그러면 user:service_id:event:timer를 만들고, 여기에 대한 Then을 등록하면 된다. 스케쥴러 만드는 것도 재미있긴 하겠는데, 일단은 IF Then 만들어 보려고 한다.
IF에 해당하는 원본은 어딘가 데이터베이스 시스템에 저장할 테고, 실제 운영에는 REDIS를 사용하도록 한다. IF가 Key Then이 Value인 자료구조를 만들면 되겠다. Then에 매개변수만 두고, 실행 할 때는 recipe와 조합해서 코드를 만드는 방법도 있겠다. 이렇게 하면 공간을 절약할 수 있겠는데, 지금은 테스트가 목적이니 그냥 통째로 코드를 입력한다.
메시징 인프라는 IoT 메시지를 받아서, IF에 등록된 값인지를 search 해야 한다. 수많은 기기로 부터 메시지들 발생 할거다. 효과적인 search를 위한 구성이 필요하다.
스케쥴 이벤트 발생기도 필요하다.
이벤트 조건도 다양해 질 수 있다.
DSL을 이용해서 이런 요소들을 매개변수로 표현하는 건 그리 어려울 것 같지는 않다. 하지만 통계같은 경우를 처리해야 한다면 문제가 어려워 질 수 있다. 뭐, 이런 서비스에 쓸데없이 복잡한 기능이다라고 생각할 수도 있겠고 굳이 구현하려면 빅데이터 영역으로 넘겨서 배치처리하는게 맞는 방향이겠지만..
프로그램의 이름은 ifttt.rb다. /sensor/001/on과 /sensor/001/off 두개의 토픽을 subscribe 한다. 데이터가 오면, REDIS로 부터 DSL 코드를 읽어서 실행한다.
recipes.rb : 위의 코드를 그대로 사용한다. 실제 email을 전송하도록 코드를 수정한다.
유저가 만든 코드는 지속적으로 실행 될 거다. 캐쉬를 할 수 있다면, 성능을 크게 개선할 수 있을 것이다. 간단해 보이지만 (대량의 데이터 처리를 위해서) 클러스터링 시스템을 구축할 경우, 캐쉬하기가 애매모호해 진다. REDIS등의 네트워크 캐시 시스템을 이용할 수도 있겠지만, 네트워크 지연이 걸림돌이다.
Contents
1. AWS Lambda 서비스
2. Lambda를 이용한 IFTTT 서비스 구축
3. DSL
4. 작동 방식 정의
5. DSL 개요
6. 물론 준비해야 할 다른 많은 것들이 있다.
7. IFTTT 서비스 구현
7.1. 구성
7.2. ifttt server
8. 고민 거리들
8.1. eval
8.2. 코드 Cache
8.3. Jruby
8.4. 인프라 구성
1. AWS Lambda 서비스
2. Lambda를 이용한 IFTTT 서비스 구축
3. DSL
4. 작동 방식 정의
5. DSL 개요
6. 물론 준비해야 할 다른 많은 것들이 있다.
7. IFTTT 서비스 구현
7.1. 구성
7.2. ifttt server
8. 고민 거리들
8.1. eval
8.2. 코드 Cache
8.3. Jruby
8.4. 인프라 구성
Recent Posts
Archive Posts
Tags