스토리 홈

인터뷰

피드

뉴스

조회수 880

P2P금융에서 고도의 엔지니어링이 필수적인 이유

지난 8월30일, 매일경제신문이 주최하고 과학기술정보통신부와 금융위원회, 금융감독원이 후원한 매경핀테크어워드2018에서 렌딧이 최우수상을 수상했다. 렌딧이 굳이 이런 경연대회에 참여를 한 이유는 ‘P2P금융산업에서 기술력과 고도의 엔지니어링 파워가 얼마나 중요한 지’를 널리 알리고 싶기 때문이었다.매경핀테크어워드 수상 소식을 들은 후, 엔지니어링팀 렌딧맨들과최근 렌딧은 개발자 채용에 그 어느때보다도 열심이다. 많은 개발자들과 만나 P2P금융산업의 미래와 우리 회사가 하는 일에 대해 설명하고 좋은 개발자를 영입하기 위해 노력하고 있다. 그런데 생각보다 훨씬 더 개발자들에게 P2P금융기업이 어떤 일을 하고 있고, 왜 개발자가 도전할 만한 분야인지 알려져 있지 않다는 사실을 알게 되었다. 이번 글에서는 렌딧이 하는 일을 바탕으로 P2P금융회사에서 왜 고도의 소프트웨어 엔지니어링이 필수적으로 필요하고, 개발자 여러분이 어떤 일에 도전해 볼 수 있는지에 대해 설명해 보려고 한다. 우선 대출과 투자 등 모든 서비스가 기존 금융회사와 달리 온라인 상에서 이루어진다. 특히 렌딧이 집중하고 있는 개인신용 P2P금융의 경우, 대출 심사와 집행, 투자 모집과 운용 등 서비스 전 과정을 100% 온라인, 비대면 서비스로 구축하고 있는 디지털 금융 플랫폼이다.대출 서비스에서는 머신러닝 기반의 대출자 심사평가모델 개발이 핵심적이다. 렌딧이 자체 개발한 렌딧 개인신용평가시스템(Lendit Credit Scoring System)을 예로 들어 보겠다. 신용평가사에서 제공하는 250여가지의 금융 데이터를 순식간에 분석해 모든 대출 신청자마다 개인화 된 적정금리를 산출해 내는 시스템이다. P2P금융기업인 렌딧이 개발한 심사평가모델을 기존 금융권의 심사평가모델과 비교할 때 가장 큰 차이점은, 머신러닝 기법을 사용해 각종 금융 데이터의 최근 12개월 간 트렌드를 분석한다는 점. 이를 통해 보다 정교하게 개인의 신용을 평가해 낸다. 여기에 추가적으로 신용평가사에서 제공하는 사기정보공유(Fraud Bureau)데이터, 직장 신용정보, 상환 정보 등을 종합적으로 반영하고 있다. 최근에는 대출자가 제출하는 신분증 확인 과정에 머신러닝을 적용해 자동화해 나가기 시작했다. 투자 서비스에서는 실시간으로 분산투자 포트폴리오를 추천해 주는 알고리듬이 돌고 있다. 투자자가 투자할 금액을 입력하면 눈깜짝할 사이에 현재 투자 가능한 채권을 조합해 분산투자 포트폴리오를 추천해 주는 시스템이다. 포트폴리오에 조합된 모든 채권에 투자금을 일정한 비율로 고르게 나누어 분산투자할 수 있도록 추천해 주는 것이 특징이다. 렌딧이 개발한 분산투자 시스템은 투자자 1인이 수백~수천개의 채권에 분산하는 것과 동시에, 채권 1개도 평균 1,303명, 최대 3,814명(기준 2018년 6월30일 현재)이 나누어 리스크를 분산하도록 개발되어 있다. 이렇게 분산투자를 시스템적으로 활성화 시키고 있는 덕분에, 현재까지 렌딧의 모든 투자자가 하고 있는 분산투자의 총 누적 건수는 거의 800만 건에 육박하는 수준이다. 점점 더 많은 데이터가 축적되고 있기 때문에, 이러한 데이터를 바탕으로 고객에게 제공할 수 있는 서비스 아이디어도 하루 하루 쌓여 가고 있는 중이다.P2P금융산업이 가장 발전한 시장인 미국의 경우, 최대 규모인 렌딩클럽 한 회사가 미국 개인신용대출 시장 전체의 약 1.5%이상을 차지할만큼 금융 시장을 혁신해 나가고 있다. 렌딧 역시 지난 3년간 빅데이터 분석에 기반한 정교한 신용평가를 통해, 대출 고객의 이자를 총 100억원이 넘게 절약해 드리는 성과를 만들어 냈다. 그간 기존 금융회사들이 만들어 내지 못한 중금리 대출 시장을 스타트업인 렌딧이 활짝 열어낸 것이다.렌딧에서 우리 렌딧맨들과 함께 한국의 금융을 혁신하는 금융 플랫폼을 만들어 가실 엔지니어 여러분을 기다립니다. 관심있는 분은 주저없이 [email protected] 로 연락 주세요. 많은 엔지니어 여러분과 만나뵙고 싶습니다. 
조회수 2651

시뮬레이션에서의 Process Mining(프로세스 마이닝) 활용

시뮬레이션은 실제로 실행하기 어려운 실험을 간단히 행하는 모의실험을 뜻하며, 특히 컴퓨터를 이용하여 모의실험을 할 때는 컴퓨터 시뮬레이션이라고 일컬어집니다.  시뮬레이션은 특수한 하드웨어를 사용하는 3D 가상현실이나 비행 시뮬레이션 등 다양한 분야에 사용되고 있으며, 이벤트 중심의 로그를 다루는 프로세스 마이닝에서는 이산 사건 시뮬레이션을 중심으로 연구가 이뤄지고 있습니다.이산사건(discrete event) 시뮬레이션은 시간이 경과함에 따라 시뮬레이션 이 진행되는 것이 아니라 시스템 외부 혹은 내부에서 사건이 발생했을 때만 모델을 실행시킵니다. 이산사건 시뮬레이션에서 사건이란 시스템의 외부 혹은 내부에서 발생하는 추상적인 신호를 말하며, 이산 사건이란 임의의 시각에 불규칙으로 일어나는 사건을 의미합니다.이산 사건 시뮬레이션 모델을 잘 만들기 위해서는 사건 시간과 사건에 대한 정확한 기술이 필요한 데, 이를 위해 프로세스 마이닝이 사용될 수 있습니다.[그림] 프로세스 마이닝 기반의 시뮬레이션 모델 도출 (Discovering Simulation Model, Rozinat et a l., 2009)이것은 기존에 시뮬레이션 모델링이 현실 세계에서의 관찰 및 수작업에 의해 이뤄졌다면, 좀 더 쉽고 정확한 모델링을 위해서는 데이터 기반의 AS-IS 프로세스 파악에 능한 프로세스 마이닝을 사용해 볼 수 있지 않을까 하는 의문에서 출발합니다.아래 표와 같이 프로세스 마이닝과 시뮬레이션은 AS-IS 모델과 TO-BE 모델 각각의 영역에서 서로 보완하는 역할을 담당하고 있습니다. [표] 프로세스 마이닝과 시뮬레이션 단계별 역할 비교단계프로세스 마이닝 (AS-IS)시뮬레이션 (TO-BE)프로세스 설계프로세스 마이닝을 통해 도출한 실제 프로세스 모델을 바탕으로 프로세스 (재)설계다양한 대안 모델에 대한 검증 수행구현 및 실행구현하고자 하는 프로세스 모델의 표준 모델 준수 여부 확인시뮬레이션을 통해 테스트 및 검증 완료된 프로세스 모델 구현모니터링 및 분석표준 모델 준수 모니터링 및 병목 지점, 재작업 구간 분석시뮬레이션을 통한 병목 개선 구간 및 자원 수요 예측, 작업 시간 효율화 효과 분석 이러한 연구들을 바탕으로 최근에는 생산 공정 내 작업 현황 파악 및 성과 측정을 위해 생산 시스템의 이벤트 로그를 저장하고 분석하여, 제조 공정에 대한 시뮬레이션 모델 요소를 도출하려는 연구가 진행되고 있습니다. 이를 통해 프로세스 마이닝에서 찾은 병목 구간 등 문제점을 바탕으로 어떻게 개선할 것인지, 프로세스 변경 혹은 개선이 어떤 결과로 이어질지 What-if 분석을 통해 의사 결정을 위한 예측 방법이 제공되고 있습니다. 시뮬레이션 수행의 결과로 많은 수행 결과가 출력되며, 좀 더 나아가 사건과 이벤트에 대한 상세 기록들이 로그 데이터 형태로 나올 수 있습니다. 시뮬레이션이 가상 현실이라는 관점에서 현실에 대한 프로세스 마이닝 분석은 가상 현실에 대해 마찬가지로 유효합니다. 실제로 시뮬레이션 모델링을 하고 나서 시뮬레이션 모델링이 현실을 반영할 수 있도록 잘 되었는지 검증할 필요가 있는데, 시뮬레이션 로그에 대한 프로세스 마이닝 분석을 통해 해당 프로세스 모델을 도출할 수 있습니다.  얻어진 모델을 현실 세계에서 얻어진 프로세스 모델과 동일한 기준에서 비교하고 이에 대한 차이를 다시 시뮬레이션 모델이 반영하는 순환적 구조를 통해 좀 더 정확한 시뮬레이션 모델을 얻게 됩니다.  [참고 문헌]https://en.wikipedia.org/wiki/Simulation#퍼즐데이터 #개발팀 #개발자 #개발후기 #인사이트
조회수 1576

비트윈의 멀티티어 아키텍처를 위한 프레젠터 이야기

블로그 첫 글에서 비트윈의 시스템 아키텍처에 대해 다룬 적이 있습니다. 시스템 구성의 미래에 대한 계획으로 멀티티어 아키텍처에 대해 언급했었는데, 이는 프로토콜을 단순화시키고 배포 자동화를 가능하게 하기 위해서 클라이언트와 비즈니스 로직을 담당하는 서버 사이에 일종의 게이트웨이를 두는 것이었습니다. 그 외에도 여러 가지 필요성이 생겨 해당 역할을 담당하는 프레젠터라는 것을 만들게 되었고 비트윈의 채팅 시스템에 적용하게 되었습니다. 만드는 과정 중에 여러 기술적인 문제들이 있었고 이를 해결하기 위한 노력을 하였습니다. 이 글에서는 비트윈 시스템에서의 프레젠터에 대해 이야기 하고자 합니다.프레젠터¶프레젠터는 일종의 게이트웨이 입니다. 기존의 시스템에서는 클라이언트들이 ELB를 통해 채팅 서버에 직접 TCP 연결을 하였습니다. 하지만 비트윈 PC버전과 자체 푸시 서버를 만들면서 ELB로는 해결할 수 없는 부족한 점들이 생겼고, ELB의 부족한 점을 채워줄 수 있는 시스템이 필요하게 되었습니다. ELB를 대체하는 역할 외에도 다른 여러 필요했던 기능들을 제공하는 프레젠터를 만들기로 하였습니다.프레젠터는 ELB의 역할을 할 뿐만 아니라 여러 다른 기능들도 제공합니다.프레젠터의 기능¶패킷을 적절한 샤드로 중계¶비트윈에서는 커플 단위로 샤딩하여 같은 커플의 채팅 요청에 대해서는 같은 채팅 서버에서 처리하고 있습니다. Consistent Hash를 통해 커플을 여러 채팅 서버로 샤딩하고 ZooKeeper를 이용하여 이 정보를 여러 채팅 서버 간 공유합니다. 프레젠터 또한 ZooKeeper와 연결을 하여 어떤 채팅 서버가 어떤 커플을 담당하는지에 대한 정보를 알고 있도록 설계되어 있습니다. 따라서 프레젠터는 첫 연결 시 보내는 인증 패킷을 보고 해당 채팅 연결에서 오는 요청들을 어떤 채팅 서버로 보내야 할지 판단할 수 있습니다. 어떤 채팅 서버로 보낼지 판단하는 과정은 처음 한 번만 일어나며, 이후 패킷부터는 자동으로 해당 채팅 서버로 중계합니다.프레젠터의 이런 기능 덕분에 클라이언트는 더 이상 어떤 채팅 서버로 붙어야 하는지 알아내는 과정 없이 아무 프레젠터와 연결만 맺으면 채팅을 할 수 있게 되었습니다. 기존에는 클라이언트들이 여러 채팅 서버 중 어떤 서버에 붙어야 하는지 확인하는 작업을 한 후에 할당된 채팅 서버로 연결 맺어야 했습니다. 그래서 클라이언트가 채팅 서버와 연결을 맺기 위해 다소 복잡한 과정을 거쳐야 했지만, 이제는 클라이언트가 프레젠터의 주소로 연결 요청만 하면 DNS Round Robin 통해 아무 프레젠터와 연결하는 방식으로 프로토콜을 단순화할 수 있었습니다. 덕분에 새로운 채팅 서버를 띄울 때마다 ELB를 Warm-Up 시켜야 했던 기존 시스템의 문제가 없어졌습니다. 그래서 비트윈 개발팀의 오랜 염원이었던 채팅 서버 오토스케일의 가능성도 열렸습니다.많은 수의 연결을 안정적으로 유지¶PC버전과 푸시 서버를 만들면서 기존의 채팅 연결과 다르게 많은 수의 연결이 장시간 동안 유지 되는 경우를 처리할 수 있어야 했습니다. 기존에는 TCP 릴레이를 하도록 설정된 ELB가 연결들을 받아주었습니다. 한 머신당 6만 개 정도의 Outbound TCP 연결을 맺을 수 있는데, ELB도 트래픽에 따라 여러 대의 머신에서 돌아가는 일종의 프로그램이므로 이 제한에 걸린다고 생각할 수 있습니다. 따라서 많은 수의 연결을 맺어놓고 있어야 하는 경우 ELB에 문제가 생길 수 있다고 판단했습니다. (과거 ELB가 연결 개수가 많아지는 경우 스케일아웃이 안되는 버그 때문에 문제가 된 적이 있기도 했습니다) 또한 클라이어트 연결당 내부 연결도 하나씩 생겨야 하면 클라이언트가 연결을 끊거나 맺을 때마다 서버 내부 연결도 매번 끊거나 연결해야 하는 오버헤드가 발생합니다.이를 해결하기 위해 프레젠터에서는 TCP 연결을 Multiplexing하는 프로토콜을 구현하여 적은 수의 내부 연결로 많은 수의 클라이언트 연결을 처리할 수 있도록 하였습니다. 서버 내부에서는 고정된 개수의 몇 개의 연결만 맺어 놓고 이 연결들만으로 수많은 클라이언트 연결을 처리할 수 있습니다. 이처럼 TCP Multiplexing을 하는 것은 Finagle과 같은 다른 RPC 프로젝트에서도 지원하는 기능입니다.TCP Multiplexing 프로토콜을 통해 많은 수의 클라이언트 연결을 소수의 서버 내부 연결로 처리합니다.또한, 프레젠터는 많은 수의 SSL 연결을 처리해야 하므로 암복호화 로직을 실행하는데 퍼포먼스가 매우 중요하게 됩니다. 채팅 서버 한 대를 제거하거나 하는 경우 많은 연결이 한꺼번에 끊어지고 연이어 한꺼번에 연결을 시도하게 되는 경우가 있을 수 있는데, 이 때 대량의 SSL Handshaking을 하게 됩니다. 기존 서버들로 대량의 SSL Handshaking을 빠른 시간안에 처리하기 위해서는 높은 퍼포먼스가 필요합니다. Java로 작성된 프로그램만으로 이런 퍼포먼스 요구사항을 달성하기 어려우므로, 클라이언트와의 연결을 담당하는 부분은 OpenSSL, libevent를 이용한 C++로 코드로 작성하였습니다. 인증 패킷을 파싱하거나 패킷들을 릴레이 하는 등의 로직을 담당하는 부분은 Alfred라는 Netty를 이용하여 만든 인하우스 RPC 라이브러리를 이용해 작성되었습니다. 연결을 담당하는 부분은 TCP 연결을 유지하는 역할과 들어온 패킷들을 Netty로 작성된 모듈로 릴레이 하는 역할만 담당하므로 매우 간단한 형태의 프로그램입니다. 짧은 시간 안에 어럽지 않게 구현할 수 있었습니다.클라이언트의 연결을 받아주는 역할을 하는 부분은 C++, 실제 로직이 필요한 부분은 Java로 작성하였습니다.여러 네트워크 최적화 기술의 지원¶ELB에는 여러 네트워크 최적화 기술들을 아직 제공하지 않는 경우가 있습니다. 대표적으로 HTTP/2 혹은 SPDY, QUIC, TCP Fast Open 등이 있습니다. 특히 모바일 환경에서는 SSL Handshaking 등 부가적인 RTT로 인한 지연을 무시할 수 없으므로 이런 기술들을 이용한 초기 연결 시간 최적화는 서비스 퀄리티에 중요한 부분 중 하나입니다. ELB는 AWS에서 관리하는 서비스이므로 AWS에서 이런 기능들을 ELB에 적용하기 전에는 이용할 수 없지만, 프레젠터는 직접 운영하는 서버이므로 필요한 기능을 바로바로 적용하여 서비스 품질을 높일 수 있습니다. ELB에서 이미 제공하는 최적화 기술인 SSL Session Ticket이나 다른 몇몇 기술은 이미 적용되어 있고 아직 적용하지 않은 기술들도 필요에 따라 차차 적용할 예정입니다.프레젠터의 구현¶C++ 연결 유지 모듈¶프레젠터는 퍼포먼스를 위해 C++로 작성되었습니다. 이는 Pure Java를 이용한 암복호화는 프레젠터에서 원하는 정도의 퍼포먼스를 낼 수 없기 때문입니다. 처음에는 OpenSSL과 libevent를 이용해 작성된 코드를 JNI를 통해 Netty 인터페이스에 붙인 event4j라는 인하우스 라이브러리를 이용하려고 했으나, 코드가 복잡하고 유지보수가 어렵다는 점 때문에 포기하였습니다. 그 후에는 netty-tcnative를 이용해보고자 했으나 테스트 결과 연결당 메모리 사용량이 큰 문제가 있었고, 이를 수정하기에는 시간이 오래 걸릴 것 같아 포기하였습니다. 결국, 페이스북에서 오픈소스로 공개한 C++ 라이브러리인 folly를 활용하여 프레젠터를 작성하게 되었습니다. folly의 네트워크 API들이 OpenSSL과 libevent를 이용해 구현되어 있습니다.릴레이 로직¶프레젠터는 첫 인증 패킷을 파싱하여 릴레이할 채팅 서버를 판단하며, 이후의 패킷부터는 실제 패킷을 까보지 않고 단순 릴레이 하도록 설계하였습니다. 처음의 Netty 파이프라인에는 Alfred 프로토콜을 처리할 수 있는 핸들러들이 설정되어 있어 인증 패킷을 파싱 할 수 있으며 인증 패킷에 있는 정보를 바탕으로 어떤 채팅 서버로 패킷을 릴레이 할지 결정합니다. 그 이후 파이프라인에 있던 핸들러를 모두 제거 한 후, 읽은 byte 스트림을 Multiplexing Protocol 프레임으로 감싸서 그대로 릴레이 하는 매우 간단한 로직을 담당하는 핸들러 하나를 추가합니다. 덕분에 로직 부분의 구현도 매우 간단해질 수 있었으며, 채팅 서버에 API가 추가되거나 변경되어도 프레젠터는 업데이트할 필요가 없다는 운영상 이점도 있었습니다.Multiplexing Protocol¶프레젠터의 Multiplexing Protocol은 Thrift를 이용하여 직접 정의 하였으며, 비트윈 개발팀 내부적으로 사용 중인 RPC 라이브러리인 Alfred에 이 프로토콜을 구현하였습니다. Thrift를 통해 C++과 Java로 컴파일된 소스코드를 각각 프레젠터의 연결 처리 부분과 로직 처리 부분에서 이용하여 통신합니다. 프레젠터에서는 Multiplexing된 TCP 연결들을 Stream이라고 명명하였으며 이는 SPDY나 HTTP/2에서의 호칭 방법과 유사합니다. SPDY나 HTTP/2도 일종의 Multiplexing 기능을 제공하고 있으며, 프레젠터의 Multiplexing Protocol도 SPDY 프레임을 많이 참고하여 작성되었습니다.수 많은 클라이언트와의 TCP연결을 Stream으로 만들어 하나의 내부 TCP연결을 통해 처리합니다.Alfred에서는 Multiplexing 된 TCP 연결을 Netty의 Channel 인터페이스로 추상화하였습니다. Netty에서 TCP 연결 하나는 Channel 하나로 만들어지는데, 실제 Stream도 Channel 인터페이스로 데이터를 읽거나 쓸 수 있도록 하였습니다. 이 추상화 덕분에 비트윈 비즈니스 로직을 담당하는 코드에서는 Stream으로 Multiplexing 된 TCP 연결을 마치 기존의 TCP 연결과 똑같이 Channel을 이용해 사용할 수 있었습니다. 그래서 실제 비즈니스 로직 코드는 전혀 건드리지 않고 프레젠터를 쉽게 붙일 수 있었습니다.로드 밸런싱¶클라이언트는 Route53에서 제공하는 DNS Round Robin 기능을 이용하여 아무 프레젠터에 연결하여 채팅 요청을 날리게 됩니다. 하지만 무조건 동등하게 Round Robin 하게 되면 새로 켜지거나 하여 연결을 거의 맺지 않고 놀고 있는 프레젠터가 있는데도 연결을 많이 맺고 있는 기존 프레젠터에에 연결이 할당되는 문제가 생길 수 있습니다. 충분한 시간이 흐르면 결국에는 연결 개수는 동등하게 되겠지만, 처음부터 놀고 있는 프레젠터에 새로운 연결을 가중치를 주어 할당하면 로드를 분산되는 데 큰 도움이 될 것입니다. 그래서 Route53의 Weighted Routing Policy 기능을 이용하기로 하였습니다. 현재 연결 개수와 CPU 사용량 등을 종합적으로 고려하여 Weight를 결정하고 이를 주기적으로 Route53의 레코드에 업데이트합니다. 이런 방법으로 현재 로드가 많이 걸리는 서버로는 적은 수의 새로운 연결을 맺게 하고 자원이 많이 남는 프레젠터로 더 많은 새로운 연결이 맺어지도록 하고 있습니다.스케일 인/아웃¶AWS에서는 트래픽에 따라 서버 개수를 늘리기도 하고 줄이기도 하는 AutoScaling 이라는 기능이 있습니다. 프레젠터가 스케일 아웃될때에는 프레젠터가 스스로 Route53에 레코드를 추가하는 식으로 새로운 연결을 맺도록 할 수 있습니다. 하지만 스케일 인으로 프레젠터가 제거될 때에는 Route53에서 레코드를 삭제하더라도 함부로 프레젠터 서버를 종료시킬 수 없습니다. 종종 클라이언트의 DNS 캐싱 로직에 문제가 있어, Route53에서 레코드를 삭제되었는데도 불구하고 이를 업데이트하지 못해 기존 프레젠터로 연결을 시도하는 경우가 있을 수 있기 때문입니다. 따라서 프레젠터 클러스터가 스케일 인 될 때에는 기존의 모든 연결이 끊어지고 충분한 시간 동안 새로운 연결이 생기지 않은 경우에만 서버를 종료시켜야 합니다. AutoScaling Group의 LifeCycleHook을 이용하여 위와 같은 조건을 만족 시켰을 때에만 프레젠터 서버를 완전히 종료시키도록 하였습니다.못다 한 이야기¶프레젠터라는 이름이 이상하다고 생각하시는 분들이 있을 것으로 생각합니다. 멀티티어 아키텍처를 이야기할 때 프레젠테이션 티어, 어플리케이션 티어, 데이터베이스 티어로 구분하곤 하는데 이 프레젠테이션 티어에서 나온 이름입니다. 지금은 실제 프레젠터가 하는 역할과 프레젠테이션 티어가 보통 맡게 되는 역할에는 많은 차이가 있지만, 어쩌다 보니 이름은 그대로 가져가게 되었습니다.프레젠터에서 AutoScaling을 하기 위해 LifeCycleHook을 이용합니다. 이때 프레젠터를 위해 LifeCycleHook 이벤트를 처리하는 프로그램을 직접 짠 것이 아니라 비트윈 개발팀이 내부적으로 만든 Kharon이라는 프로그램을 이용하였습니다. Kharon은 인스턴스가 시작되거나 종료될 때 실행할 스크립트를 작성하고 인스턴스의 특정 위치에 놓는 것만으로 LifeCycleHook을 쉽게 이용할 수 있게 하는 프로그램입니다. Kharon 덕분에 비트윈 내 다양한 시스템에서 별다른 추가 개발 없이 LifeCycleHook을 쉽게 활용하고 있습니다. 후에 Kharon에 대해 자세히 다뤄보도록 하겠습니다.정리¶비트윈 개발팀에서는 오랫동안 유지되는 수많은 채팅 서버 연결들을 처리하고 클라이언트와 서버 간 프로토콜을 단순화시키는 등 여러 이점을 얻고자 ELB의 역할을 대신하는 프레젠터를 만들었습니다. 프레젠터를 만드는 과정에서 여러 기술적 문제가 있었습니다. 이를 해결하기 위해 C++로 연결 유지 모듈을 따로 작성하였고 Multiplexing Protocol을 따로 정의하였으며 그 외 여러 가지 기술적인 결정들을 하였습니다. 이런 과정에서 시행착오들이 있었지만 이를 발판 삼아 더 좋은 기술적 결정을 내리기 위해 고민하여 결국 기존 시스템에 쉽게 적용할 수 있고 쉽게 동작하는 프레젠터를 만들어 이용하고 있습니다.저희는 언제나 타다 및 비트윈 서비스를 함께 만들며 기술적인 문제를 함께 풀어나갈 능력있는 개발자를 모시고 있습니다. 언제든 부담없이 [email protected]로 이메일을 주시기 바랍니다!
조회수 5055

Bluetooth Low Energy(BLE) 파헤치기

1. What is BLE?스마트폰이 출시되어 대중화가 될 무렵, ‘스마트’한 개념의 밴드, 워치, 글래스 등이 출시되면서 웨어러블 디바이스 시장이 태동하기 시작했다. 그리고, 2015년 상반기, 애플워치의 등장으로 작은 생태계를 이루고 있던 웨어러블 디바이스들이 다시 한번 각광을 받게 되었다. 각기 생긴 모습은 다르지만 이들의 공통점은 스마트폰과 연동되어 작동한다는 것이었다. 과거부터 기기들간의 단거리 무선통신은 Bluetooth라는 기술이 이용되었다. Bluetooth가 공식적으로 등장한지 약 16년이라는 세월이 흘렀지만, 여전히 기기간의 무선통신에는 Bluetooth가 사용된다. 하지만, 지금 사용되는 Bluetooth는 기존과는 다른 방식이다. 바로 BLE라는 특징을 가진 Bluetooth인데, 바로 이것이 오늘날 다양한 종류의 웨어러블 디바이스들이 태어날 수 있었던 원동력이 되었다. 그렇다면 BLE라는 것이 도대체 무엇일까?그림1. BLE가 뭐지? 먹는건가?과거부터 기기들간의 무선 연결은 주로 Bluetooth라는 기술을 이용했는데, 이들은 기기간에 마스터, 슬레이브 관계를 형성하여 통신하는 Bluetooth Classic이라는 방식을 이용했다. 사람들이 이러한 기기들을 이용하면서 많이 염려했던 것은 ‘Bluetooth를 연결하면 베터리가 빨리 소모된다’, ‘사용하지 않을 때는 Bluetooth 꺼놓아야지’ 등과 같은 베터리 관련된 문제들이었다. 사실이었다. Bluetooth Classic은 다른 디바이스를 무선으로 연결을 하여 사용할 수 있는 편리함을 주었지만, 연결이 되는 동안에는 베터리를 빠르게 소모시켰기 때문에 사용하는 데에 많은 불편함이 있었다.2010년, 새로운 Bluetooth 표준으로 Bluetooth 4.0 이 채택이 된다. 기존의 Bluetooth Classic과의 가장 큰 차이는 훨씩 적은 전력을 사용하여 Classic과 비슷한 수준의 무선 통신을 할 수 있다는 점이었다. 이는 당시 Bluetooth의 최대 단점이었던 과도한 베터리를 소모 문제를 해결하는 기술이었기 때문에, Bluetooth 관련 업계에 큰 반향을 일으켰다. 이렇게 저전력을 이용하여 무선통신을 하는 특징을 Bluetooth Low Energy (이하 BLE) 라고 부르는데, Bluetooth 4.0 이후의 버전들은 이 용어로 대체되서 불리기도 한다. 최근 출시되고 있는 스마트 밴드, 워치, 글래스 등의 웨어러블 무선통신 기기들의 대부분은 이 BLE 방식을 이용하여 무선 통신을 한다.Bluetooth Smart Ready, Smart, ClassicBLE 기술이 등장하면서 Bluetooth 디바이스들은 아래와 같이 3가지로 분류 되었다.그림2. BLE 3가지 분류Bluetooth 4.0과 함께 새롭게 등장한 Bluetooth Smart Ready, Bluetooth Smart에 대해서 살펴보면,Bluetooth Smart Ready 디바이스는 Bluetooth Classic 및 저에너지 Bluetooth 무선통신 (BLE)을 지원하기 때문에 “듀얼 모드” 라디오라고 불린다. 따라서, 이들은 현재 시장에 나와 있는 수억 종의 Bluetooth 디바이스들에 대한 역방향 호환성을 가진다. 종류에는 스마트폰, 태블릿, PC, TV 그리고 셋탑박스 및 게임 콘솔 등이 있다. 이런 디바이스들은 클래식 Bluetooth 디바이스 및 Bluetooth Smart 디바이스들로부터 데이터를 받아, 이들을 유용한 정보로 변환시키는 Bluetooth 시스템의 허브라고 할 수 있다.Bluetooth Smart 디바이스 내에 있는 라디오는 “싱글모드” 라디오라 불리는데, BLE 연결만을 지원한다는 의미이다. 이들은 기존의 Bluetooth Classic 디바이스들과 호환이 되지 않고 듀얼모드 라디오를 가진 Bluetooth Smart Ready 디바이스 혹은 제조업체에 의해 호환성이 명시된 특정 Bluetooth 디바이스에만 연결이 가능하다. Bluetooth Smart 디바이스들은 ‘우리 집의 창문은 모두 잠겨 있는지’, ‘내 인슐린 농도는 얼마인지’, ‘오늘 내 몸무게는 몇 킬로그램인지’ 등과 같이 특정한 형태의 정보를 수집해, Bluetooth Smart Ready 디바이스로 보내기 위해 만들어진 디바이스이다. 종류에는 심박 모니터, 스마트 손목시계, 창문 및 현관 보안 센서, 자동차 키 체인, 그리고 혈압 팔찌 등이 있다.이 글에서는 BLE를 사용하는 디바이스들이 어떤 과정으로 서로 연결되어 통신을 하는지 그리고 이 과정들을 tracking 할 수 있는 장비인 Ubertooth 에 대해 내용을 정리해서 공유해보고자 한다.2. How they communicate?BLE를 지원하는 디바이스들은 기본적으로 Advertise(Broadcast) 과 Connection 이라는 방법으로 외부와 통신한다.Advertise Mode ( = Broadcast Mode)특정 디바이스를 지정하지 않고 주변의 모든 디바이스에게 Signal을 보낸다. 다시 말해, 주변에 디바이스가 있건 없건, 다른 디바이스가 Signal을 듣는 상태이건 아니건, 자신의 Signal을 일방적으로 보내는 것이라고 생각하면 된다. 이 때, Advertising type의 Signal을 일정 주기로 보내게 된다.Advertise 관점에서, 디바이스의 역할은 다음과 같이 구분된다.Advertiser ( = Broadcaster) : Non-Connectable Advertising Packet을 주기적으로 보내는 디바이스.Observer : Advertiser가 Advertise를 Non-Connectable Advertising Packet을 듣기 위해 주기적으로 Scanning하는 디바이스.그림3. Advertiser and ObserverAdvertise 방식은 한 번에 한 개 이상의 디바이스와 통신할 수 있는 유일한 방법이다. 주로 디바이스가 자신의 존재를 알리거나 적은 양(31Bytes 이하)의 User 데이터를 보낼 때도 사용된다. 한 번에 보내야 하는 데이터 크기가 작다면, 굳이 오버헤드가 큰 Connection 과정을 거쳐서 데이터롤 보내기 보다는, Advertise를 이용하는 것이 더 효율적이기 때문이다. 게다가 전송할 수 있는 데이터 크기 제한을 보완하기 위해 Scan Request, Scan Response을 이용해서 추가적인 데이터를 주고 받을 수 있다 (이에 대해서는 뒤에 자세히 설명한다). Advertise 방식은 말 그대로 Signal을 일방적으로 뿌리는 것이기 때문에, 보안에 취약하다.Connection Mode양방향으로 데이터를 주고받거나, Advertising Packet으로만 전달하기에는 많은 양의 데이터를 주고 받아야 하는 경우에는, Connection Mode로 통신을 한다. Advertise처럼 ‘일대다’ 방식이 아닌, ‘일대일’ 방식으로 디바이스 간에 데이터 교환이 일어난다. 디바이스간에 Channel hopping 규칙을 정해놓고 통신하기 때문에 Advertise보다 안전하다.Connection 관점에서 디바이스들의 역할은 다음과 같이 구분된다.Central (Master) : Central 디바이스는 다른 디바이스와 Connection을 맺기 위해, Connectable Advertising Signal을 주기적으로 스캔하다가, 적절한 디바이스에 연결을 요청한다. 연결이 되고 나면, Central 디바이스는 timing을 설정하고 주기적인 데이터 교환을 주도한다. 여기서 timing이란, 두 디바이스가 매번 같은 Channel에서 데이터를 주고 받기 위해 정하는 hopping 규칙이라고 생각하면 된다.Peripheral (Slave) : Peripheral 디바이스는 다른 디바이스와 Connection을 맺기 위해, Connectable Advertising Signal을 주기적으로 보낸다. 이를 수신한 Central 디바이스가 Connection Request를 보내면, 이를 수락하여 Connecion을 맺는다. Connection을 맺고 나면 Central 디바이스가 지정한 timing에 맞추어 Channel을 같이 hopping을 하면서 주기적으로 데이터를 교환한다.그림4. Central and Peripheral3. Protocol Stack디바이스들은 Bluetooth로 통신을 하기 위한 Protocol Stack을 가지고 있다. 일반적으로 네트워크 통신을 하기 위해서는, 통신을 위한 규약인 Protocol을 정의해야 되는데, 이렇게 정의된 Protocol들을 층층이 쌓아놓은 그룹이 Protocol Stack이다. Bluetooth Signal Packet을 수신하거나 송신할 때, 이 Protocol Stack을 거치면서 Packet들이 분석되거나 생성된다.그림5. Protocol Stack위 그림에서 볼 수 있듯이 Protocol Stack은 가장 아랫단부터 크게 Controller, Host, Application 로 나뉜다. 여기서는 Connection 과정에서 필요한 부분인 Physical Layer, Link Layer, Generic Access Profile(GAP), Generic Attribute Profile(GATT)에 대해서 알아볼 것이다.3.1 Physical LayerPhysical Layer에는 실제 Bluetooth Analog Signal과 통신할 수 있는 회로가 구성되어 있어서, Analog 신호를 Digital 신호로 바꾸어 주거나 Digital 신호를 Analog 신호로 바꾼다. 또한 Bluetooth에서는 2.4 GHz 밴드를 총 40개의 Channel로 나누어 통신을 한다. 40개 Channel 중 3개 Channel은 Advertising Channel 로써 각종 Advertising Packet을 비롯하여 Connection을 맺기 위해 주고 받는 Packet들의 교환에 이용된다. 나머지 37개의 Channel은 Data Channel 로써 Connection 이후의 Data Packet 교환에 이용된다.그림6. Channels3.2 Link LayerPhysical Layer의 바로 윗단에는 Link Layer이 있다. Link Layer은 하드웨어와 소프트웨어의 조합으로 구성되어 있다. 하드웨어 단에서는 높은 컴퓨팅 능력이 요구되는 작업들 (Preamble, Access Address, and Air Protocol framing, CRC generation and verification, Data whitening, Random number generation, AES encryption 등)이 처리되고, 소프트웨어 단에서는 디바이스의 연결 상태를 관리한다. 또한 통신하는데 있어서 디바이스의 Role을 정의하고 이에 따라 변경되는 State를 가지고 있다.RoleMaster : 연결을 시도하고, 연결 후에 전체 connection을 관리하는 역할.Slave : Master의 연결 요청을 받고, Master의 timing 규약을 따르는 역할.Advertiser : Advertising Packet을 보내는 역할.Scanner : Advertising Packet을 Scanning하는 역할. Scanner는 아래와 같은 2가지 Scanning 모드가 있다.Passive Scanning : Scanner는 Advertising Packet을 받고 이에 대해 따로 응답을 보내지 않는다. 따라서 해당 Packet을 보낸 Advertiser는 Scanner가 Packet을 수신했는지에 대해서 알지 못한다.Active Scanning : Advertising Packet을 받은 Scanner는 Advertiser에게 추가적인 데이터를 요구하기 위해 *Scan Request라는 것을 보낸다. 이를 받은 Advertiser는 *Scan Response로 응답한다.Scan Request, Scan Response : Advertising Packet type의 한 종류이다. 앞서, 31bytes 이하의 User data에 대해서는 Advertising Signal Packet에 넣어서 보낼 수 있다고 하였다. 하지만 31bytes보다는 크지만, Commection까지 맺어서 보내기는 오버헤드가 큰 데이터가 있을 때, Scan Request, Scan Response를 이용하면 두 번에 걸쳐서 데이터를 나눠 보낼 수 있게 된다. Advertising Packet을 받은 Scanner는 추가적인 User Data(예를 들어, Peripheral 디바이스의 이름)를 얻기 위해 Scan Request를 보내게 된다. Scan Request를 받은 Advertiser는 나머지 데이터를 Scan Response Signal에 담아서 보낸다.이들은 크게 Connection 전의 역할(Advertiser, Scanner), 후의 역할(Master, Slave)로 분류된다.StateLink Layer는 5가지 State를 가지고 있는데, 각 디바이스는 서로 연결이 되는 과정에서 이 State를 변화시킨다. 다음과 같은 5개의 State가 존재한다.Standby State : Signal Packet을 보내지도, 받지도 않는 상태.Advertising State : Advertising Packet을 보내고, 해당 Advertising Packet에 대한 상대 디바이스의 Response를 받을 수 있고 이에 응답할 수 있는 상태.Scanning State : Advertising Channel에서 Scaning하고 있는 상태.Initiating State : Advertiser의 Connectable Advertising Packet을 받고난 후 Connetion Request를 보내는 상태.Connection State : Connection 이후의 상태.아래 그림은 각각의 State를 Diagram으로 나타낸 것이다.그림7. Link Layer State3.3 Generic Access Profile (GAP)Generic Access Profile (GAP)는 서로 다른 제조사가 만든 BLE 디바이스들끼리 서로 호환되어 통신할 수 있도록 해주는 주춧돌 역할을 한다. 즉, 어떻게 디바이스간에 서로를 인지하고, Data를 Advertising하고, Connection을 맺을지에 대한 프레임워크를 제공한다. 그래서 GAP는 최상위 Control Layer라고도 불린다. Advertising Mode일 때, GAP에서 Advertising Data Payload와 Scan Response Payload를 포함할 수 있다.또한 GAP에서는 BLE 통신을 위해 Role, Mode, Procedure, Security, Additional GAP Data Format 등을 정의한다. 이들은 실제 API와 직접적으로 많은 연관이 있기 때문에 그 내용이 상당히 많지만, 여기서는 BLE Connection과 관련이 있는 Role에 대해서만 알아보겠다.RoleBroadcaster : Link Layer에서 Advertiser 역할에 상응한다. 주기적으로 Advertising Packet을 보낸다. 예를 들면, 온도센서는 온도데이터를 자신과 연결된 디바이스에게 일정주기로 보낸다.Observer : Link Layer에서 Scanner 역할에 상응한다. Broadcaster가 뿌리는 Advertising Packet에서 data를 얻는다. 온도센서로부터 온도데이터를 받아서 디스플레이에 나타내는 테블릿 컴퓨터의 역할이다.Central : Link Layer에서 Master 역할과 상응한다. Central 역할은 다른 디바이스의 Advertising Packet을 듣고 Connection을 시작할 때 시작된다. 좋은 성능의 CPU를 가지고 있는 스마트폰이나, 테블릿 컴퓨터들의 역할이다.Peripheral : Link Layer에서 Slave 역할과 상응한다. Advertising Packet을 보내서 Central 역할의 디바이스가 Connection을 시작할 수 있도록 하게끔 유도한다. 센서기능이 달린 디바이스들의 역할이다.3.4 Generic Attribute Profile (GATT)BLE Data 교환을 관리하는 GATT는 디바이스들이 Data를 발견하고, 읽고, 쓰는 것을 가능하게 하는 기초적인 Data Model과 Procedure를 정의한다. 그래서 GATT는 최상위 Data Layer라고도 불린다. 디바이스간에 low-level에서의 모든 인터렉션을 정의하는 GAP와는 달리, GATT는 오직 Data의 Format 및 전달에 대해서만 처리한다. Connection Mode일 때, GATT Service와 Characteristic을 이용하여 양방향 통신을 하게 된다. Service와 Characteristic에 대한 내용은 여기를 참고하길 바란다.GATT도 Data 처리와 관련해서 다음과 같은 역할을 정의한다.RoleClient : Server에 Data를 요청한다. 하지만 처음에는 Server에 대해서 아는 것이 없기 때문에, Service Discovery라는 것을 수행한다. 이 후, Server에서 전송된 Response, Indication, Notification을 수신할 수 있다.Server : Client에게 Request를 받으면 Response를 보낸다. 또한 Client가 사용할 수 있는 User Data를 생성하고 저장해놓는 역할을 한다.4. Packet TypeBLE 통신에서는 두 가지 종류의 패킷인 Advertising Packet, Data Packet만이 존재한다. Connection을 맺기 전에는 Advertising Packet type, 맺은 후에는 Data Packet type으로 Signal을 생성한다. Data Packet은 하나로 통일되지만, Advertising Packet은 특정 기준에 따라서 다음과 같은 성질들을 갖는다.ConnectabilityConnectable : Scanner가 Connectable Advertising Packet을 받으면, Scanner는 이를 Advertiser가 Connection을 맺고 싶어한다는 신호로 받아들인다. 그러면 Scanner는 Connection Request (이하 CONNECTREQ)를 보낼 수 있다. 해당 Connectable Signal을 보낸 Advertiser는 Scanner가 CONNECTREQ가 아닌 다른 타입의 Signal을 보내면 해당 Packet을 무시하고 다음 Channel로 이동하여 계속 Advertising을 진행한다.Non-Connectable : Non-Connectable Packet을 받은 Scanner는 CONNECT_REQ를 보낼 수 없다. 주로 Connection 목적이 아닌, Data 전달이 목적일 때 쓰인다.ScannabilityScannable : Scanner가 Scannable Advertising Packet을 받으면, Scan Request (이하 SCANREQ)를 보낼수 있다. Scannable Signal을 보낸 디바이스는 Scanner가 SCANREQ가 아닌 다른 타입의 Signal을 보내면 해당 Packet을 무시하고 버린다.Non-Scannable : Non-Scannable Signal을 받은 Scanner는 SCAN_REQ를 보낼 수 없다.DirectabilityDirected : Packet안에 해당 Signal을 보내는 디바이스의 MAC Address와 받는 디바이스의 MAC Address가 들어있다. MAC Address 이외의 데이터는 넣을 수 없다. 모든 Directed Advertising Packet은 Connectable 성질을 갖는다.Undirected : 해당 Signal을 받는 대상이 지정되어 있지 않다. Directed Advertising Packet과는 다르게, 사용자가 원하는 데이터를 넣을 수 있다.위의 내용을 종합하면, Advertising pakcet을 아래와 같이 4가지 type으로 나눌 수 있다.그림6. Advertising Packet Type5. How they really communicate?BLE 통신의 핵심은 ‘timing’이다.Before ConnectionConnection 전, 디바이스는 3개의 Advertising Channel을 이용해서 데이터를 주고 받는다고 했다. 이들은 이 3개의 Channel을 자신만의 time interval로 hopping한다. 서로의 hopping 규칙이 일치하지 않기 때문에 Channel이 서로 엇갈리는 경우가 많을 것이다. 예를 들어, Advertiser는 1번 Channel에 Advertising Packet을 보냈는데, 같은 시간에 Scanner는 3번 Channel에 대해서 Scanning을 하게 되면 데이터 전달이 되지 않는 것이다. 하지만 이러한 hopping이 빠르게 자주 일어나기 때문에, 두 디바이스가 같은 Channel에 대해 Advertising와 Scanning이 발생하는 경우도 많이 생긴다. 이 경우에 서로 데이터를 주고 받을 수 있다.After ConnectionConnection이 되면, Advertising은 종료되고 기기들은 Central, Peripheral 중 하나의 역할을 하게된다. Connection을 개시한 기기가 Central이며, Advertiser가 Peripheral이 된다. 그리고 두 디바이스는 엇갈렸던 hopping 규칙을 통일시킨다. 그렇게 함으로써, 매번 같은 채널로 동시에 hopping하면서 Signal을 주고 받을 수 있게 된다. 이는 둘 간의 Connection이 끊어질 때까지 지속된다.6. How they connect each other?디바이스간의 BLE 연결을 iPhone과 Zikto Walk와의 연결과정으로 설명하면 다음과 같다.1) Zikto Walk가 Advertising Channel을 hopping하면서 Advertising Packet을 보낸다.(Zikto Walk의 Advertising Packet 유형은 ADV_IND이다)2) iPhone Bluetooth를 켠 후, Zikto 앱에 Zikto Walk를 등록한다. iPhone은 Advertising Channel을 hopping하면서 Scan을 하다가 연결하려는 Zikto의 디바이스 이름 등의 추가적인 정보를 얻기위해 SCAN_REQ를 보낸다.3) SCANREQ를 받은 Zikto Walk는 SCANRSP를 보낸다.4) Pairing이 완료되고, Zikto Walk는 다시 Advertising Packet을 다시 일정 주기마다 보낸다.5) iPhone에서 Zikto Walk로부터 걸음 수 등의 Data를 받기 위해 Sync 버튼을 누른다. 이 버튼을 누르면 iPhone은 CONNECT_REQ를 보낸다.6) Zikto와 iPhone은 서로 Acknowledging을 시작하고, timing 정보 등을 동기화 한다.7) Connection이 완료된다.8) Connection이 완료된 후, Service Data, Characteristic Data 등에 대한 Data 교환이 일어난다.9) iPhone과 Zikto Walk간에 Data Sync가 완료되면, Connection이 해제되고, 다시 Advertising Packet을 보낸다. 이를 그림으로 표현하면 아래와 같다.그림6. Advertising Packet Type7. Ubertooth디바이스간 BLE를 이용한 통신 과정에 대해 알고나니, Bluetooth Signal Packet도 Capturing 할 수 있을 거라는 생각이 들었다. 검색을 해 본 결과, 오픈소스 Bluetooth Test tool인 Ubertooth라는 장치로 디바이스간의 BLE 통신을 tracking 할 수 있다는 사실을 알게 되었다. 가격은 100달러로 생각보다 저렴했지만 국내에서는 구매할 수가 없었다. 그렇다고 궁금한 것을 해보지도 않고 포기하는 것은 엔지니어의 마인드가 아니지 않겠는가. 직접 아마존 (www.amazon.com)에서 해외구매를 하였다. 이렇게 바다 건너 멀리서 날아온 Ubertooth를 사용했던 경험을 바탕으로, Ubertooth의 원리와 BLE 통신에 대해서 조금 더 자세히 설명을 해보고자 한다.Ubertooth는 10cm정도의 몸체와 그와 비슷한 길이의 안테나를 가지고 있는 매우 작고 귀여운 모양이다. 이것이 이름하여 Ubertooth!그림8. Ubertooth오픈소스이기 때문에 모든 소스가 공개되어 있고, 소스를 빌드하고 사용하는 방법도 Ubertooth Github 및 Ubertooth Blog에 잘 나와 있어서 사용하기가 수월했다.How it works?Ubertooth는 크게 Bluetooth Classic을 tracking하는 기능과 BLE를 tracking하는 기능으로 나뉘는데, 여기서는 BLE 통신을 tracking 하는 원리에 대해서 다루겠다.BLE는 앞에서 언급했다시피, Connection 전, 후로 통신하는 방법이 다르다. 그리고 위의 내용들을 꼼꼼히 읽은 독자라면 BLE 통신에서 가장 중요하다고 언급했던 timing 이라는 것을 기억할 것이다. timing 은 BLE 통신에서 굉장히 중요한 요소이기 때문에, 보다 더 자세하고 쉽게 설명을 해보겠다.종이컵 전화기를 사용하여 대화를 해야하는 두 사람이 있다. 종이컵 전화기는 총 40개가 놓여져 있다. 이 두 사람은 40개 전화기 중 하나를 사용해서 대화를 주고 받고, 일정시간 뒤에 다음번 전화기를 이용해야 한다. 이러한 커뮤니케이션 방식에서 소통을 하기 위해서는 한 전화기로 얼마만큼의 시간동안 통화를 할 것인지, 다음 전화기는 어떤 전화기를 사용할 것인지, 그리고 어떤 방식으로 자신들의 대화를 다른 사람들의 대화들로부터 구분할 것인지 등에 대해 알아야 할 것이다. 이것들이 위에서 말했던 timing 관련 정보이다.실제 BLE 통신에서 timing 과 관련된 정보들은 다음과 같다 : Access Adress, CRC Info, Hop Interval, Hop Increment (해당 내용들에 대한 자세한 설명은 여기를 참고하기 바란다). BLE 통신을 하는 디바이스들은 이 timing 관련 정보를 동기화하여, Connection이 맺어진 이후에 해당 규칙에 따라 Channel을 hopping하면서 데이터를 주고 받는다. Ubertooth는 바로 이 정보를 알아내어, Master, Slave와 같은 패턴으로 Channel을 hopping하면서 대화를 엿듣는다. 아까 말한 종이컵 전화기에 빗대어 말하면, 제 3자(Ubertooth)가 두 사람이 정한 대화 규칙을 알아내서, 매번 이들이 전화기를 바꿔가며 대화를 할 때 마다 해당 전화기의 대화 내용을 엿듣는 것이다. 굉장히 흥미로운 방법이 아닐 수 없다. 그렇다면 Ubertooth는 어떻게 이 정보를 알아낼까?Before Connection두 디바이스가 연결되기 전, Ubertooth가 timing 관련 정보를 알아내는 방법은 매우 간단하다. Scanner가 Advertiser에게 Connection을 맺기위해 보냈던 CONNECT_REQ을 기억하는가? 공교롭게도 해당 패킷에는 이 네 가지 정보가 전부 들어있다. Ubertooth는 그 정보를 추출해내어 저장해 두고, 그 규칙에 맞게 Channel을 hopping하면서 Signal Data를 전부 엿듣는다.그림9. Ubertooth로 Capture한 CONNECT_REQ packetAfter Connection이미 연결된 디바이스들은 CONNECT_REQ를 보낼 일이 없다. 그러면 Ubertooth는 Connection 이후의 상황에 대해서는 Signal Data를 엿듣지 못하는 것일까? 아니다. Connection 이후의 상황에 대해서 Ubertooth는 다음과 같은 방법을 이용한다.BLE Signal Packet은 Advertise Mode이든 Connection Mode이든간에 무조건 하나의 Signal Packet format만 존재하기 때문에, Packet마다 특정 정보가 존재하는 부분은 어느 Packet에서나 똑같다. 4가지 정보 중 Access Address라는 것은 모든 Signal Packet마다 존재한다. Access Address라는 것은 두 디바이스간의 Unique한 Connection을 나타내는 4bytes 크기의 Identifier로써, CONNECT_REQ를 보내는 디바이스에 의해 랜덤하게 생성된다. Ubertooth는 37개의 Data Channel을 hopping하면서 모든 Data Packet의 Access Address를 추출해내어 Look Up Table 형태로 저장해 놓는다. 그리고는 각각의 Access Address가 등장한 횟수를 세게 되는데, 가장 먼저 특정 횟수만큼 등장한 Access Address를 target으로 잡는다. 나머지 3가지 정보는 각각 추출해내는 방법 및 알고리즘이 따로 존재하는데 해당 내용도 위에 언급한 사이트에 잘 나와있다. 이렇게 해서 네 가지 정보를 알아낸 Ubertooth는 두 디바이스와 같은 패턴으로 Channel을 hopping하면서 Signal Data를 엿듣는다.그림10. Ubertooth로 Capture한 Aceess Address과 나머지 3가지 정보들이렇게 보면, Ubertooth로 모든 것을 할 수 있을 것처럼 보이지만, 몇 가지 한계점이 있기도 하다. Ubertooth가 timing 관련 정보를 얻어내는 과정에 대해 다시 한 번 생각해보길 바란다. 잘 모르겠다면, 직접 Ubertooth 구매하여 테스트를 해보는 것도 엔지니어로써 굉장히 좋은 경험이 될 것이다.8. ConclusionBLE 통신과 이를 tracking하는 Ubertooth에 대해서 알아보았다. 매우 장황한 내용처럼 보이지만 이것도 매우 압축해서 설명한 것이다. 하나하나 디테일하게 쓰기 보다는 BLE를 처음 접하는 사람이 최대한 이해하기 쉽도록 작성하는 것에 초점을 맞추었다. 위의 내용들을 바탕으로, 독자들이 BLE에 더 넒고 깊은 지식을 얻게 되었으면 하는 바램이다. 글을 읽으면서 Bluetooth Classic은 어떻게 통신하는지에 대해 궁금하신 분들도 있을거라 생각한다. 이에 대해서 간단히 언급하자면, Bluetooth Classic 통신 방식은 BLE보다 훨씬 더 복잡하다. BLE에 대해서 어느 정도 알게 되었다면, Bluetooth Classic에 도전해보는 것도 괜찮을 것이다. BLE내용과 관련해서 보충이 필요한 내용이나, 관련 경험 혹은 궁금한 점 등에 대해서 아낌없이 조이와 공유해주길 바란다.9. ReferenceAkiba, “Getting Started with Bluetooth Low Energy: Tools and Techniques for Low-Power Networking”, O’Reilly Media(2015)http://www.slideshare.net/steveyoon77/bluetooth-le-controllerhttp://www.hardcopyworld.com/ngine/aduino/index.php/archives/1132https://www.bluetooth.org/ko-kr/bluetooth-brand/smart-marks-faqshttp://trvoid.blogspot.kr/2013/05/ble.htmlhttp://blog.lacklustre.net/posts/BLEFunWithUbertooth:SniffingBluetoothSmartandCrackingItsCrypto/#조이코퍼레이션 #개발팀 #개발자 #개발환경 #업무환경 #인사이트 #경험공유
조회수 1584

AWS X-Ray를 이용한 분산 애플리케이션 분석

OverviewMSA(Micro Service Architecture)를 구축하다 보면 분산 애플리케이션에 대한 분석, 디버깅, 모니터링이 어려울 때가 있습니다. 이 문제를 풀기 위해 AWS에서는 X-Ray라는 분산 추적 시스템을 제공하고 있는데요. X-Rray는 요청이 애플리케이션들을 통과하는 전체 과정을 추적합니다. 오늘은 Lambda에서 X-Rray를 사용하는 방법을 간단하게 살펴보겠습니다. lambda debuggingAWS Lambda 콘솔 > 함수선택 > Configuration > Debugging and error handling > Enable active tracing 을 선택합니다.AWS X-Ray 서비스맵Lambda에서 Enable active tracing만 선택해도 Lambda 서비스용 노드와 Lambda 함수용 노드를 확인할 수 있습니다.Lambda SDK를 추가해 하위 세그먼트를 구성하고, 주석 및 메타 데이터를 포함시키는 등의 작업을 할 수 있습니다. 이번 글에서는 Python SDK를 이용해 샘플을 만들어 보겠습니다. 우선, pip로 aws-xray-sdk를 설치합니다.SDK 패치X-Ray에서 지원하는 라이브러리를 패치해 SDK가 하위 세그먼트를 생성하고 레코딩할 수 있도록 합니다. 그 다음 patch_all 함수를 사용해 지원되는 모든 라이브러리를 패치합니다. (patch 함수로는 특정 라이브러리만 패치할 수 있습니다.)X-Ray 지원 라이브러리 (18.07.10 현재) botocore, boto3, pynamodb, aiobotocore, aioboto3, requests, aiohttp, httplib, http.client, sqlite3, mysql-connector-python subsegment 생성 및 metadata 작성subsegmentxray_recorder.begin_subsegment/end_subsegment 메서드를 사용해 하위 세그먼트를 구성할 수 있고, @xray_recorder.capture 데코레이터를 사용해 함수에 대한 하위 세그먼트를 생성할 수 있습니다.annotation, metadataput_annotation을 사용해 주석을 기록할 수 있고 put_metadata를 사용해 메타데이터를 기록할 수 있습니다. 1) Service mapTrace timelineSegment annotationSegment metadata서비스 맵을 통해 요청에 대한 노드 연결을 시각화해서 확인할 수 있습니다. 간단한 방법으로 서비스 오류, 병목, 지연 등 애플리케이션의 여러 문제를 식별할 수 있습니다. Service map errorTrace timeline errorSegment Exceptions서비스 맵과 타임라인을 이용하면 동기/비동기 요청, 서비스별 상태 및 오류 내용까지 확인할 수 있습니다. Service mapTrace timeline지금까지 분산 애플리케이션 환경에서 사용하는 AWS X-Ray의 기본 기능들을 실행했습니다. 기본적인 기능들만 살펴봤는데도 AWS 플랫폼의 분산 어플리케이션 환경에서 요청 추적 및 검토, 문제식별, 성능개선 등을 유용하게 활용할 수 있다는 걸 알 수 있었습니다. 추가적인 설명은 아래 참고의 링크들을 확인해주세요. 1) 어노테이션 데이터는 검색용으로 인덱싱되고 메타데이터는 검색에 사용할 수 없습니다. 참고AWS X-Ray – 분산 추적 시스템AWS X-Ray SDK for Python - AWS X-Ray글이상근 팀장 | R&D 개발1팀[email protected]#브랜디 #개발자 #개발팀 #인사이트 #경험공유
조회수 1601

VCNC가 Hadoop대신 Spark를 선택한 이유

요즘은 데이터 분석이 스타트업, 대기업 가릴 것 없이 유행입니다. VCNC도 비트윈 출시 때부터 지금까지 데이터 분석을 해오고 있고, 데이터 기반의 의사결정을 내리고 있습니다.데이터 분석을 하는데 처음부터 복잡한 기술이 필요한 것은 아닙니다. Flurry, Google Analytics 등의 훌륭한 무료 툴들이 있습니다. 하지만 이러한 범용 툴에서 제공하는 것 이상의 특수하고 자세한 분석을 하고 싶을 때 직접 많은 데이터를 다루는 빅데이터 분석을 하게 됩니다. VCNC에서도 비트윈의 복잡한 회원 가입 프로세스나, 채팅, 모멘츠 등 다양한 기능에 대해 심층적인 분석을 위해 직접 데이터를 분석하고 있습니다.빅데이터 분석 기술큰 데이터를 다룰 때 가장 많이 쓰는 기술은 Hadoop MapReduce와 연관 기술인 Hive입니다. 구글의 논문으로부터 영감을 받아 이를 구현한 오픈소스 프로젝트인 Hadoop은 클러스터 컴퓨팅 프레임웍으로 비싼 슈퍼컴퓨터를 사지 않아도, 컴퓨터를 여러 대 연결하면 대수에 따라서 데이터 처리 성능이 스케일되는 기술입니다. 세상에 나온지 10년이 넘었지만 아직도 잘 쓰이고 있으며 데이터가 많아지고 컴퓨터가 저렴해지면서 점점 더 많이 쓰이고 있습니다. VCNC도 작년까지는 데이터 분석을 하는데 MapReduce를 많이 사용했습니다.주스를 만드는 과정에 빗대어 MapReduce를 설명한 그림. 함수형 프로그래밍의 기본 개념인 Map, Reduce라는 프레임을 활용하여 여러 가지 문제를 병렬적으로 처리할 수 있다. MapReduce slideshare 참조MapReduce는 슈퍼컴퓨터 없이도 저렴한 서버를 여러 대 연결하여 빅데이터 분석을 가능하게 해 준 혁신적인 기술이지만 10년이 지나니 여러 가지 단점들이 보이게 되었습니다. 우선 과도하게 복잡한 코드를 짜야합니다. 아래는 간단한 Word Count 예제를 MapReduce로 구현한 것인데 매우 어렵고 복잡합니다.MapReduce로 단어 갯수를 카운트하는 간단한 예제 (Java). 많은 코드를 작성해야 한다.이의 대안으로 SQL을 MapReduce로 변환해주는 Hive 프로젝트가 있어 많은 사람이 잘 사용하고 있지만, 쿼리를 최적화하기가 어렵고 속도가 더 느려지는 경우가 많다는 어려움이 있습니다.MapReduce의 대안으로 최근 아주 뜨거운 기술이 있는데 바로 Apache Spark입니다. Spark는 Hadoop MapReduce와 비슷한 목적을 해결하기 위한 클러스터 컴퓨팅 프레임웍으로, 메모리를 활용한 아주 빠른 데이터 처리가 특징입니다. 또한, 함수형 프로그래밍이 가능한 언어인 Scala를 사용하여 코드가 매우 간단하며, interactive shell을 사용할 수 있습니다.Spark으로 단어 개수를 카운트하는 간단한 예제 (Scala). MapReduce에 비해 훨씬 간단하다.Spark과 MapReduce의 성능 비교. I/O intensive 한 작업은 성능이 극적으로 향상되며, CPU intensive 한 작업의 경우에도 효율이 더 높다. (자료: RDD 논문)Apache Spark는 미국이나 중국에서는 현재 Hadoop을 대체할만한 기술로 급부상하고 있으며, 국내에도 최신 기술에 발 빠른 사람들은 이미 사용하고 있거나, 관심을 갖고 있습니다. 성능이 좋고 사용하기 쉬울 뿐 아니라, 범용으로 사용할 수 있는 프레임웍이기에 앞으로 더 여러 분야에서 많이 사용하게 될 것입니다. 아직 Spark를 접해보지 못하신 분들은 한번 시간을 내어 살펴보시길 추천합니다.기존의 데이터 분석 시스템 아키텍처기존의 데이터 분석 시스템 아키텍처기존의 시스템은 비용을 줄이기 위해 머신들을 사무실 구석에 놓고 직접 관리했으며, AWS S3 Tokyo Region에 있는 로그를 다운받아 따로 저장한 뒤, MapReduce로 계산을 하고 dashboard를 위한 사이트를 따로 제작하여 운영하고 있었습니다.이러한 시스템은 빅데이터 분석을 할 수 있다는 것 외에는 불편한 점이 많았습니다. 자주 고장 나는 하드웨어를 수리하느라 바빴고, 충분히 많은 머신을 확보할 여유가 없었기 때문에 분석 시간도 아주 오래 걸렸습니다. 그리고 분석부터 시각화까지 과정이 복잡하였기 때문에 간단한 것이라도 구현하려면 시간과 노력이 많이 들었습니다.Spark과 Zeppelin을 만나다이때 저희의 관심을 끈 것이 바로 Apache Spark입니다. MapReduce에 비해 성능과 인터페이스가 월등히 좋은 데다가 0.x 버전과는 달리 1.0 버전에서 많은 문제가 해결되면서 안정적으로 운영할 수 있어 비트윈 데이터 분석팀에서는 Spark 도입을 결정했습니다.Apache Zeppelin은 국내에서 주도하고 있는 오픈소스 프로젝트로써, Spark를 훨씬 더 편하고 강력하게 사용할 수 있게 해주는 도구입니다. 주요한 역할은 노트북 툴, 즉 shell에서 사용할 코드를 기록하고 재실행할 수 있도록 관리해주는 역할과 코드나 쿼리의 실행 결과를 차트나 표 등으로 시각화해서 보여주는 역할입니다. VCNC에서는 Zeppelin의 초기 버전부터 관심을 가지고 살펴보다가, Apache Spark를 엔진으로 사용하도록 바뀐 이후에 활용성이 대폭 좋아졌다고 판단하여 데이터 분석에 Zeppelin을 도입하여 사용하고 있고, 개발에도 참여하고 있습니다.또한, 위에서 언급한 하드웨어 관리에 드는 노력을 줄이기 위해서 전적으로 클라우드를 사용하기로 함에 따라서1 아래와 같은 새로운 구조를 가지게 되었습니다.새로운 데이터 분석 시스템 아키텍처새로운 데이터 분석 시스템 아키텍처새로운 데이터 분석 시스템은 아키텍처라고 하기에 다소 부끄러울 정도로 간단합니다. 애초에 전체 시스템 구성을 간단하게 만드는 것에 중점을 두었기 때문입니다. 대략적인 구성과 활용법은 아래와 같습니다.모든 서버는 AWS 클라우드를 이용수 대의 Zeppelin 서버, 수 대의 Spark 서버운영Spark 서버는 메모리가 중요하므로 EC2 R3 instance 사용로그는 별도로 저장하지 않고 서비스 서버에서 S3로 업로드하는 로그를 곧바로 가져와서 분석함중간 결과 저장도 별도의 데이터베이스를 두지 않고 S3에 파일로 저장Zeppelin의 scheduler 기능을 이용하여 daily batch 작업 수행별도의 dashboard용 Zeppelin을 통해 중간 결과를 시각화하며 팀에 결과 공유이렇게 간단한 구조이긴 하지만 Apache Spark와 Apache Zeppelin을 활용한 이 시스템의 능력은 기존 시스템보다 더 강력하고, 더 다양한 일을 더 빠르게 해낼 수 있습니다.기존현재일일 배치 분석코드 작성 및 관리가 어려움Zeppelin의 Schedule 기능을 통해 수행 Interactive shell로 쉽게 데이터를 탐험 오류가 생긴 경우에 shell을 통해 손쉽게 원인 발견 및 수정 가능Ad-hoc(즉석) 분석복잡하고 많은 코드를 짜야 함분석 작업에 수 일 소요Interactive shell 환경에서 즉시 분석 수행 가능Dashboard별도의 사이트를 제작하여 운영 관리가 어렵고 오류 대응 힘듦Zeppelin report mode 사용해서 제작 코드가 바로 시각화되므로 제작 및 관리 수월성능일일 배치 분석에 약 8시간 소요메모리를 활용하여 동일 작업에 약 1시간 소요이렇게 시스템을 재구성하는 작업이 간단치는 않았습니다. 이전 시스템을 계속 부분적으로 운영하면서 점진적으로 재구성 작업을 하였는데 대부분 시스템을 옮기는데 약 1개월 정도가 걸렸습니다. 그리고 기존 시스템을 완전히 대체하는 작업은 약 6개월 후에 종료되었는데, 이는 분석 성능이 크게 중요하지 않은 부분들에 대해서는 시간을 두고 여유 있게 작업했기 때문이었습니다.Spark와 Spark SQL을 활용하여 원하는 데이터를 즉석에서 뽑아내고 공유하는 예제Zeppelin을 활용하여 인기 스티커를 조회하는 dashboard 만드는 예제결론비트윈 데이터 분석팀은 수개월에 걸쳐 데이터 분석 시스템을 전부 재구성하였습니다. 중점을 둔 부분은빠르고 효율적이며 범용성이 있는 Apache Spark, Apache Zeppelin을 활용하는 것최대한 시스템을 간단하게 구성하여 관리 포인트를 줄이는 것두 가지였고, 그 결과는 매우 성공적이었습니다.우선 데이터 분석가 입장에서도 관리해야 할 포인트가 적어져 부담이 덜하고, 이에 따라 Ad-hoc분석을 수행할 수 있는 시간도 늘어나 여러 가지 데이터 분석 결과를 필요로 하는 다른 팀들의 만족도가 높아졌습니다. 새로운 기술을 사용해 본 경험을 글로 써서 공유하고, 오픈소스 커뮤니티에 기여할 수 있는 시간과 기회도 생겼기 때문에 개발자로서 보람을 느끼고 있습니다.물론 새롭게 구성한 시스템이 장점만 있는 것은 아닙니다. 새로운 기술들로 시스템을 구성하다 보니 세세한 기능들이 아쉬울 때도 있고, 안정성도 더 좋아져야 한다고 느낍니다. 대부분 오픈소스 프로젝트이므로, 이러한 부분은 적극적으로 기여하여 개선하여 나갈 계획입니다.비트윈 팀에서는 더 좋은 개발환경, 분석환경을 위해 노력하고 있으며 이는 더 좋은 서비스를 만들기 위한 중요한 기반이 된다고 생각합니다. 저희는 항상 좋은 개발자를 모시고 있다는 광고와 함께 글을 마칩니다.연관 자료: AWS 한국 유저 그룹 - Spark + S3 + R3 을 이용한 데이터 분석 시스템 만들기↩저희는 언제나 타다 및 비트윈 서비스를 함께 만들며 기술적인 문제를 함께 풀어나갈 능력있는 개발자를 모시고 있습니다. 언제든 부담없이 [email protected]로 이메일을 주시기 바랍니다!
조회수 1480

A씨의 일주일

스포카 개발팀 문성원입니다. 오늘은 스포카 개발팀의 가공의 개발자 A씨의 일주일을 통해, 스포카 개발팀에서는 일주일간의 개발 일정을 어떻게 진행하는지 살펴보겠습니다. 평소 스타트업(Startup) 개발팀의 문화에 관심이 있으셨던 분들에게 도움이 되길 바랍니다.월요일오전 10시, A씨는 평소보다 조금 일찍 사무실에 도착했습니다. 매주 월요일은 스포카 전체 미팅이 있는 날이기 때문이죠. 한 주간 각자 진행한 것을 토대로 이번 주에 진행할 일을 대외적으로 공표하는 이 회의에 앞서, 스포카 개발팀은 따로 미팅을 잠깐 가집니다. 그동안 지난 주 개발 사항, 이번 주 구현 목록 등을 트렐로(Trello)를 통해 정리한 뒤, 이를 전체 미팅에서 공유합니다. A씨는 지난 주에 미쳐 다 구현하지 못했던 서버의 몇 가지 기능과 클라이언트 신버전 배포 준비를 하게 되었습니다.정신없이 회의 하고 났더니 벌써 점심시간입니다. 늘 가던 근처 식당에서 즐겁게 점심을 먹고 사무실로 올라온 A씨는 막간을 이용해 간밤에 올라온 스포카 개발 블로그의 원고를 검토합니다. 몇 가지 오탈자와 맞춤법을 지적한 뒤 모두가 지루해할 월요일 오후 1~2시경에 공개하는 것이 목표입니다.올라간 블로그 글을 확인한 뒤에, A씨는 구현해야 할 서버 기능을 살펴보기로 했습니다. 생각보단 많긴 하지만 일주일 안에는 어떻게든 끝낼 수도 있을 것 같은 분량이네요. 우선 트렐로에 올라온 카드의 명세를 토대로 작업해야 할 내용을 체크리스트(Check List)로 정리합니다. 그다음은 모두가 짐작하시듯이 열심히 일합니다. A씨는 프로니까요.어느덧 저녁 시간이 다 되었습니다. 특별히 일이 없는 이상 야근은 하지 않는 주의인 A씨지만, 오늘만큼은 저녁을 먹고 조금 더 남아있기로 합니다. 팀 내에서 진행하고 있는 스터디 때문이죠. 혼자서 읽기는 까다로웠던 책을 다 같이 읽어보니 조금은 이해가 더 되는 느낌이 드네요.화요일A씨는 오전에 작업하던 중 이상한 점을 발견합니다. 구현하기로 한 기능이 기존 기능과 모순이 되기 때문이죠. 이걸 어떻게 해결할까 고민하던 A씨는 다행히 사무실에 남아있던 엔에이블러(Enabler)팀원들과 간단하게 미팅을 합니다. 문제를 설명하고 명세를 다시 확인한 A씨는 작성한 회의록과 함께 배포합니다. 트렐로의 해당 카드에도 첨부하여 나중에 다시 볼 수 있게 하는 것은 기본입니다.뜻하지 않은 문제 때문에 오전을 날려서 기분이 나빠진 A씨지만, 다행히 좋아하는 스파게티를 먹고 기운을 내기로 했습니다. 사무실에 올라와 인터넷 뉴스와 페이스북을 잠시 보던 A씨는 암묵적으로만 정해진 점심시간이 끝나자 바로 작업을 시작합니다. A씨는 프로니까요.그런데 문제가 있습니다. 오전에 배포한 회의록을 읽어 본 다른 팀원들이 이건 다른 문제의 원인이 될 수 있다고 합니다. A씨는 새 기능 추가가 단순히 로직이 아니라 클라이언트 UI를 포함한 대규모 변경이 필요하다는 것을 깨닫습니다. A씨는 새 기능에 대한 대략적인 스케치를 발사믹 목업(Balsamiq Mockup)으로 마친 뒤 이를 다시 배포합니다. 또한, 관련된 카드에 설명도 잊지 않습니다.수요일매주 수요일 오전에 스포카 개발팀은 짧은 미팅을 합니다. 금주의 진행사항 중 변경사항이나 도움이 필요한 내용을 공유하는 자리인데요. 여기서 A씨는 어제 일을 다시 정리해서 이야기하고, 일정이 지연될 수 있음을 전달합니다. A씨에게 할당된 카드 일부를 다음 주로 미루거나, 좀 한가한 사람에게 나눠주는 형식으로 짐을 던 A씨였지만, 여전히 큰일이 되어버린 기능 변경은 무거운 짐입니다.이런 대량의 작업 때문에 고민하던 A씨에게 같은 팀 B씨가 어떤 라이브러리를 소개해줍니다. A씨는 처음 보는 라이브러리인지라 B씨가 전담해서 가르쳐주는 모양이 되었지만, 생각보다 문제 해결에 큰 도움이 될 것 같습니다. 마침 다음 주에 개발 블로그에 글을 써야 할 당번이 된 A씨는 그 라이브러리에 대해 좀 더 공부해서 쓰기로 정합니다.B씨의 도움 덕에 진행 속도가 붙은 A씨는, 금주 업무 중 하나였던 클라이언트 새 버전의 테스트를 내일부터 진행하기 위해 페이스북이나 인터넷 뉴스도 보지 않은 채 열심히 일합니다. 이런 A씨의 프로다운 모습에 하늘도 감탄했는지, 퇴근 시간인 7시 전에 작업을 끝낸 A씨는 구현된 기능들을 테스트 해 보고 팀의 다른 개발자와 공유하기 위해 github에 만들어진 스포카 서버 코드 저장소에 푸시(Push)합니다.목요일구글 플레이(Google Play)는 하루 정도면 배포가 되니 다행이지만 애플 앱스토어(Apple App Store)는 일주일 정도의 심사기간이 있기 때문에 거절(Reject)당하지 않게 철저히 준비해야 합니다. 그래서 어느 때보다 A씨는 날카로운 눈매로 클라이언트를 점검합니다. 아니나 다를까 메뉴를 이동하다 보니 화면 구성이 흐트러지는 버그가 발견되었습니다. 하지만 프로답게 A씨는 당황하지 않고 재현 조건을 확인한 뒤, 클라이언트 담당자인 C씨에게 알려줍니다. “클라이언트 관련한 버그를 찾았는데, 트렐로를 확인해보세요.”라구요. QA(Quality Assurance) 업무 역시 스포카 개발팀은 직접 처리합니다.밖에 비가 오는지라 피자를 시켜먹은 뒤, 자리에 앉아 잠깐 쉬고 있던 A씨에게 D씨가 다가와서는, “어제 푸시한 소스를 내려받다(Pull)가 충돌(Conflict)이 났는데, 어떻게 병합(Merge)해야 할지 모르겠네요.” 라며 묻습니다. A씨는 D씨와 충돌이 난 소스를 함께 검토하고 문제가 발생하지 않게끔 조정한 뒤 이를 다시 푸시해서 상황을 종료합니다.이러는 사이 C씨가 A씨가 말한 버그를 고쳤다며 다시 확인해보라고 트렐로의 관련 카드를 “테스트” 리스트로 옮깁니다. A씨는 재현된 상황에서 문제 없이 동작하는 것을 확인하고 카드를 “완료” 리스트로 다시 옮깁니다. 이제 클라이언트 앱을 심의 신청하고 어제 구현한 서버 쪽 코드의 개선사항이 있는지 살펴봅니다. 서버는 클라이언트가 앱스토어나 플레이에 준비되는 것을 확인한 뒤, DotCloud에서 제공하는 배포 스크립트를 통해 손쉽게 버전업할 수 있기 때문에 시간이 좀 남아 있습니다. 현재로선 특별히 더 손댈 부분이 없다는 걸 확인한 A씨는 오늘도 즐겁게 퇴근합니다.금요일월요일과 마찬가지로 오늘도 A씨는 평소보다 조금 서둘러서 사무실에 도착했습니다. 오늘은 사내 전체적으로 한 주간 있었던 업무 내용을 간략하게 보고하는 자리가 있습니다. A씨는 이번 주에 맡은 서버 개발이 이러저러해서 이렇고 저렇게 바뀌었다고 설명한 뒤, 앱스토어에 신청되었다는 사실을 공지합니다. 전체 보고가 끝난 뒤엔 개발팀은 따로 남아서 약간 자세하게 금주 작업을 공유하면서 트렐로의 “완료” 상태에 있는 카드들을 정리하는 시간을 갖습니다.점심을 먹고 나서, 이번 주에 더는 급한 일정이 없다는 것을 확인한 A씨는 개발 블로그에 쓸 글을 정리하기 시작합니다. 수요일에 B씨가 알려 준 라이브러리의 사용 방법은 대강 배웠지만, 그것을 남에게 설명할 수 있을 만큼 자세히 알지는 못했기 때문에 A씨는 한동안 공식 문서와 예제 코드들과 씨름합니다. 그래도 어느새 옆에서 거들기 시작한 B씨 덕에 글은 생각보다 순조롭게 마무리되었습니다. 이제 다음 주 월요일까지 퇴고해서 블로그에 공개하기만 하면 되죠.생각보다 오늘 업무를 끝낸 A씨는 친구들과 약속이 있는 홍대로 가기 위해, 7시 정시에 사무실을 떠납니다.#스포카 #개발 #개발자 #개발팀 #개발자의일주일 #개발자의일상 #인사이트 #경험공유
조회수 2934

레코딩 플러그인 이야기

마음챙김명상앱 '마보'의 콘텐츠들은 모두 Waves 플러그인으로 프로세싱된다.(처음과 마지막을 제외하면) Waves에 대해 간단한 생각을 정리하자면 다음과 같다.머큐리 구입시 UAD와도 고민을 많이 했지만 소프트웨어로만 비교를 한다면 waves가 훨씬 편하게 사용이 가능하다. 그 중에서도 CPU로 돌릴 수 있다는 점이 제온 CPU 에서 강력하게 작용한다.(Waves 하드웨어가 필요하다면 영국콘솔회사 DiGiCo와의 합작품인 DiGiGrid라는것도 있다.)근데 문제는... 맥에서는 더이상 CPU파워가 따라주지 않는다는 것이다.이런 상황에서 밖에서 작업하기에 딱 좋은 솔루션이 있었다. Soundgrid라는 waves의 DSP솔루션이다.이 사운드그리드에 대해 요약하면 waves의 플러그인만 따로 모아서 랜케이블로 Soundgrid 연결을 하면 CPU의 부담을 주지 않고 Daw에서 똑같은 프로세싱이 가능하다.이번에 BLS에서 데모로 받은 Waves Soundgrid IMPACT SERVER를 까페에 들고 나왔다.문제는 예상했던 사이즈가 아닌 맥북보다 훨씬 커서 카페에 가지고 다니기 부담스러운 크기... 휴대성이라는 측면에서는 역시 좀 무리가 있지 않나 싶다.(사진참조)어쨌든 카페에서 작업이 가능하게 되었다는 점. 다만, 카페에 가는데 차가 필요하다는 점이 있겠다.앞서 말했듯 마보 콘텐츠는 waves외에 플러그인의 시작과 끝을 Izotope 플러그인을 쓴다.마지막에는 라우드니스를 위해 오존을 사용한다. 오존은 너무 유명한 플러그인이니 설명도 생략.녹음이 끝나면 바로 첫단에 오디오스위트로 걸어주는 RX5라는 플러그인이 있다.이 플러그인은 보이스를 녹음한다면, 혹은 볼륨이 크지 않은 클래식 악기를 녹음한다면 정말 요긴하다.첫째로 입에서 발생하는 립노이즈들을 효과적으로 빠르게 제거해 준다. 콘덴서 마이크에서 타는 쩝쩝거리는 소리들을 손으로 하나씩 잡을 필요가 없다. 그저 한번 클릭으로 모든 파형의 클릭소리들을 제거해준다.Waves Mercury에도 X-Click이있지만 Izotope의 RX5가 훨씬 퀄리티가 좋다.두번째로 De-noise의 강력한 기능이다. 녹음시에 발생되는 팬소음들은 사실 EQ를 통해 어느정도 제거가 가능한 험의 형태로 발생한다면, 전기적 접지의 부재로 인한 핑크노이즈는 쉽게 제거가 불가능하다.하지만. 이 De-noise의 노이즈 LEARN기능으로 노이즈를 분석한 후 노이즈를 획기적으로 제거할 수 있다.칭찬일색으로 보이지만 RX5는 유튜브 믹싱채널을 운영하는 Alan JS Han님도 추천을 하실 만큼 유명하다.(근데 Izotope는 품질은 정말 유명하나 CPU를 정말 힘들게 한다.)자세한 이야기는 각 사진 속에보다시피 크기가 생각보다 크고 3kg에 육박하는 mini-itx PC이다.. 공연장비가 베이스이기 때문에 랜케이블로 연결한다.프로툴 유저라면 한번쯤 겪어본 창프로툴 유저라면 한번쯤 겪어본 창보이스가 없는 부분을 선택해 기본으로 깔리는 노이즈를 분석한다.전 구간에 분석한 노이즈 커브를 적용한 모습.깔끔하게 정리되었다.(SSL프리에서 오는 하모닉스들도 제거)#마보 #콘텐츠 #프레임워크 #스택 #인사이트 #일지
조회수 1484

[H2W@NL] 전문가들의 고정밀 시너지, 하이브리드 HD 매핑

네이버랩스의 인재상은 passionate self-motivated team player입니다. 어쩌면 '자기주도적 팀플레이어'라는 말은 형용모순(形容矛盾)일 지도 모릅니다. 하지만 우린 계속 시도했고, 문화는 계속 쌓여갑니다. 다양한 분야의 전문가들이 경계없이 협력하고 스스로 결정하며 함께 도전하는 곳의 이야기를 전합니다. How to work at NAVER LABSH2W@NL 시리즈 전체보기지난해 11월, 네이버랩스는 국내 기업 중 최초로 도로 HD맵 데이터셋을 무상 배포했습니다. 수많은 국내 자율주행 연구자들을 위해서입니다. 그렇다면, 왜 자율주행 연구에 HD맵은 중요할까요? 안전하고 효과적인 자율주행을 위해서입니다. 센서 데이터와 HD맵을 연동하면 고층 빌딩이 즐비한 도심에서도 현재 위치를 끊김없이 정확하게 인식할 수 있도록 해주고, 복잡하게 얽혀있는 도로 구조를 광범위하게 파악해 효과적인 경로 계획을 세울 수 있으며, 신호등/횡단보도 등의 위치를 HD맵을 통해 미리 확인해 실시간 인지 정확도를 높일 수도 있습니다. 그래서 네이버랩스는 자율주행 연구 시작 시점부터 HD맵 솔루션을 함께 연구해 왔습니다. 그 결과가 하이브리드 HD 매핑입니다. 항공사진과 MMS 데이터를 융합해 고정밀 지도를 만드는 기술입니다. 다른 어디에서도 시도하지 못했던, 가장 독창적인 방식의 매핑 솔루션은 어떻게 개발되었을까요? 그 주역들의 이야기를 들어보았습니다.Q. 왜 HD맵 기술을 개발하나요?HD맵은 도로 자율주행을 위한 시작(김형준|시스템 소프트웨어 개발) 자율주행 시대가 온다고 합니다. 그렇다면, 반드시 그보다 먼저 필요한 것은 HD맵입니다. 자율주행 차량이 도로를 안전하게 주행하려면, 차선 단위의 아주 정밀한 정보가 필요하기 때문입니다. 보통은 MMS (Mobile Mapping System) 차량이 일일이 돌아다니며 수집한 도로 데이터로 HD맵을 제작하는 것이 일반적이지만, 이 방식은 소요되는 시간과 비용이 많습니다. 지역이 광범위해지면 더 많은 리소스가 필요하고요. 우리는 그걸 획기적으로 줄일 수 있는 방법을 찾고 싶었습니다. 정확도는 유지하되, 도시 단위의 넓은 지역을 더 빠르고 효율적으로 제작하는 솔루션을 찾았습니다. 그 결과가 네이버랩스의 하이브리드 HD 매핑 기술입니다. 항공 사진을 통해 대규모 지역의 도로의 레이아웃과 건물 정보 등을 얻고, 이 위에 자체 MMS 차량인 R1으로 취득한 데이터를 정합해서 HD맵을 만듭니다. R1이 최소한만 주행해도 HD맵을 제작할 수 있기 때문에, 소요되는 시간과 비용을 획기적으로 줄일 수 있습니다.(전준호|비주얼 피처맵 개발) 이렇게 완성된 HD맵에는 도로 자율주행에 필수적인 고정밀 정보들이 담겨 있습니다. 도로의 구조 정보인 로드 레이아웃 맵(Road Layout Map), 기하 정보를 가진 포인트 클라우드 맵(Point Cloud Map), 시각 정보를 가진 비주얼 피처 맵(Visual Feature Map) 등이죠.(신용호|센서 캘리브레이션) 우리가 하이브리드 HD 매핑이란 새로운 방식을 고안하고 완성할 수 있었던 건, 그 동안 지속적으로 개발해 온 자율주행 기술과 항공 사진 기반의 지도 생성 기술을 모두 내재화하고 있었기 때문이죠.도시 규모의 HD맵을 효율적으로 제작할 수 있는 독자 솔루션(이진한|PM/소프트웨어 개발) 사실 자율주행 기술을 연구하는 회사들은 많습니다. 그런데 독자적인 HD 매핑 기술까지 보유한 회사는 의외로 많지 않아요. 네이버랩스도 처음엔 그랬어요. 자율주행 프로젝트가 시작된 2016년 무렵엔 자체 HD 매핑 기술이 없다는 점이 아쉬웠어요. 센서만으로는 얻기 힘든 정보들을 미리 담아둘 수 있는 그릇이 HD맵인데, 바로 그 정보들이 자율주행의 성능을 높이는데 큰 역할을 하거든요. 결국 이 그릇을 만드는 방법을 내재화했죠. 이제는 도시 규모의 HD맵을 효율적으로 제작할 수 있는 독자 솔루션을 갖췄습니다. 실제로 이 결과물을 Localization에 바로 활용하여 자율주행 기술도 함께 고도화하고 있습니다.Q. 어떤 협업을 통해 개발되었나요?아웃풋이 바로 새로운 인풋이 되는(이진한|PM/소프트웨어 개발) 하이브리드 HD 매핑은 여러 분야의 전문가들이 함께 했습니다. 한 프로젝트의 결과물이 다른 프로젝트의 입력으로 연결되는 구조라고 할 수 있겠네요. 예를 들어 R1 하드웨어 장비 개발 프로젝트는 Sensor Calibration 프로젝트로 이어지고, 항공 매핑을 통해 만들어진 로드 레이아웃 데이터에 MMS 데이터를 연결하고… 이렇게 유기적인 의존 관계로 진행되었습니다.(이웅희|센서 데이터 툴 개발) 자체 개발한 MMS 차량인 R1에는 다수의 카메라, 라이다, GPS, 자이로센서 등 많은 센서들이 탑재되어 있어요. 이러한 개별 센서들에 대한 드라이버 개발은 물론 전체 센서 데이터가 동시에 들어왔을 때 유실 없이 저장할 수 있는 시스템 개발, 그리고 운용 소프트웨어 개발이 필요했습니다.(신용호|센서 캘리브레이션) R1이 수집된 데이터를 융합하기 위해서 반드시 필요한 과정이 있습니다. 캘리브레이션입니다. 각 센서간에는 상대적인 위치와 방향 등의 차이가 발생하는데, 캘리브레이션을 통해 정확하게 매칭을 시켜야 하죠. 그렇지 않으면 수집한 데이터들을 제대로 사용할 수가 없습니다.하늘과 도로에서 획득한 데이터를 융합하여 도시 규모의 HD맵 생성(김진석|항공 매핑) R1이 지상을 담당한다면, 저희는 하늘에서 찍은 정보를 활용합니다. 항공 사진을 통해 정확도를 획기적으로 높이는 방식을 개발했습니다. 항공 사진에서 8cm 해상도로 왜곡이 제거된 연직 정사영상(TrueOrtho)을 생성한 후, 도로 영역의 2D/3D 로드 레이아웃을 생성합니다. 여기에 R1이 수집한 포인트 클라우드 데이터를 정합하면, 대규모 지역의 HD맵을 빠르고 효율적으로 만들 수 있게 됩니다.(임준택|라이다 피처맵 개발) 이처럼 R1이 도로의 포인트 클라우드를, 항공기가 대규모 지역의 로드 레이아웃을 스캔해 결합하는 방식은 아주 새로운 솔루션입니다. 물론 그냥 붙인다고 HD맵이 바로 나오는 것은 아닙니다. 스캔 데이터에서 자동차나 사람같이 불필요한 부분을 지우는 딥러닝 모델을 만들고, HD맵을 사용할 차량이나 로봇을 위한 특징점을 추출하는 과정도 필수적입니다.서로 다른 분야의 전문가, 하나의 팀(전준호|비주얼 피처맵 개발) HD맵을 이루는 요소들, 즉 Road Layout Map/Point Cloud Map/Visual Feature Map 등의 구축 알고리즘을 각기 개발해, 이 데이터들을 잘 포함하고 있는 HD맵을 제작하는 거죠. 이렇듯 많은 팀의 협력으로 완성한 매핑 솔루션입니다. 항공 사진의 정합과 인식, MMS 차량의 데이터 수집을 위한 장비와 센서 시스템 구축, GPS와 LiDAR 데이터를 이용한 위치 인식 기술, 시각 정보 추출을 위한 딥러닝 기술 등 서로 다른 전문가가 하나의 팀으로 모여있어요. 같은 목적을 갖고 밀접하게 협업하기에 더 높은 수준의 연구와 개발이 가능한 것 같습니다.“결과도 중요하죠. 하지만 문제를 같이 정의하고, 함께 해법을 찾아가는 과정은 더 중요한 것 같아요. 그래야 좋은 결과가 이어질 수 있으니까요.”(김형준|시스템 소프트웨어 개발) 다양한 분야의 전문가들이 모여 유기적인 협업이 언제든 가능하다는 것은 프로젝트에서 난항을 겪을 때 큰 힘을 발휘합니다. 예전에, 데이터 취득 시스템의 안정성에 문제가 생긴 적이 있어요. 그때 하드웨어 엔지니어와 소프트웨어 엔지니어들이 모두 모여 동시에 검토를 했습니다. 필드를 돌며 문제 발생 시점의 상황을 함께 체크하고, 그 중 기구 엔지니어 분들이 원인을 찾아 문제를 해결했습니다.(김상진|하드웨어 설계) 저도 그때가 기억나요. 차량 진동으로 인한 간헐적인 회로 단락이 원인이었죠. 짧은 시간에 가장 정확한 답을 찾기 위해 필요한 것은, 역시 유기적인 팀웍인 것 같아요.(신용호|센서 캘리브레이션) 팀이 없는 것처럼 협업이 잘 된다는 점도 자랑하고 싶어요. 함께 잘하기 위해서라는 목표만으로 일에 몰입할 수 있다는 건 정말 좋은 경험이죠.Q. 경과, 그리고 목표는?서울시 2,000km 로드 레이아웃 지도 구축(김진석|항공 매핑) 서울시 4차선 이상 도로 2,000km에 대한 로드 레이아웃 구축을 완료했습니다. 자율주행에 필요한 도로 구조 정보(차선, 중앙선, 정지선, 좌회전 등의 노면표시)를 정밀한 벡터 데이터 형식으로 변환했습니다. 서울시만큼 큰 대도시 규모의 매핑이란 관점에서 보자면, 국내에서 유일한 기술입니다.(김형준|시스템 소프트웨어 개발) 하이브리드 HD 매핑의 자체 프로세스가 정립되면서, 예전과 비교해 최소한의 작업으로 원하는 지역의 HD맵을 생성할 수 있게 되었습니다. 무상 공개한 판교 및 상암 지역 HD맵도 이 결과물 중 하나죠.(이진한|PM/소프트웨어 개발) 상암/판교 지역의 HD맵 무상 배포를 DEVIEW에서 발표했을 때가 정말 보람되었던 것 같아요. 국내에서 자율주행을 연구하고 있는 많은 기관에서 데이터셋 신청을 해주셨어요. 저희의 솔루션으로 만든 HD맵이 국내 자율주행 기술 고도화에 도움이 될 수 있었으면 좋겠습니다.(전준호|비주얼 피처맵 개발) 네이버랩스의 HD맵은 도로 위의 정밀 위치 인식을 최종 목표로 하고 있습니다. 예를 들어 Visual Feature Map의 경우 위치 인식에 필요한 최소한의 시각 정보와 기하 정보를 Descriptor 형태로 경량화 했기 때문에, 대규모 도심 지역의 데이터도 용량이 아주 작습니다. 이러한 최적화를 계속할 계획이고요.미래 모빌리티 세상으로 한 걸음 더(김상진|하드웨어 설계) 매핑 시스템 고도화의 목표는 결국 신뢰성 높은 지도를 만드는 것에 있습니다. 하드웨어 시스템의 신뢰성/유연성/운용성을 빠르게 개선하고, 이를 더욱 저비용으로 구현할 수 있도록 개발을 지속하고 있어요. 이런 연구들의 결과가 모이고, 이러한 고정밀 데이터가 쌓이면, 우리가 상상하고 있는 미래 모빌리티 세상을 더욱 앞당길 수 있다고 생각합니다.
조회수 1859

Swift 4.1에서 딥링크로 앱을 여는 경우 크래시되는 문제 해결하기

최근 Xcode 9.3 버전이 배포되었습니다. 이 버전에는 가장 최신의 Swift 4.1 버전이 포함되어 있습니다. Swift 4.1에는 여러 흥미로운 개선사항들이 많지만, 치명적인 버그도 존재합니다. 바로 딥링크를 통해 앱을 여는 경우 크래시가 발생하는 문제입니다. StyleShare에서는 QA 과정을 통해 문제를 발견할 수 있었습니다.만약 여러분의 애플리케이션이 아래 조건을 모두 충족할 경우 문제가 발생합니다:Swift 4.1 버전을 이용해서 빌드한 경우Deployment Target이 iOS 11.0 미만인 경우AppDelegate에서 application(_:open:sourceApplication:annotation:) 메서드를 구현한 경우문제를 재현하기에 가장 좋은 방법은 Safari 앱을 이용하는 것입니다.1. iOS 기기 또는 사뮬레이터에서 Safari 앱을 구동합니다.2. 주소 입력란에 앱이 지원하는 딥링크 URL을 입력한 뒤 이동합니다. (e.g. myapp://)3. 앱이 구동됨과 동시에 강제 종료됩니다.이 버그는 Swift 이슈 트래커에 SR-7240 티켓으로 이미 등록되어 있습니다. Resolved 상태로 표시되지만 이번 Xcode 9.3 버전에는 포함되지 않은 것으로 보입니다. 다행히 댓글에 한 개발자가 문제를 해결할 수 있는 workaround를 공유해두었는데요. 이 방법을 이용하면 당장의 문제는 해결할 수 있습니다. AppDelegate 메서드의 annotation 파라미터의 타입을 Any에서 Any?로 변경하는 것입니다.- func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool + func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any?) -> Bool<iframe width="700" height="250" data-src="/media/0ce1fe8c63fca7a6c953233b94406d02?postId=ed495077c36" data-media-id="0ce1fe8c63fca7a6c953233b94406d02" data-thumbnail="https://i.embed.ly/1/image?url=https://avatars2.githubusercontent.com/u/931655?s=400&v=4&key=a19fcc184b9711e1b4764040d3dc5c07" class="progressiveMedia-iframe js-progressiveMedia-iframe" allowfullscreen="" frameborder="0" src="https://medium.com/media/0ce1fe8c63fca7a6c953233b94406d02?postId=ed495077c36" style="display: block; position: absolute; margin: auto; max-width: 100%; box-sizing: border-box; transform: translateZ(0px); top: 0px; left: 0px; width: 700px; height: 100px;">UIApplicationDelegate에 정의된 메서드 시그니쳐와 다르기 때문에 컴파일러가 경고를 표시하지만 무시하셔도 됩니다.만약 새로운 버전의 앱을 릴리즈 할 계획을 가지고 계시다면 이 이슈를 꼭 확인하시길 바랍니다. 이 버그는 페이스북 로그인 등 다른 앱을 이용한 로그인이나, 카드 결제 후 주문서로 돌아오는 흐름에서 큰 문제를 일으킵니다. 이 글이 여러분들께 도움이 되길 바랍니다.Swift Korea 그룹에서 Xcode Release Notes에도 같은 내용이 있다는 것을 제보해주셨습니다. Swift Compiler 섹션의 Known Issues 4번째 항목입니다.#스타일쉐어 #개발팀 #개발자 #개발후기 #경험공유 #인사이트
조회수 2183

비전공자를 위한개발자 되기 5 스텝

안녕하세요. 언제 어디서나 함께하는 코딩 교실 엘리스입니다 :)아이디어만 좋다면 뭐든 실현해볼 수 있는 시대! 지금은 '프로그래밍'이라는 강력한 무기를 통해 원하는 세계를 실현할 수 있는 잠재적 가능성이 폭발적인 때입니다. 그리고 그 기회는 비단 '개발자'라는 특정 직업에 국한하지 않더라도 각계 분야에 펼쳐져 있는데요. 이미 마케터, 기획자, 디자이너, 콘텐츠 창작자, 금융업계 종사자, 지리학자, 연구원 등 다양한 분야의 많은 사람들이 프로그래밍을 통해 각자의 영역과 세계 곳곳을 새로운 곳으로 만들고 있습니다.높은 급여와 삶의 질을 보장하고 나의 꿈을 펼칠 수 있는 탁월한 수단인 프로그래밍.프로그래밍을 업으로 삼고 있는 사람들의 시작은 어땠을까요?이 글에서는 소프트웨어 엔지니어가 되고자 이제 막 마음먹은 분들을 위해 프로그래머가 되기 위한 다섯 가지 짚고 넘어가면 좋을 팁들을 알려드릴게요.STEP 1. 개발 친화적인 환경 찾아가기서당개 삼 년이면 풍월을 읊는다컴퓨터 공학 전공자와 비전공자가 가지게 되는 가장 큰 차이는 무엇일까요? 개발에 대한 이론 지식? 개발 능력?물론 모든 게 상대적인 것이겠지만 일반적으로 한 가지 큰 차이가 있다면 바로 '환경'이라고 할 수 있을 듯합니다. 내 주변에 개발과 관련된 자원이 얼마나 풍부한가 하는 점입니다.전공자가 개발을 시작하고자 마음을 먹으면 주위에서 좋은 리소스를 쉽게 찾을 수 있습니다. 한편 비전공자는 개발 공부를 시작하려고 할 때 레퍼런스로 삼을만한 좋은 예가 없으니 망망대해에 홀로 떠있는 기분이 들 수밖에 없겠죠! 그렇다고 해서 반드시 컴퓨터 공학 전공에서부터 다시 시작하거나 고액의 학원에 다닐 필요는 없습니다. 먼저 개발과 관련된 인적, 물적 자원이 풍부한 곳으로 적극적으로 다가가보세요. 작은 환경의 변화가 큰 변화의 시작점이 될 수 있습니다.엘리스가 추천하는 방법!온라인 커뮤니티 활동하기 : 코딩과 관련된 페이스북 그룹에 가입하여 많은 정보를 접하고 질문도 하면서 활동해보세요. 나와 비슷한 상황인 사람을 만나 서로 도움을 주고받을 수도 있고, 내 롤모델이 될만한 훌륭한 개발자를 만나 공부의 동력이 될지도요!개발 동아리, 스터디 등에 참여하기★ 엘리스 코딩 클래스 활용하기 : PC로도, 모바일 앱으로도 언제 어디서든 프로그래밍을 위한 환경에 접속하세요! 엘리스에 로그인하는 것만으로 공부하기 위한 모든 리소스를 얻을 수 있을 뿐만 아니라 과목별 채팅방을 통해서 함께 공부하고 있는 수강생들, 과목 튜터와의 활발한 대화에 참여할 수 있습니다. STEP 2. 강력한 동기와 조력자 만들기하늘은 스스로 돕는 자를 돕는다컴퓨터 공학 전공자라고 하면 모두 다 개발을 잘할까요? 적어도 아주 조금은 더 잘할까요? 대답은 NO!아무리 많은 이론을 배웠다고 해도 직접 개발을 하지 않는다면 아무런 소용이 없겠지요. 이해도가 다르기 때문에 배움의 속도는 조금 다를 수도 있겠지만 이런 차이보다는 개인의 학습 의지와 동기가 얼마나 분명하냐가 더 중요합니다.막연하게 '개발자'라는 너무 먼 목표만 보고 달리는 것보다는 보다 가까이에 있고 달성하기 쉬운 분명한 목표를 단계별로 설정해보세요. 그리고 '즐거움'을 느낄 수 있는 수단을 찾아 목표 달성을 위한 집중력을 높이세요. 동시에 내가 어려움에 처하거나 헤매고 있을 때 도와줄 조력자가 있다면 금상첨화!Photo by Mimi Thian on Unsplash엘리스가 추천하는 방법!동기 부여를 위한 작은 목표 설정 : 지식 습득 및 학습과 관련된 목표로 그룹 스터디 참여, 부족한 부분의 프로그래밍 강의 완강, 책 한 권 떼기 등이 있을 수 있고, 더 적극적인 형태의 개발 경험을 위해 공모전, 경진 대회 등 기간과 보상이 정해져 있는 대외 활동 참가 및 수상도 좋은 목표가 될 수 있을 거예요.★ 엘리스 코딩 튜터 활용하기 : 엘리스에는 학습을 도와주는 튜터가 있습니다. 엘리스 튜터는 답을 알려주는 사람이 아니라 답을 찾는 법을 알려주는 길잡이입니다. 공부하다가 막힐 때, 길을 잃은 것 같을 때 엘리스 튜터를 멘토로 삼아 보세요! 구독 및 트랙 이용 시 담당 튜터가 배정되어 개인 채팅방을 통해 1:1 튜터링을 받을 수 있고, 클래스 수강 시 단체 채팅방을 통해 언제든 질문할 수 있습니다.STEP 3. 원하는 개발 분야 탐색해보기  콩 심은 데 콩 나고 팥 심은 데 팥 난다개발에는 아주 숱~한 다양한 분야가 있습니다. 그리고 그 분야에 따라 특성도, 익혀야 하는 언어와 기술도 천차만별인데요. 아래 몇 개의 개발 분야와 사용 언어 및 기술에 대해서 적었으니 참고해보세요. 그리고 이보다 더 다양한 개발의 세계를 탐색해보면서 흥미가 가는 분야가 있다면 구체적으로 검색하고 공부를 시작할 계획을 세워보세요.Photo by Victoriano Izquierdo on Unsplash잘 모르겠다 or 코알못이다파이썬은 분야를 막론하고 많은 분야에서 사용되며 익히기에 쉬워 처음 코딩을 시작하는 입문자에게 가장 적합한 언어 중 하나입니다. 개발 언어부터 접해보고 싶다면 파이썬 언어 학습에서 시작해보세요!웹 개발 '콩 심은 데 콩 나고~'라는 속담을 인용했지만, 사실 다양한 개발 영역의 많은 지식들이 서로 겹치는 부분도 있고, 어느 한 분야를 잘할 수 있을 때 다른 분야로 전향하거나 옮겨가는 일은 보다 수월할 수 있습니다. 개발의 시작을 보다 쉽게 하고 싶다면 웹 개발부터 접근해보세요. 공부할 수 있는 자원이 풍부하고 추후 다른 개발 분야로의 전향도 가능하기 때문이에요.프론트엔드프론트엔드 개발은 주로 웹 환경에서 사용자와 맞닿는 가시적인 부분을 개발하는 영역입니다. 사용자가 코드를 작성하지 않고도 컴퓨터에게 명령을 내리는 등의 의사소통을 그래픽적으로 쉽게 할 수 있도록 가시적으로 만들어주는 것이 바로 프론트엔드 개발자의 역할이라고 할 수 있는데요. 예를 들어 엘리스에 로그인하고 싶을 때 '로그인 버튼을 클릭'하여 쉽게 로그인할 수 있는 인터페이스도 프론트엔드에 해당합니다. * 익혀야 하는 기본기 : HTML, CSS, JavaScript* 좀 더 나아가서 : JavaScript의 프레임 워크인 React.js 또는 Vue.js 또는 Angular.js 백엔드/서버백엔드 개발은 웹 환경에서 보통 사용자에게는 보이지 않는 서버(컴퓨터) 단의 개발을 의미하며, 사용자가 웹 상에서 활동함으로 인해 쌓이는 데이터가 모이는 DB(Data Base)를 다루는 영역을 개발합니다.* 익혀야 하는 기본기데이터베이스에 대한 지식 : MariaDB, PostgreSQL, MongoDB 등. 서버 쪽의 언어- 금융, 제약 등 전통적인 대기업 : Java의 프레임 워크인 Spring을 많이 사용- 과거 많이 쓰이던 기술 : Php(학습 속도와 개발 속도가 빠르며 무료!)를 많이 사용- 요즘 떠오르는 기술 : Python 기반 프레임 워크인 Django 또는 Flask. JavaScript의 프레임 워크인 Node.js* 좀 더 나아가서 : 클라우드 컴퓨팅 기술 Amazon AWS 또는 Azure에 대한 지식데이터 사이언스 - 데이터 분석가21세기에 가장 각광받는 직업 중 하나로 떠오른 '데이터 사이언티스트'에 대해서 모두 다 한 번쯤은 들어보셨을 거예요. 데이터 사이언스 분야에도 아주 복잡하고 다양한 영역들이 존재하는데요. 통상 데이터 사이언스라고 하면 수학 및 통계에 대한 지식, 컴퓨터 공학에 대한 지식, 인공지능 및 머신러닝과 관련된 기술을 사용하게 됩니다. 너무 많아 보이나요? 아래에는 데이터 사이언스의 많은 영역 중에서도 '데이터 분석가'로서 꼭 알아야 하는 내용을 적었습니다.* 익혀야 하는 기본기수학적 지식 : 통계, 선형대수학분석을 위한 언어 : Python, R* 좀 더 나아가서 : 머신러닝 기술임베디드 개발계산기, 에어컨, 자동차 등의 기계가 일정 기능을 컴퓨터처럼 수행할 수 있도록 기계 내부의 하드웨어 시스템을 구축하는 것이 임베디드 개발입니다. 사물 인터넷(IoT, Internet of Things)이나 하드웨어 부품과 관련된 분야에 관심이 간다면 임베디드 개발에 대해서 좀 더 알아보세요!* 익혀야 하는 기본기임베디드 개발 언어- 가장 많이 사용하는 언어 : C언어 - 국내 전통적인 대기업 : Java- 수요가 많은 언어 : Python (임베디드 분야에서도 빠지지 않고 자주 사용하는 언어! 국내 채용 사이트에서 임베디드 관련 개발 스택으로 많이 요구.)* 좀 더 나아가서 : 무선 통신 기술에 대한 지식*(공통) 개발자라면 익히고 있어야 할 기본기 : Git을 사용한 버전 관리 방법엘리스가 추천하는 실습 기반 과목HTML/CSS | JavaScript | 모바일 웹 코딩Git과 Git 버전 관리 (6월 오픈 예정)Python 기초 I | Python 기초 IIC 언어 | C++Java 기초 및 심화인공지능/머신러닝 기초 | 프로그래밍 수학데이터 분석 | Numpy, Pandas | 크롤링 | Kaggle 문제R 기초 |  R 패키지 | R 데이터 분석STEP 4. 실습, 프로젝트 기반으로 공부하고 개발 경험 쌓기구슬이 서 말이어도 꿰어야 보배다책을 사고 인강을 결제해도 직접 만들어보면서 익히지 않으면 절대 내 것이 될 수 없는 것이 또 개발!처음 언어를 익히는 단계에서부터 실습 기반으로 직접 코딩하고 그 결과를 확인해보면서 학습하는 것이 중요해요! 필요한 공부를 실습 단위로 쪼개어 직접 구현해보면서 익히고, 좀 더 나아가서는 프로젝트 단위로 구현하면서 실전 기술을 습득해보세요. 또한 실무에서는 혼자 개발하는 것이 아니라 뭐든 '협업'해야 하기 때문에 혼자 하는 프로젝트 외에도 여러 사람들과 함께하는 그룹 프로젝트의 경험이 큰 도움이 될 거예요. 자기소개서, 포트폴리오, 면접 시에도 어떤 프로젝트에서 내가 맡은 부분은 어느 부분이었고 어떻게 주도적으로 이끌었는지가 관건이 될 수 있습니다.엘리스가 추천하는 방법!★ 온라인 코딩 실습으로 기본기 다지기 : 엘리스는 별도의 코딩 환경 세팅 없이 온라인에서 바로 코딩 문제를 풀고 내가 짠 코드의 결과를 확인할 수 있어서 실습 기반으로 학습하기에 탁월한 플랫폼입니다. :) KAIST, SKT, 삼성 SDS 등에서도 활용하는 검증된 플랫폼에서 코딩 실습으로 기본기를 다지세요!프로젝트 단위로 혼자서 만들어보기 : 프로그래밍 언어의 기본에 익숙해졌다면, 직접 A to Z를 구현하는 작은 프로젝트를 통해 실제 필요한 기술이 뭔지 파악해가며 실전 기술을 익혀보세요. 그룹 프로젝트에 참여해서 협업 경험을 통해 익히기 : 취업을 위해서 중요한 것 중 하나인 '협업'능력! 그룹 프로젝트에 참여하여 비단 개발 실력뿐만 아니라 실무에 필요한 다양한 역량 또한 길러보세요.STEP 5. 포트폴리오, 시험 준비하고 개발 직군에 지원하기시작이 반, 그 이상이다!아시겠지만 개발자가 되면 끝인 그런 일은 없겠죠. (어떤 직무에서도 마찬가지일 거예요.) 끊임없는 공부, 새로운 기술 연마, 리팩토링, 문서화, 코딩 공부 코딩 공부!그러니 완벽에서 시작해야 한다는 생각은 버리고 지금까지 최선을 다해온 결과물을 가지고서 개발 직군에 지원하세요. 실제 개발자로 일하게 되면 그 속에서 배우고 성장할 수 있는 자원이 훨씬 더 많아집니다!'자리가 사람을 만든다'라는 말이 괜한 말이 아니니, 더 큰 성장과 가능성이 있는 곳으로 가기 위한 준비와 지원을 주저 없이 해보시길 바라요!Photo by Green Chameleon on Unsplash엘리스가 추천하는 방법!나를 잘 보여줄 포트폴리오 만들기 : (사용한 언어 / 프레임 워크 / 앞의 것을 적용하여 프로젝트에서 내가 한 역할) 별로 정리해두고 내가 커밋한 코드와 함께 보여주기.   블로그 쓰기 : 거창한 것이 아니어도 좋으니 공부하면서 느꼈던 것, 새로 알게 된 지식들, 프로젝트하면서 고민했던 것들을 블로그로 정리해보세요. 내가 구현한 것들을 이미지를 통해서 가시적으로 보여줄 수 있다면 금상첨화!★ 엘리스에서 알고리즘 시험 준비하기 : 이미 많은 수강생 분들이 엘리스 알고리즘 과목을 통해서 코드를 발전시키고 알고리즘 시험 및 취업에 성공하고 있습니다. :) 대기업 입사를 준비하시는 분이라면 엘리스 알고리즘 과목들을 꼭 수강해보세요.이다음의 6번째 스텝은 무엇이 될까요? 아마도 1~5 스텝을 계속 반복해나가면서 익숙해지고, 다른 역할로 각각의 스텝에 참여하게 되는 일이 아닐까요.엘리스는 누구나 프로그래밍을 통해 원하는 일을 할 수 있도록 좋은 강의 콘텐츠와 서비스, 플랫폼으로 여러분의 다섯 스텝에 함께하고자 합니다. :) 막막한 초심자 분들에게 앞으로의 방향성을 그려보는 데에 조금이라도 도움이 되길 바라며 글을 발행합니다.그럼 엘리스에서 만나요! >> 엘리스 아카데미 바로가기* 이밖에 조언, 첨언, 질문 등을 댓글로 남겨주시면 이 글의 독자분들에게 큰 도움이 됩니다.
조회수 2325

JPassKit 적용중 오류 발생

서비스에서 ios wallet을 제공하려고 하니, 예전과는 다르게 서버단 통신을 통해 인증받는 절차가 추가로 생겼단다. 다만, 애플에서 제공하는 서버쪽 데모를 보면 ruby로 만들어져있다. 왜 하필 루비인가? swift도 아니고… 여튼 그걸 java로 porting하려니 이미 만들어 놓은 것이 있을 것 같아서 구글링했더니, jpasskit이 그나마 제일 fork도 많이 되고, 사용도 하는 것 같아서 lib dependency를 추가했다.<!-- PassKit --> de.brendamour jpasskit 0.0.8 개발을 완료했는데, Test Case에서 오류가 나타나기 시작했다.com.fasterxml.jackson.databind.JsonMappingException: Can not resolve PropertyFilter with id 'validateFilter'; no FilterProvider configured난 jackson filter를 바꾼 적이 없는데 왜 에러가 나는 것인가? 처음에는 jpasskit issue를 보고 jackson lib의 version 호환성 문제가 있는 것 같아서 아래처럼 dependency처리를 했다.<!-- PassKit --> de.brendamour jpasskit 0.0.8 com.fasterxml.jackson.core jackson-core 위의 오류가 해결된 것처럼 보여서 SNAPSHOT version을 만들었는데, 됐다안됐다한다. 예를 들어서 local profile에서 하면 되고, develop profile에서 하면 오류나고… 혹은 전체 junit을 모두 돌리면 에러가 발생하는데, 에러나는 class만 테스트 돌리면 성공하고 ㅠ.ㅠ그래서 해당 소스를 파보다가 문제점을 발견하였다.우리의 프로젝트에서는 pojo type인 jackson object mapper를 bean으로 등록해서 사용하고 있다. bean으로 등록하면 몇 가지 장점이 있는데, 자세한 설명은 이 글의 범위를 벗어나기 때문에 생략한다.@Primary @Bean public ObjectMapper objectMapper() { ObjectMapper objectMapper = new CustomObjectMapper(); initializeObjectMapper(objectMapper); return objectMapper; }그래서 Object Mapper는 singleton으로 재사용하고 있는데, jpasskit은 Object Mapper를 변조시키고 있다.public final class PKFileBasedSigningUtil extends PKAbstractSIgningUtil { private static final String FILE_SEPARATOR_UNIX = "/"; private static final String MANIFEST_JSON_FILE_NAME = "manifest.json"; private static final String PASS_JSON_FILE_NAME = "pass.json"; private ObjectWriter objectWriter; @Inject public PKFileBasedSigningUtil(ObjectMapper objectMapper) { this.addBCProvider(); this.objectWriter = this.configureObjectMapper(objectMapper); } ...protected ObjectWriter configureObjectMapper(ObjectMapper jsonObjectMapper) { jsonObjectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); jsonObjectMapper.setDateFormat(new ISO8601DateFormat()); SimpleFilterProvider filters = new SimpleFilterProvider(); filters.addFilter("validateFilter", SimpleBeanPropertyFilter.serializeAllExcept(new String[]{"valid", "validationErrors"})); filters.addFilter("pkPassFilter", SimpleBeanPropertyFilter.serializeAllExcept(new String[]{"valid", "validationErrors", "foregroundColorAsObject", "backgroundColorAsObject", "labelColorAsObject", "passThatWasSet"})); filters.addFilter("barcodeFilter", SimpleBeanPropertyFilter.serializeAllExcept(new String[]{"valid", "validationErrors", "messageEncodingAsString"})); filters.addFilter("charsetFilter", SimpleBeanPropertyFilter.filterOutAllExcept(new String[]{"name"})); jsonObjectMapper.setSerializationInclusion(Include.NON_NULL); jsonObjectMapper.addMixIn(Object.class, PKAbstractSIgningUtil.ValidateFilterMixIn.class); jsonObjectMapper.addMixIn(PKPass.class, PKAbstractSIgningUtil.PkPassFilterMixIn.class); jsonObjectMapper.addMixIn(PKBarcode.class, PKAbstractSIgningUtil.BarcodeFilterMixIn.class); jsonObjectMapper.addMixIn(Charset.class, PKAbstractSIgningUtil.CharsetFilterMixIn.class); return jsonObjectMapper.writer(filters); }확실해졌다. 위에서 상황마다 오류가 간헐적으로 발생하는 이유는 이와 같은 것이었다. jpasskit이 실행되기 전까지는 정상적으로 동작한다. 그러다가 jpasskit을 한 번 거치면 이미 등록되어 있는 object mapper bean의 설정이 바뀌게 된다. 즉, 우리가 설정한 custom configuration들이 무시되어버려서, 전혀 엉뚱한 곳에서 에러를 일으킨다.jpasskit에서 사용하는 object mapper는 특별한 설정이 필요한 것은 아니라, bean을 사용하지 않고 기본 object mapper를 생성해서 넘기는 식으로 수정하였다.private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); ... private byte[] createPKPassBinaries(PKPass pass, PKSigningInformation pkSigningInformation, InputStream thumbnail, InputStream thumbnail2x) throws Exception { return new PKFileBasedSigningUtil(OBJECT_MAPPER).createSignedAndZippedPkPassArchive(pass, createPKPassTemplate(thumbnail, thumbnail2x), pkSigningInformation); }All Clear.해당 내용은 jpasskit에 issue reporting하여 신규 release(0.0.9)가 예정중이다.#데일리 #데일리호텔 #기술스택 #스택도입 #후기 #일지 #JPasskit

기업문화 엿볼 때, 더팀스

로그인

/