스토리 홈

인터뷰

피드

뉴스

조회수 582

HBase상 트랜잭션 라이브러리 Haeinsa를 소개합니다

비트윈에서는 서비스 초기부터 HBase를 주요 데이터베이스로 사용하였습니다. HBase에서도 일반적인 다른 NoSQL처럼 트랜잭션을 제공하지 않습니다. HBase, Cassandra와 MongoDB는 하나의 행 혹은 하나의 Document에 대한 원자적 연산만 제공합니다. 하지만 여러 행에 대한 연산들을 원자적으로 실행할 수 있게 해주는 추상화된 트랜잭션 기능이 없다면 보통의 서비스 개발에 어려움을 겪게 됩니다. 비트윈 개발팀은 이런 문제를 해결하기 위해 노력했으며, 결국 HBase에서 트랜잭션을 제공해주는 라이브러리인 Haeinsa를 구현하여 실제 서비스에 적용하여 성공적으로 운영하고 있습니다. VCNC에서는 Haeinsa를 오픈소스로 공개하고 이번 글에서 이를 소개하고자 합니다.Haeinsa란 무엇인가?¶Haeinsa는 Percolator에서 영감을 받아 만들어진 트랜잭션 라이브러리입니다. HAcid, HBaseSI 등 HBase상에서 구현된 트랜잭션 프로젝트는 몇 개 있었지만, 성능상 큰 문제가 있었습니다. 실제로 서비스에 적용할 수 없었기 때문에 Haeinsa를 구현하게 되었습니다. Haeinsa를 이용하면 다음과 같은 코드를 통해 여러 행에 대한 트랜잭션을 쉽게 사용할 수 있습니다. 아래 예시에는 Put연산만 나와 있지만, 해인사는 Put외에도 Get, Delete, Scan 등 HBase에서 제공하는 일반적인 연산들을 모두 제공합니다.HaeinsaTransaction tx = tm.begin(); HaeinsaPut put1 = new HaeinsaPut(rowKey1);put1.add(family, qualifier, value1);table.put(tx, put1); HaeinsaPut put2 = new HaeinsaPut(rowKey2);put2.add(family, qualifier, value2);table.put(tx, put2); tx.commit();Haeinsa의 특징¶Haeinsa의 특징을 간략하게 정리하면 다음과 같습니다. 좀 더 자세한 사항들은 Haeinsa 위키를 참고해 주시기 바랍니다.ACID: Multi-Row, Multi-Table에 대해 ACID 속성을 모두 만족하는 트랜잭션을 제공합니다.Linear Scalability: 트래픽이 늘어나더라도 HBase 노드들만 늘려주면 처리량을 늘릴 수 있습니다.Serializability: Snapshot Isolation보다 강력한 Isolation Level인 Serializability를 제공합니다.Low Overhead: NoSQL상에서의 트랜잭션을 위한 다른 프로젝트에 비해 오버헤드가 적습니다.Fault Tolerant: 서버나 클라이언트가 갑자기 죽더라도 트렌젝션의 무결성에는 아무 영향을 미치지 않습니다.Easy Migration: Haeinsa는 HBase를 전혀 건드리지 않고 클라이언트 라이브러리만 이용하여 트랜잭션을 구현합니다. 각 테이블에 Haeinsa 내부적으로 사용하는 Lock Column Family만 추가해주면 기존에 사용하던 HBase 클러스터에도 Haeinsa를 쉽게 적용할 수 있습니다.Used in practice: 비트윈에서는 Haeinsa를 이용하여 하루에 3억 건 이상의 트랜잭션을 처리하고 있습니다.Haeinsa는 오픈소스입니다. 고칠 점이 있다면 언제든지 GitHub에 리포지터리에서 개선에 참여하실 수 있습니다.Haeinsa의 성능¶Haeinsa는 같은 수의 연산을 처리하는 트랜잭션이라도 소수의 Row에 연산이 여러 번 일어나는 경우가 성능상 유리합니다. 다음 몇 가지 성능 테스트 그래프를 통해 Haeinsa의 성능에 대해 알아보겠습니다.아래 그래프는 3개의 Row에 총 6개의 Write, 3개의 Read연산을 수행한 트랜잭션의 테스트 결과입니다. 두 개의 Row에 3Write, 1Read 연산을 하고, 한 개의 Row에 1Read 연산을 한 것으로, 비트윈에서 가장 많이 일어나는 요청인 메시지 전송에 대해 시뮬레이션한 것입니다. 실제 서비스에서 가장 많이 일어나는 종류의 트랜잭션이라고 생각할 수 있습니다. 그런데 그냥 HBase를 사용하는 것보다 Haeinsa를 이용하는 것이 더 오히려 좋은 성능을 내는 것을 알 수 있습니다. 이는 Haeinsa에서는 커밋 시에만 모든 변경사항을 묶어서 한 번에 반영하기 때문에, 매번 RPC가 일어나는 일반 HBase보다 더 좋은 성능을 내는 것입니다.HBase 클러스터가 커질수록 트랜잭션 처리량이 늘어납니다. HBase와 마찬가지입니다.HBase 클러스터의 크기에 따른 응답시간 입니다. HBase와 다르지 않습니다..아래 그래프는 2개의 Row에 각각 한 개의 Write, 나머지 한 개의 Row에는 한 개의 Read 연산을 하는 트랜잭션에 대해 테스트한 것입니다. 각 Row에 하나의 연산만이 일어나기 때문에 최악의 경우라고 할 수 있습니다. 처리량과 응답시간 모두 그냥 HBase를 사용하는 것보다 2배에서 3배 정도 좋지 않은 것을 알 수 있습니다. 하지만 이 수치는 DynamoDB 상의 트랜잭션과 같은 다른 트랜잭션 라이브러리와 비교한다면 상당히 좋은 수준입니다.HBase보다 처리량이 떨어지긴 하지만, 클러스터가 커질수록 처리량이 늘어납니다.HBase보다 응답시간이 크긴 하지만 클러스터 크기에 따른 변화가 HBase와 크게 다르지 않습니다.저희는 언제나 타다 및 비트윈 서비스를 함께 만들며 기술적인 문제를 함께 풀어나갈 능력있는 개발자를 모시고 있습니다. 언제든 부담없이 jobs@vcnc.co.kr로 이메일을 주시기 바랍니다!
조회수 1111

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

요즘은 데이터 분석이 스타트업, 대기업 가릴 것 없이 유행입니다. 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 을 이용한 데이터 분석 시스템 만들기↩
조회수 2028

당신이 고민해야 할 성능 분석 요소

IT 서비스는 더욱 복잡해지고 어플리케이션과 인프라의 경계도 클라우드 환경과 함께 허물어지고 있습니다. 많은 기업들이 가상화를 넘어 컨테이너로 가고 있으며 서버리스도 더이상 낮설지 않습니다. 인프라의 변화와 함께 아키텍처의 변화도 다양하게 만들어져 가고 있습니다. 복잡성이 아무리 높아져도 우리는 서비스의 성능을 보장해야 합니다. 서비스의 성능을 보장하기 위해 우리가 체크해야 할 중요 요소들을 알아보려고 합니다. 1. 인프라스트럭처와 클라우드서비스의 성능은 코드 밖에서도 만들어집니다. 그중에서도 인프라스트럭처는 매우 중요한 요소입니다. 국내에서 인프라스트럭쳐 분야는 클라우드로 전환하는 과도기적인 상황에 있습니다. SMB 시장에서 클라우드는 익숙한 환경이지만 국내 엔터프라이즈 기업의 클라우드 도입 비율은 20%가 되지 않습니다. 특히 클라우드를 도입하려는 엔터프라이즈 기업들은 데이터 센터, 퍼블릭 클라우드, 프라이빗 클라우드를 모두 사용하는 상황으로 넘어가면서 클라우드에 대한 모니터링 체계를 구성하는데 많은 어려움을 겪고 있습니다. 특히 기존의 자원 사용량을 설계하고 운영하던 방식에서 스케일의 변화를 통해 서비스의 성능을 실시간으로 조절하는 클라우드 서비스 운영 방법은 조직의 구조 변화를 동반하기 때문에 더욱 어려운 작업이기도 합니다. 이렇듯 클라우드의 전환은 최근 웹 서비스의 성능에 많은 영향을 미치고 있으며 데이터독이나 뉴렐릭 그리고 와탭 같은 성능 분석 서비스들은 클라우드 기반의 인프라 모니터링 기능들을 강화하고 있습니다. 2. 데이터베이스어플리케이션 성능 이슈의 80% 이상이 데이터베이스 레이어에서 발생합니다. 대부분의 엔터프라이즈 기업들은 자사의 어플리케이션을 성능 분석을 위해 DBA 포지션을 마련하거나 필요에 의해 컨설팅을 받고 있지만 아쉽게도 스타트업은 DBA포지션을 마련하는 경우가 거의 없습니다. 웹 서비스의 규모가 커지기 시작하면 데이터베이스로 인한 지연 장애가 매우 심각해 지기 시작합니다. 레거시로 인한 이슈까지 추가되면 서비스의 성능은 지속적으로 낮아지게 되므로 데이터베이스는 꾸준히 관리해야 하는 요소입니다.데이터베이스의 비중이 높다보니 어플리케이션 분석 서비스 중에서도 데이터베이스만 집중적으로 분석하는 도구들이 있습니다. 국내에서는 엑셈과 티맥스에서 데이터베이스 분석 솔루션을 제공하고 있습니다.  3. 오픈 소스와 써드파티 소프트웨어최근 두가지 형태의 트렌드가 서비스 성능에 영향을 주고 있습니다. 하나는 오픈 소스이고 다른 하나는 써드 파티 소프트웨어 입니다. 안정화 된 오픈 소스를 사용하더라도 설정 이슈 또는 사용 환경 이슈로 성능에 영향을 주는 상황이 많이 발생합니다. 위젯, 광고플랫폼, 플러그인등의 써드파티 또한 웹 서비스의 성능에 영향을 주는 요소입니다. 최근 써드 파티의 사용은 점점 늘어나는 추세로 인해 장애 발생에 대한 위험도는 더욱 높아가고 있습니다. 특히 써드 파티는 시간이 흐르면서 성능에 조금씩 부하를 누적시키기도 하므로 충분히 주의를 기울여야 합니다. 이런 환경에서도 서비스의 성능을 유지하기 위한 방법으로 통계 기반의 메소드 분석 기법 모니터링의 중요한 요소가 되어 가고 있습니다. 와탭의 Java 모니터링이 메소드 분석 서비스를 제공하고 있습니다. 4. 모바일구글 이 운영하는 더블클릭(https://www.doubleclickbygoogle.com/articles/mobile-speed-matters/)에 따르면 북미에서 3G에서의 모바일 페이지 로딩까지 소요되는 시간은 평균 19초입니다. 한국은 이미 4G를 넘어가고 있기도 하고 모바일 기기의 성능도 매우 높아서 북미와 상황이 다르지만 모바일 기반의 웹 서비스 성능을 분석할 수 있는 방안의 필요성은 높아져 가고 있습니다. 이와 함께 다양한 환경을 지원하는 end-to-end 모니터링의 중요성이 점점 대두되고 있는 상황입니다.  5. 컨테이너최근 인프라스트럭처의 새로운 흐름은 컨테이너 입니다. 한국은 리눅스 기반의 서비스 구축 시스템이 잘 발달한 덕분에 클라우드 도입이 다른 나라보다 늦은 편입니다. 하지만 최근 국내에 컨테이너 기반의 인프라스트럭처 도입 기업들이 많아지고 있습니다. 우리나라는 가상화를 건너뛰고 컨테이너부터 활성화 될수도 있을 거라 생각됩니다. 컨테이너 환경은 가상화보다 더 많은 인프라를 더 유동적으로 사용하게 되므로 기존의 규모를 뛰어 넘는 관리 체계를 만들어 나가야 합니다. 데이터독과 뉴렐릭 같은 SaaS 기반의 모니터링 서비스들은 이미 컨테이너의 대한 지원을 하고 있으며 와탭 또한 단순 지원을 넘어 컨테이너 전용 서비스를 준비중에 있습니다. 6. 마이크로 서비스많은 기업들이 클라우드와 함께 Micro Service Arichtecture를 도입하고 있기 때문에 독립적인 어플리케이션을 기반으로 하는 서비스 구조는 계속 발전해 나갈 것입니다. 마이크로 서비스와 클라우드의 조합은 커져가는 서비스의 규모를 독립적인 작은 단위로 나눌 수 있어서 매력적이긴 하지만 과거와 다른 운영 조직과 프로세스를 만들어야 하는 숙제를 만들었습니다. 예를 들면 기존에는 하나의 임계치를 사용하여 서비스의 위험도를 관리했다면 이젠 독립적으로 동작하는 서비스들의 임계치를 각각 어떻게 설정하고 관리할 것인지 고민해야 합니다. 독립된 마이크로 서비스의 성능 이슈가 전체 서비스 성능 이슈로 확대되지 않더라도 작게 발생하는 이슈들을 관리하지 못한다면 지속적으로 발전해야 하는 서비스의 미래도 흔들리게 될 것입니다. 7. 서버사이드 코드정상적인 상황이라면 서버사이드 코드에서 발생되는 지연시간은 찰나에 가깝지만 장애 상황에서의 지연은 서버사이드에서 발생하는 경우가 많습니다. 특히 방어가 되어 있지 않은 코드들은 물리적 요소의 작은 변화에 대처하지 못하고 웹 서비스 전체에 영향을 미치게 됩니다. 스타트업의 경우 개발팀이 운영을 함께 맡고 있는 경우가 많기 때문에 서버사이드의 코드를 직접 분석하곤 합니다. 하지만 서비스의 성능이 느려지는 상황 자체를 파악하지 못하는 경우가 많습니다. 서버 사이드에서 평균 응답시간을 체크하는 경우 10초 평균 응답시간이 0.5초를 넘는 경우는 거의 없습니다. 하지만 0.5초의 평균 응답시간을 같는 서비스라 할지라도 하루 동안 10초이상 걸린 고객의 숫자는 규모에 따라 1,000명이 넘을 수도 있습니다. 서비스에 규모가 있다면 꼭 APM을 사용해야 합니다.8. 네트워크 지연네트워크의 지연으로 인한 고객 불만은 예상외로 많이 발생합니다. 인프라스트럭처 이슈로 볼 수도 있겠지만 서비스를 운영한다면 항상 체크하고 있어야 하는 요소입니다. 해당 이슈를 확인 하려면 웹서비스 모니터링을 사용하시면 됩니다. 웹서비스 모니터링을 통해 네트웍상태를 포함한 서비스의 응답시간을 체크해 볼수 있습니다. 와탭의 경우 내부적으로 웹서비스 모니터링을 개발하여 사용하고 있지만 아직 서비스 하고 있지는 않습니다.  9. 자원 사용률자원 사용률은 최근 새로 떠오르는 이슈입니다. 이전에는 인프라스트럭쳐가 고정값이였기 때문에 자원 사용률이 모자라는 경우 서비스 성능을 포기하고 초과되는 고객의 요청을 앞단에서 버리거나 대기시키는 기법들을 사용해왔습니다. 클라우드 환경에서는 자원 사용량의 임계치가 넘어가면 자동으로 스케일을 조정하는 환경이 마련되면서 성능을 유지하는 것이 가능합니다.  클라우드 환경에서 과부하 상태에 접근하면 자동으로 인프라의 규모가 확장되고 과부하 상태는 정상으로 돌아갑니다. 이렇게 환경이 바뀌면서 자원 사용률의 중요 이슈가 성능에서 비용으로 전환되고 있습니다. 부하에 따른 스케일링 정책을 어떻게 정하는지에 따라서 성능과 비용 모두가 영향을 받기 때문에 Auto Scale에 대한 모니터닝이 관심을 받고 있습니다.  마무리웹 서비스의 성능에 영향을 주는 요소는 정말 많습니다. 와탭랩스 IT 기업의 어플리케이션을 모니터링 하기 때문에 기업의 IT 어플리케이션 성능 문제에 대해 항상 고민하고 있습니다. 해당 내용은 매달 또는 분기별로 트렌드를 반영하여 업데이트하고 할 생각입니다. 많은 분들에게 도움이 되었으면 좋겠습니다. #와탭랩스 #개발자 #개발팀 #인사이트 #경험공유 #일지
조회수 3883

풀스택 개발자, 그것은 환상..

풀스택 개발자라는 용어가 가끔 등장한다. 죄송하지만, 한국에서는 이 용어가 정말 잘못 이해된 상태로 사용되고 있다. 처음에 만들어진 의미와 뜻이 한국에 들어오면서 변한 것을 보는 것이 이번만도 아니다.언제나처럼, 이 '단어'가 의미하는 뜻은 '귤이 회수를 건너면서 언제나 탱자가 되는' 한국적인 환경에서는 매우 이상하게 와전된 의미로 사용되고 있다. 특히나 비개발자들인 경영진들이 그러하고, 개발자들도 가끔 잘못된 의미로 사용한다.와전된 의미의 '풀스택 개발자(Full Stack Developer)'는 프런트엔드와 서버 엔드를 넘나드는 모든 것을 다 아는 전지전능한 개발자인 것처럼 쓰인다. 죄송하지만, 풀스택 개발자의 의미는 프런트-엔드부터 서버-엔드까지 모든 것을 다룰 줄 아는 개발자를 의미하는 것이 아니다.이 '용어'가 쓰이는 분야를 조금은 국한시켜야 할 필요가 있다.그것은 '웹'환경의 프론트 영역으로 국한시키는 것이 매우 현명할 것이다. 다음의 링크를 참조하기를 권한다.http://www.sitepoint.com/full-stack-developer/위의 사이트에 있는 이미지와 단어를 차용한다. 아래의 그림을 살펴보라.[이미지출처 : http://www.sitepoint.com/full-stack-developer/ ]OS부터 Database, WebServer, Server Side Code, Browser, Client Side Code를 아우르는 능력을 가진 사람을 Full-Stack Developer라고 부를 수 있다.좀 더 쉽게 이야기하자면, 'Web'환경은 서버사이드 코드와 클라이언트 사이드 코드를 모두 이해하고 작성되어야 한다. 브라우저( 특히나 변덕스러운 호환성 문제들.. )의 스크립트 환경이 효과적으로 가동되기 위해서는 웹서버의 API를 적절하게 디자인하고 구현된 상태에서 동작되어야 하며, 대부분의 코드들은 직접 Database에 영향을 주는 경우가 많다. 더군다나, 소프트웨어 개발을 하려면 형상관리부터 배포 처리를 위한 기술도 할 줄 알아야 한다.맞다. 'Web'개발 환경에서는 Full-Stack Developer가 되지 않으면 제대로 된 개발이 어렵다. 그래서, '웹'에서는 풀스택 개발자를 지향해야 하고, 매우 당연하게 해당 스킬들을 익숙하게 다루어야 한다.풀스택 개발자는 Web의 개발환경에서는 어쩔 수 없이 매우 당연한 기술적인 한계이고 해야 할 업무를 위해서는 필연적인 형태 인 것이다.이렇게 '웹 환경에서의 풀스택 개발자'는 한국에도 많이 존재한다. 상당수의 PHP개발자 분들이 그러한 '풀스택 개발자'인 경우가 많다.그렇지만, 이 풀스택 개발자의 용어는 '개발'이나 '소프트웨어'를 잘 모르는 경영자의 머릿속으로 잘못 들어가서 마치, iOS나 Android APP도 개발하고 Rest API 디자인이나 구현도 하면서, AWS의 분산 환경에 대한 이해나 개발도 모두 가능한 '전지전능한 개발자'와 같은 의미로 잘못 사용되기도 한다.( 더군다나, 디자인능력이 극도로 필요한 자바스크립트나 능동형 웹-UI를 만들어 내는 능력은 전혀 다른 능력이다 )원래 의미의 '풀스택 개발자'는 '혼자서 웹서비스 하나를 만들 수 있는 개발자'라는 좁은 의미로는 맞다. 하지만, 이를 과도하게 해석하거나 아전인수격으로 해석하는 것은 매우 곤란하다. 그것은 바로 한국적인 특수한 환경 때문에 그러하다.슬프지만, 한국적인 의미의 풀스택 개발자가 존재하기는 하고 있다.프로그래머가 기획도 하면서, 서버 구입부터 설치까지 다진 행하고, DB도 일부 다룰 줄 알면서, 웹이나 클라이언트 프로그래밍의 일부도 할 줄 아는 매우 한국적인 풀스택 개발자가 존재하기는 한다. ( 근데, 그런 개발자들을 풀스택 개발자라고 표현하지 않는다. 거의 기업의 잡부(?)처럼 부려지는 경우다. )노가다 - dokata, 土方 -'막일'을 하는 노가다를 하는 잡부가 한국형 풀스택 개발자라고 표현하겠다.하지만, 그런 테크트리로 형성된 한국형 풀스택 개발자들의 실력은 매우 볼품이 없는 경우가 대부분이다. 필자가 공공 SI현장에서 만난 수많은 한국형 풀스택 개발자들이 그러했다.그들은 컴파일러가 만들어내는 에러 메시지에 대한 이해는 없지만, 10년 넘게 업무를 배운 경험과 대충 Linux나 Windows Server의 기본적인 경험과 온통 스파게티 식으로 구성되어진 소스로 만들어진 더 이상 시장이 커지지 않는 한계가 다다른 시장에서 소프트웨어 개발을 하고 있다.태생적으로 '잡부'가 될 수밖에 없는 작업현장에서 진정한 의미의 풀스택 개발자는 거의 형성되기 어렵다. 이런 한국형 풀스택 개발자들은 실제 하나하나의 스킬들을 확인하거나 체크해본다면 거의 대부분 매우 부족하거나, 특정 기능에만 적합한 일반적으로 쓸모없는 기술들이 대부분일 가능성이 크다고 단언하겠다.이런 경향은 게임업계도 비슷하다. 한국형 풀스택 게임 개발자는 게임 기획부터 스프라이트의 2D부터, 포토샵이나 일러스트레이트도 다룰 줄 알며, 3D Max로 3D도 만들고, Auto-Cad로 도면 데이터도 다루고, DirectX에 Unity도 다루며, 서버나 iOS의 앱까지 만들 줄 안다고 하지만, 정작 그 어느 하나도 제대로 못 다루는 경우가 태반이다.물론, 전부 다루는 사람이 없는 것은 아니다. 있기는 있지만... 그분들 굉장히 유명하거나 특정 기술하나 가 대가의 수준이기 때문에 자신이 가진 다른 기술들을 포함해서 자신을 '풀스택 개발자'라고 포장하지 않는다.하지만, 한국에서 유독 '개발자 구인 광고'를 보면 '풀스택 개발자'를 찾는 곳이 많은 이유는 무엇 때문일까?그것은, 무지한 경영진이나 무지한 비즈니스 모델, 무지한 리소스 활용이 난무하는 헬게이트의 주인들이나 그런 단어들을 주로 사용한다고 보면 된다.100% 단언컨대 한 사람의 개발자가 완벽한 풀스택 개발자라고 하더라도, 요구사항이 발생하고 유지보수업무가 존재하는 업무를 하드웨어적인 서버 관리부터 서버 API, 앱 프로그래밍, 웹 프로그래밍을 하기 위한 스킬은 알 수 있다고 하더라도 그 복잡하고 어지러운 업무량은 모두 다룰 수 없다.만일 그런 것이 가능하다고 이야기하는 경영진이 있거나 무지한 영업맨이 있다면 정신 차리라고 조언해주자. 심지어 그렇게 만들 수 있는 서비스는 존재하지 않고, 존재한다고 하더라도.. 어마어마한 '기술적 부채'가 존재하며, 대부분의 가장 비싼 개발자의 리소스를 그 기술적 부채를 해결하기 위해서 사용되고 있을 것이라고.물론, 그렇게 동작하는 허접하고 쓰레기 같은 코드라고 하더라도, 특정 조건과 특정 환경에서는 서비스가 가능한 경우가 한국에는 많이 존재한다. 경영진이나 영업, 기획은 고객들을 설득하고 고객들이 해당 제품과 서비스를 사용하기 위해서 일부를 희생할 것이다. 그리고, 분명 다른 영역에서 누수가 발생하거나 희생되고 있는 것을 잊지 말자.특히나 경쟁이 없는 제품이거나 더 이상 리소스를 투입하기 어려운 소프트웨어나 서비스의 경우에는 이런 형태로도 동작은 할 것이다. 하루에 한두 번 서버의 Oracle 커넥션을 모두 종료하는 유지보수 행위를 하는 전산실의 업무가 그러한 경우 때문에 벌어진다.중견기업이거나 제조업체, 병원의 전산실에 '야간 당직'업무가 있고, 시스템 모니터링에 민감하다면 대부분 '기술적 부채'를 안고 허접하게 만들어진 것뿐이라고 판단하면 된다.말 그대로, 헬조선의 헬게이트, 헬(!)한 업무환경으로 소프트웨어 개발자로서 비전이 없는 영역이라고 생각하면 된다. 하지만, 그럼에도 불구하고... 스타트업 경영진이나 대기업, 중소기업 경영진들은 '풀스택 개발자'의 환상에 대해서 이야기한다.'모든 것을 다 하는 개발자'가 있으면, 복잡한 커뮤니케이션 비용도 안 들고, 인건비도 적게 들것이라는 착각을 한다. 다만, 이 부분만큼은 명쾌하게 이야기하겠다. '그런 회사 가지 말라'는 것이다.'풀스택 개발자'를 구인하고 있는 회사는 개발자의 무덤이라는 것이다. 대부분 그러하다. 그 이유를 다음과 같이 정리하겠다. 그들이 '풀스택 개발자'를 뽑고 싶은 이유는 간단하다. '돈'이 없어서다. 그리고, 다음의 이유들이 있는 경우이다.하나. 경영진이 요구사항 정의도 제대로 못하므로 개발자와 의사소통에 자신이 없다. 그래서, 풀스택 개발자를 구하려고 한다. 한 명 하고만 이야기하면 될 것이라고 착각한다.둘. 개발자의 인력이 몇 명이 투입되는지에 대해서 평가나 정의가 불가능하므로, 풀스택 개발자를 구하려 한다.셋. 개발자가 두 명, 세명이 있다면 팀 리더도 있어야 하고, 관리자도 있어야 하므로 그 비용을 줄이기 위해서 풀스택 개발자가 필요하다. 한마디로, 돈이 없다.넷. 현대의 웹서비스들을 가동하기 위해서는 최소한의 비용과 인건비가 투여된다. 이 비용을 투자할 정도로 비즈니스 모델에 가치가 없기 때문에 여러 명의 개발자를 고용할 수 없기 때문에 풀스택 개발자를 구하려 한다.다섯. 풀스택 개발자라면 막연하게 다 해줄 것 같은 환상을 가진 경영진이 있는 경우이다. 슬프지만, 전설의 개발자인 '제프 딘'을 고용한다고 하더라도, 삽질을 할 것이다.물론, 스타트업에 초기에 합류하면서 CTO의 역할을 부여받았다면 조금은 입장이 달라진다. 정당한 지분을 받고, 미래의 가치에 대해서 나눌 수 있다면, 해당 롤을 가진 사람은 알아서 '풀스택 개발자'가 될 가능성이 크다. 그러므로, 매우 당연하지만 CTO는 풀스택 개발자에 근접되면 좋기는 할 것 같다. 하지만, 현실적으로는 그렇게 세팅하지 못하는 경우가 대부분이다.그리고, 냉정하게 초기 개발이나 Lab수준, 시리즈 A를 투자받기 전의 '소프트웨어'나 '서비스'는 대부분 비즈니스 모델을 증명하는 수준에서 끝내는 것이 바람직하다. 굳이, 환상의 개발자나 풀스택 개발자가 아니라도 비즈니스 모델을 검토하고 증명하는 모델을 구현하는 것은 충분하게 가능한 경우가 대부분이다.사용자가 수백만 명도 아니고, 구현된 기능들도 수백 가지가 아니며, 아직은 스파게티 식으로 구성하더라도 무방하기 때문이다. 해당 기술적 부채는 서비스의 증명 후에 해당 코드는 버려지고, 다시 개발팀을 제대로 세팅하여 구현하면 되기 때문이다. 더군다나, 대부분의 스타트업은 고속 개발을 해야 하기 때문에 '풀스택 개발'이 가능한 '웹'만으로는 모든 것을 커버하기 어려울 것이다.좌우지간, 간단하게 이야기해서 '풀스택 개발자'타령하는 구인광고를 보게 된다면, 그 회사나 팀은 무언가 잘못 생각하고 있거나, '돈'이 없는 조직이라고 생각하면 된다. 거기에, '기술'이나 '개발'에 대해서는 아무것도 모르는 사람이 사장이 존재하는 곳이라고 생각하면 된다.헬게이트에 입성하고픈 개발자라면 '풀스택 개발자'를 구인하는 곳으로 가면 된다. 엄청난 '일'의 쓰나미를 경험하고, 인성이 피폐해지는 것을 경험할 것이다.필자는 국내 최고의 개발자들을 여럿 알고 있다. 하지만, 그분들은 자신들을 '풀스택 개발자'라고 이야기하지 않는다. 그 용어가 의미하는 것 자체가 '날림'이라는 것을 너무도 잘 알고 있기 때문이다. 물론, 10년 20년을 소프트웨어 개발을 하다 보면 얻어지는 경험과 지식들이 있다.궁극적으로는 풀스택 개발자가 이야기하는 비슷한 테크트리를 대부분 알고는 있게 된다. 하지만, 경력 20년 되고 하나의 도메인에 익숙하며, 특정 분야의 대가인 분들을 스타트업에서 고용한다는 것은 거의 불가능에 가깝다. 간혹, 그런 분들이 직접 스타트업을 하는 것이라면 모를까 말이다.이제 이야기를 마무리하겠다.'웹 개발'을 하려면 '풀스택 개발'을 지향하는 것은 맞다. 하지만, 그것 자체가 완벽한 풀스택 개발을 의미하는 것이 아니라는 것을 생각하기 바란다. 그리고, 경영진이나 비개발자들에게도 다시 한번 이야기한다. '풀스택 개발자'를 구인하겠다는 환상을 버리기 바란다.그런 사람 없고, 있다고 하더라도... '풀스택 개발자'를 구인하겠다는 발상으로는 절대 초빙하거나 모실 수 없다는 것을... 깨몽 하기 바란다.물론, '풀스택 개발자'처럼 이것 저것 다하는 정성스럽고, 일에 애정 넘치는 개발자들을 제대로 대우해주시기를... 기술로써의 풀스택 개발자가 아니라, 그 기업이 원하는 일을 풀스택 개발자처럼 일할 뿐이다. 그들에 대한 애정 넘치는 말한마디... 경영진들에게 부탁드린다.갑자기, '풀스택 개발자'에 대한 환상에 대해서 정리하고 싶어서 한 번에 글을 써 내려갔다. ~.~
조회수 2624

Retrofit2 로 전환

Android 와 NetworkAndroid 에서 Network 라이브러리들은 다양하지만 근 1년 사이에 주로 사용되는 라이브러리들이 점차적으로 적어지고 있습니다.오늘은 그 중에서 Retrofit 에 대해 이야기 하고자 합니다.토스랩의 Android Network Library1. Spring-Android, Retrofit 그리고 Retrofit2토스랩은 총 3개의 네트워크 라이브러리를 사용하였습니다. 초창기에는 AndroidAnnotations 에 연동되어 있는 Spring-Android 를 사용하였습니다. 하지만 다중 쓰레드 환경에서 동일한 Request 객체를 사용하면서 저사양 단말에서 문제로 두각되기 시작하였습니다.그래서 Retrofit 으로 2015년 중순쯤 전환을 하였습니다. 그러다 2016년 초 Retrofit2 가 정식 배포가 되면서 자연스럽게 Retrofit2 로의 전환이 대두되기 시작하였습니다. 전환의 이유는 내부의 네트워크 모듈에 대한 Refactoring 이었는데 그와 동시에 Retrofit2 로의 전환도 함께 진행되었습니다.2. 이슈들What the CALL기존의 Retrofit 은 200~399 에러에 대해서는 정상적인 Body 를 반환하고 400 이상의 경우에는 Typed Exception 형태로 로직을 진행하였습니다. 하지만 이정도로는 Response Status 나 Header 정보를 알기에는 추가적인 로직이 필요로 하였습니다. 물론 Success 케이스에도 마찬가지이긴 하였습니다.이는 Retrofit 의 기본적인 목적에 부합되지 않는다는 문제가 있었습니다. Retrofit 의 가장 기본적인 목적은 Okhttp 의 상위 구현체로써 쉽게 Request 와 Response 를 구현한다는 것입니다. 손쉬운 구현이 필요한 정보를 제외시킨다는 것은 별개의 문제이기 때문입니다.그래서 Retrofit2 에서는 Call 객체를 통해서 Request 와 Response 에 적용된 Header, StatusCode, Body 등을 직접 접근 할 수 있도록 인터페이스를 추가하였습니다.이 객체는 불변성을 가지고 있기 때문에 Getter 만이 존재하며 Request 에 필요한 정보는 다른 부분에서 적용되어야 함을 명시하셔야 합니다.Call 객체의 적용Call 객체를 적용하는 과정에서 2가지의 이슈가 있었습니다.Interface 의 모든 Return Value 를 Call 로 전환할 것Request Error 를 직접 핸들링 하도록 수정해야 함이 2가지 때문에 여러가지가 연쇄적으로 수정되어야 했습니다.먼저 수정과정을 설명하기 앞서 Jandi 앱의 Network 통신 전제조건에 대해서 설명해드리도록 하겠습니다.Jandi 앱은 모든 Network 통신은 Current Thread 에서 한다는 것을 전제로 합니다. 이는 MainThread 에서의 통신이 아니라 호출자의 Thread 를 따라간다는 것을 전제로 하고 있습니다. 또한 이를 위해 Reponse 반환, Error Handling, 세션 자동 갱신을 위해 Generic 으로 선언된 Facade 용도의 Wrapper Class 를 별도로 두고 있습니다.따라서 수정해야할 1,2 번을 위해 아래와 같은 수정을 하였습니다.Facade Class 내에서 성공여부를 직접 파악한다.성공시 Return Value 를 직접 반환할 수 있도록 한다.실패시 Status, Response 정보를 이용하여 throw Exception 을 한다. (세션 정보를 갱신 로직은 당연히 포함되어 있습니다.)그래서 아래와 같은 코드 형태가 되었습니다.Response response = apiExecutor.execute(); if (response.isSuccessful()) { RESULT object = response.body(); retryCnt = 0; return object; } else { // 400 이상 오류에 대해 처리 return handleException(apiExecutor, response, null); } Network 통신 과정에서의 Exception 이 나는 경우는 2가지 입니다.기기의 Network 자체가 끊겨 있거나 비정상인 경우Response 의 Parsing 과정에서 오류가 발생한 경우Annotation 의 변화Annotation 의 가장 큰 변화는 DELETE 였습니다. 기존의 Retrofit 에서는 DELETE 요청은 GET 방식으로 가능하였습니다. 즉 POST 처럼 Body 를 설정할 수 없게 되어 있었습니다. 따라서 DELETE 를 쓰기 위해서는 별도의 Custom HTTP Annotation 을 설정 할 적용하여야 했습니다.Retrofit2 에서는 이런 경우에 대비하기 위해 @HTTP 를 개방하였습니다. @HTTP(path = "{url}", method = "DELETE", hasBody = true) 와 같이 사용해야만 Custom HTTP Method 를 적용하실 수 있습니다.Jackson2-Converter 대응Jackson2-Converter 의 이슈는 최근에서야 알게 되었습니다. Jandi 앱은 그동안 Jackson 1.x 를 사용하였고 최근에서야 Jackson2 로 전환을 하였습니다.그 과정에서 Retrofit2 의 converter-jackson 라이브러리를 사용하려 하였으나 중대한 문제가 있었습니다.Retrofit2 에서 Reqeust Body 의 Serialize 는 메소드의 참조변수로 선언된 클래스만 지원하며 상속한 자녀클래스를 넣어도 부모 클래스의 결과만을 리턴 하는것이었습니다. (gson 과 여타 converter 에 대해는 해당 이슈에 대해 파악해보지 않았습니다).이를테면 아래와 같은 경우입니다.interface Api { @PUT("/profile") Call modifyProfile(@Body Profile profile); } public class Profile {} public class NameProfile extends Profile{ String name; } public class PhoneProfile extends Profile{ String phone; } // using case api.modifyProfile(new NameProfile("Steve")); 허나 아래와 같은 상황이 펼쳐집니다.// expect {"name":"Steve"} // actual {} 해당 문제는 Converter-Jackson 의 이슈이기 때문에 위와 같은 상황이 예상된다면 별도의 Converter.Factory 를 선언하여 사용하시기 바랍니다.OkHttpClient 생성 이슈Okhttp 에 여러가지 기능이 추가되었습니다. 그중 잔디가 사용 중인 목록입니다.okhttp-logging-interceptorauthenticatorCutome SSL이런 이유 때문에 OkHttpClient 를 직접 생성하여 사용 하고 있습니다.처음에는 OkHttpClient 를 모든 API 호출시 새로 생성하도록 하였습니다. 헌데 TestCode 가 200회가 넘어가면 File IO 를 너무 많이 사용했다는 오류가 계속적으로 발생하였습니다.이 오류가 단순히 File IO 가 많아서 라는 메세지 때문에 처음에는 Database 에 대한 오류인 줄 알고 Memory Cache 작업과 테스트코드 개선작업을 하였으나 정상 동작이 되지 않았습니다. (테스트 코드 1회에 평균 2번의 API 통신과 2회의 DB 처리를 합니다.)그 와중에 기존의 테스트 코드는 정상 동작하는 것을 보고 Retrofit2 작업을 진행한 branch 만의 문제임을 깨달았습니다.현재는 OkhttpClient.Builder 를 통해 생성한 1개의 OkhttpClient 만을 재사용하도록 변경하였습니다.Network Retry 시 동작 변경Retrofit2 는 Call 객체를 이용하여 동일한 정보로 재요청을 할 수 있도록 지원하고 있습니다. 하지만 이에 대한 제약이 하나 있습니다. 이미 Network IO 가 끝난 경우 Retrofit2 는 Call 객체를 복사하여 재사용할 것을 가이드 하고 있습니다. 그래서 재요청시 다음과 같이 코드를 작성하셔야 합니다.Call call = action0.call(); if (!call.isExecuted()) { return call.execute(); } else { return call.clone().execute(); } OkHttp3 의존성Okhttp 를 사용하는 타 라이브러리가 있다면 Okhttp3 의존성을 가지고 있기 때문에 이에 유념하셔야 합니다.3. 정리Retrofit1 -> Retrofit2 로 변경하는 과정에서 다양한 이슈를 발견하였습니다.Return Value 수정Exception 처리 강화Annotation 수정Request-Response Converter 수정OkhttpClient 재사용 정의재요청 처리에 대한 validation 추가OkHttp3 의존성Retrofit2 로 변경에 있어서 가장 큰 핵심은 Call 이라는 객체라고 할 수 있다는 것입니다.이 객체는 Request 에 대한 동작 제어(cancel, retry 등), Request-Response 의 독립성 보장, 그에 따라 각각의 정보에 대한 접근 등을 보장하게 됩니다.Retrofit2 는 그외에도 Okhttp3 와 다양한 플러그인 지원하고 있습니다. 요청-응답에 필요한 Body 의 변환툴 (Converter-xxx), EndPoint 에서 접근하는 Call 객체에 대한 다양한 툴 (CallAdapter-xxx)현재 Retrofit1 에서 잘 동작하고 있고 의도대로 흐름제어를 하고 있다면 Retrofit2 로 옮겨갈 이유는 없습니다. 하지만 변경을 하고자 한다면 이러한 영향도가 있을 것임을 공유해드렸습니다.참고하면 좋은 Slidehttps://speakerdeck.com/jakewharton/simple-http-with-retrofit-2-droidcon-nyc-2015Jake Wharton’ Retrofit2Presentation 영상#토스랩 #잔디 #JANDI #개발 #개발자 #인사이트 #경험공유
조회수 1222

Navigation Controller 자유롭게 다루기

Intro: The Navigation Controller예고했던 Navigation Controller와 TabBar Controller의 커스터마이즈 중, Navigation Controller의 구조와 간단한 커스텀 방법을 나누겠습니다. Navigation Controller(이하 내비게이션 컨트롤러)는 거의 모든 iOS 앱에서 사용된다고 해도 과언이 아닌 자주 사용되며, 간결하지만 막강한 기능을 가진 컨트롤러입니다. 앞선 글에서 소개했듯, TabBar Controller와 함께 iOS의 양대 컨트롤러라고 불러도 대부분의 iOS 개발자들이 동의하리라고 생각합니다. 이번 글에서는 내비게이션 컨트롤러를 커스텀하는 방법을 소개하겠습니다.Navigation Cotroller (출처: apple developer)목차1. Push, Pop 애니메이션 커스터마이징2. Pop 제스처 사용하기, 사용하지 않기3. Back 버튼 타이틀 숨기기4. 상단 좌우의 버튼 추가하기5. NavigationBar 숨기기, 보여주기6. What’s NEXT?1. Push, Pop 애니메이션 커스터마이징Push, Pop 트랜지션 기능은 내비게이션 컨트롤러의 핵심적인 기능입니다. Stack에 다음 View Controller를 쌓으며 디스플레이하는 것이 Push, 이전의 View Controller로 되돌아가는 것이 Pop 액션입니다. Pop 액션에는 최초에 디스플레이됐던 View Controller로 돌아가는 Pop to Root 액션이 포함되어 있습니다.<iframe width="560" height="315" src="https://www.youtube.com/embed/NqfYhI5ySKk" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="">Pop View Controller(animated)이러한 액션에는 애니메이션이 포함됩니다. 대개 기본적으로 적용된 애니메이션을 사용하면 되지만, 어떤 이유로 애니메이션을 커스텀하고 싶은 경우가 생깁니다. 이럴 때는 UINavigationController를 상속하는 커스텀 클래스를 만들어서 커스텀할 수 있습니다. 물론 Extension 형식으로 함수를 작성할 수도 있습니다.// UINavigationController를 상속하는 커스텀 클래스를 작성 class BRNavigationController: UINavigationController { // 애니메이션을 적용하는 함수를 작성 func overrideAnimation() { //여기에서 커스텀 애니메이션을 작성합니다. let transition = CATransition() transition.duration = 0.3 transition.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut) transition.type = kCATransitionFade self.view.layer.add(transition, forKey: nil) } // popToRootViewController(animted)를 오버라이드 override func popToRootViewController(animated: Bool) -> [UIViewController]? { print("Custom Animation Triggered") if(viewControllers.last!.isKind(of: PersonalViewController.self)) { // 커스텀 애니메이션을 사용할 ViewController의 케이스를 분기한다 // 작성된 커스텀 애니메이션 트리거 self.overrideAnimation() //UINaivgationController의 Function을 그대로 반환 return super.popToRootViewController(animated: false) } else { // 다른 모든 케이스의 경우 디폴트 애니메이션을 사용 //UINavigationController의 Function을 그대로 반환 return super.popToRootViewController(animated: animated) } } } 위의 코드로 작성한 애니메이션 아래의 영상과 같이 동작합니다.<iframe width="560" height="315" src="https://www.youtube.com/embed/g_XCo1Hmnj0" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="">커스텀 Pop 애니메이션이 적용된 Navigation Controller위와 같이 커스텀된 내비게이션 컨트롤러는, 단지 애니메이션을 오버라이드하는 데 그치지 않고 다양한 방식의 효율적 코드 작성을 할 수 있게 합니다. 우리가 아는 것처럼, 수퍼클래스의 위용과 유용을 마음껏 누릴 수 있습니다.2. Pop 제스처 사용하기, 사용하지 않기내비게이션 컨트롤러에서는 화면 왼쪽 끝에서 오른쪽으로 스와이프하는 Pop 제스처를 사용해 이전 View Controller로 돌아갈 수 있습니다. 하지만 종방향 스크롤이나 스와이프 이벤트를 사용하는 ViewController의 경우 어쩔 수 없이 Pop 제스처를 막아야 하는 일이 생깁니다. 이럴 때에는 해당하는 ViewController에서 다음과 같이 간단한 코드로 Pop 제스처를 방지하거나, 방지 해제할 수 있습니다.// 아래의 코드를 트리거하면 Pop 제스처를 비활성화할 수 있습니다 self.navigationController?.interactivePopGestureRecognizer?.isEnabled = false 이 코드를 한 번 적용하면, 해당 내비게이션 컨트롤러의 Stack에 쌓인(또는 쌓일) View Controller에 일괄적으로 적용되기 때문에 반드시 다른 ViewController에서는 기본적으로 isEnabeld를 True값으로 지정하도록 코드를 구성하여 모든 ViewController에 일괄적용되는 것을 방지해야 합니다.다만 이 부분에서 중요한 것은, Back 버튼을 숨기거나 커스텀할 때 각별히 주의해야 한다는 것입니다. 제스처를 사용하는 사용자들도 있지만, 제스처의 존재 자체를 모르는 사용자들도 있기 때문에 Back 버튼은 대부분의 경우 유지하는 것이 좋습니다. 제스처를 비활성화할 때는 더더욱 유지해야 하고요.Back Button이 없다면 어떻게 뒤로 돌아갈 수 있을까요.3. Back 버튼의 타이틀 숨기기내비게이션 컨트롤러에 포함된 Navigation Bar(이하 내비게이션 바)의 Back 버튼은 자동으로 이전 ViewController의 타이틀을 보여주도록 디폴트 설정되어 있습니다. 이렇게 자동지정된 타이틀이 마음에 들지 않는다면, 간단한 트릭을 사용하여 타이틀을 없앨 수 있습니다.먼저, Back 버튼의 타이틀이 되는 이전 ViewController의 타이틀은 ViewController에서 다음과 같이 지정됩니다.// 직접 ViewController의 타이틀을 지정 viewController.title = "이것이 바로 타이틀입니다" Back Button에 '상품정보' 타이틀이 보입니다.위의 코드로 지정한 ViewController의 타이틀은 Push 액션을 통해 다음 ViewController로 넘어갔을 때 Back 버튼의 타이틀로 사용됩니다. 그래서 이 코드를 사용하지 않고, 커스텀 Label을 titleView에 넣어주는 것으로 대신할 수 있습니다.// titleView로 사용할 Label을 생성 let label = UILabel(frame: customFrame) label.text = "이것을 타이틀로 사용합니다" // viewController의 titleView를 생성한 Label로 셋업 viewController.titleView = label 짜잔- Back Button의 타이틀이 사라졌습니다!4. 상단 좌우 버튼 추가하기여러 iOS 앱들을 사용하다 보면, 내비게이션 바의 좌/우측단에 위치한 버튼들을 자주 보게 됩니다. 이 버튼들은 BarButtons(이하 내비게이션 바 버튼) 라고 불리우는 컴포넌트들입니다. 내비게이션 바 버튼들은 배열 방식으로 좌/우측에 각각 배치됩니다. 원하는 이미지와 텍스트 등으로 내비게이션 바 버튼을 생성한 후, 좌/우측의 버튼 배열 중 원하는 곳에 각각 넣어주면 디스플레이 되는 방식입니다. 다음의 코드 예제를 통해 내비게이션 바 버튼을 추가할 수 있습니다.// RightBarButtons에 추가할 UIBarButtonItem을 생성 let customButton = UIBarButtonItem(customView: customView) // Container가 될 Array를 생성 (혹은 직접 지정하는 방법도 있습니다) let rightBarButtons: [UIBarButtonItem] = [] // Array에 버튼 아이템을 추가 rightBarButtons.append(customButton) // RightBarButtonItems 배열을 셋업 viewController.navigationItem.rightBarButtonItems = rightBarButtons //LeftBarButtons에 추가할 UIBarButtonItem을 생성 let customButtonCopy = UIBarButtonItem(customView: customView) // Container가 될 Array를 생성 (혹은 직접 지정하는 방법도 있습니다) let leftBarButtons: [UIBarButtonItem] = [] // Array에 버튼 아이템을 추가 leftBarButtons.append(customButtonCopy) // LeftBarButtonItems 배열을 셋업 viewController.navigationItem.leftBarButtonItems = leftBarButtons 타이틀뷰, LeftBarButton, RightBarButton이 모두 커스텀된 브랜디의 홈5. NavigationBar 숨기기, 보여주기앱의 UI가 전체화면으로 컨텐츠를 표시해야 할 때, 또는 다른 목적에 의해서 내비게이션 바를 숨기거나 보여주어야 할 때가 있습니다. 이럴 때는 간단한 코드 트리거로 내비게이션 바를 숨기거나 보여줄 수 있습니다.// 단 한 줄의 코드로 내비게이션 바를 숨길 수 있다구요? navigationController.setNavigationBarHidden(false, animated: true) <iframe width="560" height="315" src="https://www.youtube.com/embed/ldpe-M8Uyy8" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="">내비게이션바를 숨겼다가 보였다가6. What’s NEXT?현재 앱스토어에 배포된 브랜디 iOS 앱은 내비게이션 컨트롤러를 적극적으로 활용하여 작성되었습니다. 내비게이션 컨트롤러는 기본 설정으로 사용할 때에도 여전히 막강한 특징들을 많이 가지고 있기 때문에, 선택적으로 알아두어야 할 컴포넌트가 아닌 필수적으로 그 장단점과 용법을 꿰고 있어야 하는 중요한 컴포넌트입니다. 내비게이션 컨트롤러만 잘 다루어도 앱을 개발할 때 굉장히 도움을 많이 받을 수 있다는 것이죠.내비게이션 컨트롤러는 다양한 방식으로 커스터마이즈를 할 수도 있습니다. 물론 이러한 커스터마이즈는 필수사항은 아닙니다. 디자인적 요소를 적용하기 위해 커스터마이즈하는 경우가 대부분이지만, 그에 못지 않게 개발자가 프로젝트의 컴포넌트를 정규화하고 모듈화하기 위해 커스텀하는 경우도 많은 만큼 StackOverflow나 애플 개발자 문서를 참고해 다양한 커스터마이즈를 해보는 것도 재미있을 겁니다.다음 글에서는 TabBar Controller의 커스터마이즈 방식에 대해 간략하게 공유하겠습니다. iOS 루키들의 장수와 번영을 바라며, 글을 마칩니다. Live long and prosper!참고UINavigationController - UIKit | Apple Developer Documentation글이정환 과장 | R&D 개발MA팀leejh@brandi.co.kr브랜디, 오직 예쁜 옷만
조회수 9056

AWS 비용 얼마까지 줄여봤니?

최근 들어 스타트업의 인프라는 DevOps의 유행과 함께 IDC에서 클라우드로 급속도로 이전해가고 있습니다. 많은 클라우드 업체가 있지만 그중에서도 Amazon Web Service (AWS) 가 가장 선호되고 있고 잔디도 AWS를 이용하여 서버 인프라를 구성하고 있습니다. 하지만 AWS 비용은 예상보다 만만치 않습니다. 잔디에서는 비용을 줄이기 위해 여러 가지 노력을 하고 있는데 이 글에서는 스케쥴링 기능을 이용하여 비용을 줄이는 방법에 대해 공유하도록 하겠습니다.AWS는 저렴한가?AWS는 ‘저렴한 비용’을 자사 서비스의 큰 강점이라고 홍보하지만 실제 사용해보면 막상 ‘과연 정말 저렴한가?’ 라는 의문을 가지게 됩니다. 여러 클라우드 업체의 비용을 비교한 리포트를 보더라도 AWS는 절대 저렴하지 않습니다. 오히려 클라우드 업체 중 가장 비싼 곳 중 하나입니다. 그렇다고 이제 와서 클라우드 업체를 옮기는 건 배보다 배꼽이 더 클 수도… (들어올때는 맘대로지만 나갈땐 아니란다.)예약 인스턴스? 스팟 인스턴스? 온디맨드?AWS에서는 제공하는 요금 할인 방법은 예약 인스턴스나 스팟 인스턴스를 이용하는 것입니다.예약 인스턴스는 계약 기간에 따라 최대 60%까지 저렴한 가격으로 이용할 수 있습니다. 하지만 정확한 기간과 수요예측을 하지 못한다면 잉여 인스턴스가 될 수 있습니다.스팟 인스턴스는 입찰가격을 정해놓고 저렴할 때 이용할 수 있습니다. 하지만 그때가 언제일지도 알 수 없고 인스턴스를 가져갔다고 하더라도 더 높은 입찰가격을 제시한 사용자에게 인스턴스를 뺏길 수 있습니다. 마치 KTX를 입석 티켓으로 빈 좌석에 앉아서 가다가 좌석 티켓 주인이 나타나 ‘내 자린데요?’ 하면 얄짤없면 좌석을 내줘야 하는 느낌입니다. 그때 느끼는 그 서러움은 느껴보지 못한 자는 알 수 없습니다.온디맨드는 사용한 만큼 할인 없이 비용을 지불하는 것입니다. 언제든지 필요할 때 사용하고 사용한 만큼만 과금되어 가장 적절해 보이지만 예약이나 스팟에 비해 역시나 비쌉니다. 비싸지만 현실적으로 가장 많이 사용됩니다.개발서버는 얼마 안쓰는데 좀 깍아줘!일반적으로 개발서버도 라이브와 같이 구성합니다. 고가용성은 고려하지 않더라도 아키텍쳐는 똑같이 구성하게 됩니다. 그리고 아키텍쳐가 복잡해질수록 구성하는 서버도 많아지고 언제부턴가는 개발서버도 비용을 무시할 수 없는 수준에 이르게 됩니다. 하지만 개발서버는 24시간 사용하지도 않고 업무시간에만 사용합니다. 이쯤 되면 한 번쯤 이런 생각을 하게 됩니다. ‘개발서버는 실제로 얼마 쓰지도 않는데 좀 깍아줘야 되는 거 아냐?’ 개발서버뿐만 아니라 정해진 시간만 사용하는 모든 서버들이 해당될 것입니다.EC2 SchedulerAWS는 이러한 원성(?)을 들었는지 EC2 Scheduler 라는 간단한 솔루션을 소개했습니다. 내용을 보면 설정된 시간과 요일에 자동으로 EC2 인스턴스가 자동으로 켜지고 꺼집니다. 하루 10시간 가용한다면 주말 제외 월~금요일만 작동시켜 비용을 70%나 절감할 수 있습니다.이대로만 된다면 왠만한 스팟이나 예약 인스턴스보다 더 저렴하게 개발서버를 이용할 수 있습니다. 하지만 이 솔루션을 그대로 도입하기에는 문제점들이 있었습니다.EC2 Scheduler 의 문제점EC2 Scheduler는 다음과 같은 문제점들이 있습니다.서버 아키텍쳐에 따라서 의존성이 있어 서버 실행 순서가 보장되어야 하는 경우가 고려되지 않는다.단순히 EC2 한두 대 띄워서 사용하는 게 아니고 훨씬 더 복잡한 서버 의존 관계를 가지게 됩니다. 예를 들어 DB -> Middleware -> API -> Batch 같은 관계가 있다고 한다면 의존관계에 있는 서버들이 순차적으로 실행되어야 합니다.스케쥴 시간이 UTC로만 작동한다.UTC로만 작동하기 때문에 시간 설정을 할 때는 항상 UTC 기준으로 변환해야 하는 불편함이 있습니다.스케쥴링의 예외적인 상황이 고려되지 않는다.평일이 공휴일인 경우에는 서버를 작동할 필요가 없고 평소보다 서버를 일찍 켜야 하거나 야근을 하게 되어 중지 시간을 변경해야 되는 경우에는 해당 일자에만 변경이 가능해야 했습니다.EC2에 대해서만 작동하도록 되어 있다.EC2보다 비싼 RDS도 최근에 Stop 시킬 수 있도록 추가되었습니다. Aurora는 미지원잔디의 서버 아키텍쳐는 훨씬 복잡하여 서버의 실행 순서가 맞지 않으면 정상작동을 하지 않기 때문에 1번은 반드시 해결되어야 하는 가장 치명적인 문제였습니다.AWS Instance SchedulerEC2 Scheduler의 문제점을 보안한 Instance Scheduler를 소개하겠습니다. EC2나 RDS 모두 하나의 서버를 Instance로 부르기 때문에 Instance Scheduler라 하였습니다. Instance Scheduler는 Serverless 아키텍쳐인 Cloudwatch + Lambda를 이용하여 구성되어 있습니다.작동방식Cloudwatch Event를 이용하여 Lambda를 함수를 실행시키고 Dynamo DB에 저장된 스케쥴 정보와 Instance의 Tag 값을 기반으로 RDS와 EC2를 조회하고 Instance를 시작하거나 중지합니다. 그리고 JANDI의 Incoming Webhook을 이용하여 토픽에 알림 메시지를 보내줍니다.Cloudwatch EventInstance Scheduler Lambda 함수를 작동시키는 트리거는 Cloudwatch Event를 이용합니다. 5분마다 작동시키도록 되어 있으며 각각의 사용 환경에 따라 변경할 수 있습니다.Cron 식 0/5 * * * ? *, 대상은 Instance Scheduler Lambda를 지정합니다.Dynamo DBDynamo DB에는 Schedule, Schedule 예외 설정, Schedule 서버 그룹에 대한 정보가 정의되어 있습니다.1. ScheduleSchedule 작동에 대한 기본 정보를 정의하고 있습니다.{ "ScheduleName": "Development", "TagValue": "Development", "DaysActive": "weekdays", "Enabled": true, "StartTime": "09:30", "StopTime": "22:00", "ForceStart": false } ScheduleNameSchedule 이름 입니다.TagValue적용 대상 Instance를 조회할 때 참조하는 Tag 값입니다. Instance를 Schedule에 적용 대상에 포함시키기 위해서는 해당 Instance의 Tag에 ScheduleName이라는 Key에 TagValue를 Tagging 하면 됩니다.DaysActiveSchedule 적용 요일입니다. 아래와 같은 옵션이 적용됩니다.all : 매일weekdays : 월~금mon,wed,fri : 월,수,금요일EnabledSchedule의 작동 여부입니다.StartTime, StopTime서버 시작 시간과 중지 시간입니다.ForceStartSchedule 강제 시작 여부를 나타냅니다. (Enabled 여부에 상관없이 작동합니다.)2. Schedule Server Group하나의 Schedule에는 N 개의 서버 그룹을 정의할 수 있고 각각은 먼저 실행되어야 하는 의존관계 서버 그룹을 정의하고 있습니다. 의존관계에 있는 서버 그룹의 Instance Status를 확인하여 시작 여부를 결정하도록 하였습니다. 그러면 의존관계가 없는 서버 그룹부터 시작하고 의존관계의 Depth 가장 깊은 서버 그룹은 가장 늦게 시작하게 되어 서버 실행 순서를 보장하게 됩니다.{ "Dependency": [ "GROUP1", "GROUP2", "GROUP3", "GROUP4" ], "GroupName": "GROUP5", "InstanceType": "EC2", "ScheduleName": "Development" } Dependency의존관계 서버 그룹 목록입니다.GroupName서버 그룹 이름입니다.InstanceTypeEC2와 RDS를 지원합니다.3. Schedule Exception공휴일이나 야근 등으로 인해 스케쥴을 미작동 시키거나 시간을 변경해야 하는 경우에 예외사항들을 정의하고 있습니다.{ "ExceptionUuid": "414faf09-5f6a-4182-b8fd-65522d7612b2", "ScheduleName": "Development", "ExceptionDate": "2017-07-10", "ExceptionType": "stop", "ExceptionValue": "21:00" } ScheduleName예외 적용 대상 Schedule의 이름입니다.ExceptionDate예외발생일 (YYYY-MM-DD)ExceptionTypestart : 시작stop : 중지ExceptionValueNone : 미작동H:M : 변경시간LambdaInstance Scheduler의 Lambda 코드는 Python으로 개발되었으며 Github에 오픈소스로 공개하였습니다. boto3는 배포 package에 Dependency를 추가하지 않아도 Lambda 실행환경에서 가용 라이브러리로 사용할 수 있습니다. 하지만 현재 기본적으로 사용할 수 있는 boto3 버전에서는 RDS Instance를 stop 할 수 있는 함수가 없기 때문에 최신 버전이 필요합니다. 따라서 boto3 버전을 변경하여 함께 packaging 하여 업로드하여야 합니다. 배포는 Lambda 관리 도구인 Apex를 이용합니다. Apex를 이용하면 Dependency package 및 Lambda 생성 및 업데이트, 환경 변수 설정 등을 모두 한 번에 할 수 있습니다.참조 : Lambda Execution Environment and Available LibrariesAWS SDK는 Python boto3 (botocore:1.5.75, boto3:1.4.4) 를 이용합니다.TimeZone 설정Lambda는 기본적으로 UTC TimeZone으로 설정되어 있으며 Instance Scheduler에서는 TimeZone을 변경할 수 있도록 하였습니다. 기본 설정은 Asiz/Seoul이고 아래 코드를 수정하여 변경할 수 있습니다.os.environ['TZ'] = 'Asia/Seoul' time.tzset() JANDI 메신저와 연동Instance Scheduler는 JANDI 메신저의 Incoming Wehbook 을 이용하여 Webhook URL을 Lambda의 환경 변수에 설정하면 서버의 시작과 중지에 대한 알람과 중지 10분 전부터 곧 서버가 중지된다는 알람을 발송하여 필요하다면 서버 중지 시간을 연장할 수 있도록 합니다.Incoming Webhook 설정JANDI의 토픽에서 Incoming Webhook을 연결하고 Webhook URL을 복사합니다.배포된 Lambda 함수의 Code 탭에서 Environment variables에 WEBHOOK_URL을 설정하거나 function.json에서 변경 후 재배포 하여도 됩니다.Instance Scheduler 알람서버 그룹이 시작되면 아래와 같이 알람 메시지를 표시합니다.서버가 중지되기 전에 알람 메시지를 표시합니다.정리Instance Scheduler는 EC2 Scheduler에 비해서 다음과 같은 기능이 추가되었습니다.스케쥴 시간의 타임존 적용서버 그룹 설정 및 의존관계 설정스케쥴의 예외 설정RDS 스케쥴 추가스케쥴에 상관없이 강제 시작 및 중지메신저로 상태 알람EC2 Scheduler에 비해 아쉬운 부분이나 예외사항에 대해서 좀 더 유동적으로 대응할 수 있도록 개선하였습니다.다음 장에는 스케쥴을 컨트롤을 위한 Bot 적용기를 소개하도록 하겠습니다.#토스랩 #잔디 #JANDI #AWS #서버개발 #개발 #개발자 #개발팀 #경험공유 #인사이트 #후기 #일지
조회수 796

Top Five Games Made in Seoul

 Based in a country seeing huge growth in its video game sector, Korean game studios have been releasing big hits in the past few years. As seen in our previous post, the Top Ten Things to do in Seoul for Gamers, Koreans of all ages have been diving headfirst into gaming culture. Mostly focused on digital gaming like mobile and PC, the gaming industry has been growing at an annual rate of 4.3% (Statista). Although the most popular games by far are MMORPGs, we tried to diversify the list for all types of players to enjoy.  MapleStory  MapleStory - Source: maplestory.nexon.net  MapleStory has been around for years and only continues to be a huge favorite in Korea and around the world. An extremely social game, it sees players work to improve their own character’s skills while chatting, looting and even getting married to others. The 2D element gives the game an almost retro vibe, even though it has been updated many times, including the release of a sequel. Create your avatar, choose your class and find out how to fulfill your quest by defeating the Black Mage.   Ragnarok Online  Ragnark Online - Source: mmoculture.com  You guessed it, another tried and true MMORPG. Based on a comic of the same name by Lee Myung-jin, this 3D game features a constantly changing timeline that players must interact and adapt with within the specific world. The key part of the game is choosing the “job” of your character. With that choice come make-or-break strengths and weaknesses that can determine the gameplay for you. Starting at 13 but growing to 50 classes, the choice is daunting but crucial as your job can change as well. Whether you want to try out the newest sequel, the mobile version, or even watch the animated TV series, Ragnarok Online is definitely one to check out.   Blade & Soul  Blade and Soul - Source: www.bladeandsoul.com  Developed by one of the most notable studios in Korea, NCSOFT, this fantasy martial arts game was only released in Western countries 2 years ago, but had been out in Korea and Japan since 2012. A super renowned character customization system gives the game an update from the more traditional fighting style games. There are four playable races that reference the four Chinese Symbols of Azure Dragon, Vermillion Bird, Black Tortoise and White Tiger. Definitely a must for fans of combat-driven games.   ANIPANG  ANIPENG - Source: anipang-for-kakao.en.softonic.com  Finally a change of pace! ANIPANG is a mobile puzzle game, and also the first Korean game to reach 20 million downloads. Filled to the brim with squishy animal faces, this match-3 style game can be enjoyed alone or by competing with friends. Whether it’s killing time waiting for the bus or just wanting to beat that one tricky level, ANIPANG can be played anywhere at any time.   Lineage  Linage - Source: mmogames.com  Rounding out this list is Lineage, a video game series released in the 90s and still receiving sequels and spin-offs to this day. Taking you back to medieval times, this game is one of the most successful MMORPGs to date. The realistic siege warfare and constant lore updates makes it a fun and addictive way to pass the time. The mobile release of the game broke records and had fans eager to play, so don’t miss out. 
조회수 2101

Activation Function

Activation Function(활성함수)인공신경망을 공부하다보면 활성함수(activation function)라는 것을 만나게 됩니다. 대부분의 분들은 처음 공부를 시작할 때, 저와 마찬가지로 활성함수는 그냥 이런 거구나 하신 뒤에 넘어가고 있을 거라 생각합니다. 하지만 딥러닝을 좀더 공부하다보면 어떤 활성함수를 사용했는지, 혹은 사용하지 않았는지로 인해 다양한 문제가 발생하곤 합니다. 특히 요즘 핫한 deep neural network 에서는 활성함수가 어떤 것인가에 따라서 vanishing gradient 문제로 인해 학습의 정도가 달라지기도 합니다. 이러한 이유에서 이번 포스팅에서는 활성함수를 자세히 이해해보도록 하겠습니다.인공신경망이 사람의 신경구조를 모방하여 만들어졌다는 사실은 다들 알고 계실겁니다. 인공신경망의 가장 기본 개념은 단일 퍼셉트론에서 출발했습니다. 관련된 포스팅에서도 설명했지만 퍼셉트론은 여러 개의 신호가 들어오면 이를 조합하여 다음으로 신호를 보낼지 말지를 결정합니다(0 또는 1). 이것을 발전시킨 feed forward multiple layer neural network는 하나의 단일 뉴런에 여러 신호가 들어오면, 다음 뉴런에 보낼 신호의 강도를 결정하게 됩니다. 즉, 단일 퍼셉트론이 multi layer perceptron으로 발전해나가는 과정에서, 뉴런은 신호의 전달유무가 아닌 전달 강도를 정하게 되었습니다. 이때 전달하는 신호의 세기를 정하는 방법이 활성함수입니다.많은 분들은 대표적인 활성함수로 sigmoid를 떠올리실 것입니다. 활성함수의 개념을 잡기에는 이만큼 좋은 함수가 없기 때문입니다. 그럼 우선 활성함수의 가장 기본적인 개념을 sigmoid를 통해 알아보도록 하죠. 그 전에 여러분의 이해를 돕기 위해 로지스틱 회귀분석에 대해 먼저 알아보겠습니다.로지스틱 회귀분석(logistic regression)로지스틱 회귀분석은 generalized linear model입니다. 정확히 말하자면 generalized linear model이라는 큰 개념의 여러 케이스 중 하나라고 볼 수 있겠네요. 로지스틱 회귀분석의 목적은 독립변수의 선형결합으로 종속변수인 ‘어떠한 사건이 발생할 확률’을 알고자 하는 것입니다. 어렵죠..? 쉬운 예시를 하나 들어보겠습니다.우리는 어떠한 연구를 통해 1일 흡연량과 폐암 발생 여부의 관계를 알고싶습니다. 이때 가장 쉬운 방법은 1일 흡연량{x}과 폐암 발생확률{p(y)}이 선형 관련성이 있다고 보고, 선형 회귀 분석(linear regression)을 시행하는 것입니다. 그 결과, p(y)=0.02x+0.1<math>p(y)=0.02x+0.1</math> 이라는 식이 도출되었다고 생각해보죠. 이 식은 담배를 전혀 안 피우는 사람은 10%의 확률로 폐암에 걸리고, 하루에 담배를 1개비씩 더 피울 때마다 폐암에 걸릴 확률이 2% 증가한다는 의미입니다. 표면적으로 보았을 때는 꽤나 합리적으로 보입니다. 하지만 과연 이 식을 실제 예측에 활용해도 전혀 문제가 없을까요? 예상하셨겠지만, 그렇지 않습니다.담배는 한 갑에 20개비가 들어있고, 3갑이면 60개비가 들어있습니다. 따라서 하루에 담배를 3갑 피우는 사람은 0.02∗60+0.1=1.3<math>0.02∗60+0.1=1.3</math>, 즉 130%의 확률로 폐암에 걸린다는 결론이 도출됩니다. 이는 확률의 공리에 어긋나는 결론입니다. 따라서 과거의 수학자들은 선형이라는 이해 및 계산이 쉬운 방법을 그대로 유지하면서 확률의 공리에 어긋나지 않는 방법을 찾고자하였고, 다양한 방법들 중 가장 보편적으로 사용하게 된 방법이 로지스틱 함수를 연결함수로 사용한 로지스틱 회귀분석입니다.로지스틱 함수는 아래와 같이 생겼습니다.g(x)=ex1+ex<math>g(x)=ex1+ex</math>이것을 연결함수로 적용한 generalized linear model, 즉 logistic regression의 수식은 아래와 같은 형태가 됩니다.P(y|x)=eβx1+eβx<math>P(y|x)=eβx1+eβx</math>위 식을 이용하면 비로소 선형이라는 직관적인 성질을 띄면서, 결과값의 범위가 0~1로 제한되어 확률값의 예측에 사용할 수 있는 회귀식이 도출됩니다. 이 때, 위에 사용한 로지스틱 함수가 바로 우리가 활성함수로 사용하는 sigmoid function입니다. 따라서 sigmoid를 활성함수로 사용할 경우, 필연적으로 로지스틱 회귀분석과 관련이 있을 것이라고 예상할 수 있습니다. 둘 간의 관련성을 아래 그림을 통해 알아보겠습니다.여러분의 이해를 돕고자 hidden layer가 없는 가장 단순한 형태의 feed forward neural network 형태를 그려보았습니다. 위 그림을 수식으로 나타내볼까요?P(Y|X)=exp(∑2i=0wixi)1+exp(∑2i=0wixi)=11+exp(−∑2i=0wixi)<math>P(Y|X)=exp(∑i=02wixi)1+exp(∑i=02wixi)=11+exp(−∑i=02wixi)</math>즉, 위처럼 sigmoid를 활성함수로 사용한 간단한 neural network는 logistic regression과 일치합니다. 물론 계수(weight) 추정 방법은 통계학에서 기존에 행하던 방법과는 차이가 있지만, 결과적으론 비슷한 값이 추정될 것입니다. 우리는 이 그림을 통해 아래와 같은 직관을 얻을 수 있습니다.input과 weight를 곱해서 더하는 과정은 linear combination(선형 결합)이다.인공신경망의 학습은 각 뉴런에 곱해지는 ‘weight’라는 모수(parameter)를 추정(estimate)하는 과정이다.이제 눈치 채셨나요? Sigmoid를 활성함수로 사용하는 multi layer perceptron neural network의 hidden layer의 각 뉴런은 로지스틱 회귀분석을 하는 것과 정확히 일치합니다. 따라서 학습 과정에서 각 layer의 weight라는 모수를 학습을 통해 추정하는 것입니다.mlp 적용그럼 이제 위에서 배운 로지스틱 회귀분석을 mlp에 적용해보겠습니다. 우리는 단층 퍼셉트론 에서 아래와 같은 그림을 보았습니다.위처럼 선형으로 깔끔하게 분류가 가능한 문제는 활성함수가 계단함수인 단층 퍼셉트론으로도 충분히 해결할 수 있습니다. 하지만 아래와 같은 경우는 문제가 달라집니다.이러한 분류 문제는 선형으로는 불가능하며, 비선형적인 분류를 하여야 합니다. 이처럼 우리가 원하는 비선형의 분류를 하기 위하여 크게 두 가지가 필요합니다.1개 이상의 hidden layer(2개 이상의 뉴런을 포함하여야 함)비선형의 활성함수먼저 비선형의 활성함수가 필요한 이유부터 간단하게 생각해보겠습니다. 만약 활성함수가 비선형이 아니라면, 각 뉴런의 결과값은 선형결합의 선형결합이 됩니다. 따라서 아무리 multiple layer를 쌓는다고 하여도, 결과적으로 출력값은 입력값들의 선형결합이 됩니다. 즉, 층을 여러 개 쌓는 의미가 퇴색되는 것입니다.다음으로 hidden layer와 뉴런의 갯수에 대한 정의가 왜 필요한지 생각해보겠습니다. 위에서 언급하였듯이 logistic regression은 generalized linear model입니다. 여기서 ‘linear model’에 주목해주세요. 즉, logistic regression도 결국은 선형 모델이라는 것입니다. 왜일까요? Logistic regression을 이항분류 문제(결과의 범주가 0 또는 1)에 적용하여, 결과값이 특정값 이상이면 1로 분류한다고 생각해보겠습니다. 이것은 결국 기존의 단일 퍼셉트론에서 활성함수로 sigmoid를 사용한 뒤, 다시 계단함수를 적용한 것과 같습니다. 비록 우리가 sigmoid라는 비선형의 활성함수를 사용했지만, 로지스틱 함수의 지수를 풀어내면 결국 선형 결합의 결과값에 대한 분류이므로 우리가 원하는 비선형의 분류를 할 수 없습니다. 따라서 위와같은 문제를 해결하기 위하여, 비선형의 활성함수를 쓰되, 다수의 뉴런을 갖는 hidden layer를 사용하는 것입니다. 이 때, hidden layer의 뉴런 갯수가 늘어날 수록 좀더 비선형으로 데이터에 적합한 분류가 가능해지지만 overfitting 문제가 발생하게 됩니다. 따라서 hidden layer의 뉴런 갯수를 과제마다 적절히 지정해주는 것이 중요합니다.activation function의 종류마지막으로 activation function의 종류 및 특징에 대해 정리해보겠습니다.1. Sigmoid functionBy Qef (talk) - Created from scratch with gnuplot, Public Domain, Link<특징>수식 : σ(wx+b)=ewx+b1+ewx+b<math>σ(wx+b)=ewx+b1+ewx+b</math>범위 : (0,1)시그모이드 함수는 완전히 값을 전달하지 않거나(0) 혹은 완전히 전달한다(1)는 특성 때문에 실제 인체의 뉴런과 유사하다고 생각되어 널리 사용되었으나, 현재는 점차 사용하지 않는 추세입니다. 그 이유는 아래와 같습니다.Vanishing Gradient :sigmoid 함수는 뉴런의 활성화 값이 0 또는 1에 매우 가깝다면(saturate), 해당 편미분 값이 0에 매우 가까워지는 특성이 있습니다. 인공신경망의 back propagation에서 가장 일반적으로 사용되는 gradient descent의 경우 chain rule을 이용하는데, 이 과정에서 0에 매우 작은 값이 계속 곱해진다면 그 값은 0으로 점점 더 수렴합니다. 즉, 학습의 결과가 back propagation 과정에서 전달되지 못하고 이에 따라 weight 값의 조정이 되지 않습니다. 이것은 학습의 과정뿐만 아니라, 초기 weight 값을 임의로 줄 때에도 문제가 됩니다. f=σ(wx+b)<math>f=σ(wx+b)</math> 를 통해 확인해보죠. 만약 w의 값이 매우 커서 σ(wx+b)<math>σ(wx+b)</math>의 값이 1에 매우 가까워 진다면, weight값은 초기 값에서 크게 변하지 않고 학습이 되지 않을 것입니다. 그럼 우리의 신경망 모델의 정확성도 감소하겠죠. 이것이 vanishing gradient problem입니다.중심값이 0이 아니다 :Sigmoid function의 결과값은 그 중점이 0이 아니며, 모두 양수입니다. 이 경우 모수를 추정하는 학습이 어렵다는 단점이 있습니다. 하지만 이것은 다른 방식으로 모델 내에서 극복이 가능하기 때문에 vanishing gradient 에 비해 큰 문제는 아닙니다.2. tanh function<특징>수식 : tanh(x)=e2x−1e2x+1<math>tanh(x)=e2x−1e2x+1</math>범위 : (-1,1)tanh(hyperbolic tangent) function은 sigmoid 처럼 비선형 함수이지만 결과값의 범위가 -1부터 1이기 때문에 sigmoid와 달리 중심값이 0입니다. 따라서 sigmoid보다 optimazation이 빠르다는 장점이 있고, 항상 선호됩니다. 하지만 여전히 vanishing gradient 문제가 발생하기 때문에 대안이 등장하게 됩니다.3. Relu(Rectified Linear Unit)<특징>수식 : y=max(0,x)<math>y=max(0,x)</math>범위 : (0,∞<math>∞</math>)Relu는 위 그림처럼 선형그래프를 한 번 꺾은 형태입니다. 이 간단한 함수는 오랫동안 인공신경망의 발목을 잡던 vanishing gradient 문제를 해결했습니다. 하지만 여전히 장점과 단점이 존재합니다.장점기존의 sigmoid, tanh에 비해 converge되는 속도가 빠릅니다. 이것은 그래프의 형태가 선형이고, saturate problem이 발생하지 않기 때문으로 보여집니다.x값이 0을 기준으로 선형발현/미발현 이라는 간단한 형태이기 때문에 상대적으로 연산량이 많은 exponential을 사용하지 않아, 컴퓨터의 연산에 대한 부담을 줄여줍니다.단점“dying Relu problem”이 발생합니다. 만일 학습 과정에서 weight가 특정 뉴런이 activate되지 않도록 바뀐다면, 해당 뉴런을 지나는 gradient도 0이 됩니다. 따라서 training 과정에서 해당 뉴런이 한 번도 발현하지 않게 될 수도 있습니다. 심한 경우에는 네트워크 전체 뉴런의 40%가 죽어있는 경우도 발생한다고 합니다(출처 : http://cs231n.github.io/neural-networks-1/). 이것을 막기 위해서는 learning rate를 크지 않게 조절하는 것이 중요합니다. 또 다른 해결 방안으로는 leaky relu와 같은 activation function을 사용할 수도 있습니다.정리이번 포스팅을 통해 우리는 activation function이 무엇이고, 왜 필요한 것인지 알아보았습니다. 또한 어떠한 activation을 어떻게 사용해야하는지도 배웠습니다. 제가 위에 소개한 것 이외에도 다양한 activation function이 있으므로, 한 번쯤 찾아보며 공부해보시면 좋겠습니다.
조회수 2308

스타트업이 CTO를 찾는 법?

스타트업이 CTO를 찾는 법? 을 알고 계신 분에게 드리는 "질문"입니다. 이 글을 읽으시는 분들에게 부탁드리고 싶은 것은.. 1. 어디에 만나볼 엔지니어(개발자) 분들이 있으니 거기에 포스팅을 해보세요2. 엔지니어 들은 job을 찾을 때, 이런저런 고민을 하니.. 이런 포인트에서 조금 더 고민해보세요. 3. job 포스팅에는 이런저런 구체적인 내용들이 더 필요하니, 구체적으로 XX를 더 작성해보세요4. 이분 한번 만나보시겠어요? (소개 등등) 5. 공유를 해주셔도 좋습니다... 이런 고민을 함께 하시는 분들을 위해~등등의 조언을 댓글로 주셔도 좋고, 메일로 주셔도 좋고.. 아무튼 이 글은 조언을 구하고자 쓰는 글입니다. ^^;개발을 잘 모르는 스타트업 대표가 CTO를 모시는 방법은 어떤 것이 있을까요? ㅜㅜ대부분의 경우 co-founder 중, 엔지니어(engineer) 분이 CTO의 역할을 담당해주시는 것이 일반적인 경우로 보입니다. 하지만 서비스에서 engineer의 비중이 상대적으로 낮은 스타트업의 경우는 회사가 성장해 나감에 따라 function을 더 크게 만들어 나가는 경우도 있겠지요? 파펨도 그러한 회사 중에 하나입니다.지금까지는 할 수 있는 한 효율성을 따져가면서 최소한의 개발을 진행해왔지만, 이제는 조금 더 적극적으로 서비스를 고도화시켜야 할 때! 이기에 이제 좋은 분을 내부에 모셔야 하는데.. 우선 대표 입장에서의 고민을 한번 늘어놔 본다면.. 1) 개발을 거의 모르기 때문에 (새로 모셔야 할) 그분이 실력자 인지 아닌지 알 수가 없다는 불안감2) Ruby on Rails로 개발이 되어 있어, 이 언어에 능한 분을 찾는다는 것이 어렵다는 소문을 이미 많이 들음3) 엔지니어 분들이 선호하는 job 에 대한 구체적인 정보가 없음  반대로 job을 찾고 있는 엔지니어 분의 입장에서 상상력을 발휘해 본다면.. A) 잘 될 회사인지 아닌지 정확히 모르겠음 : 투자 몇 번 받은 것으로 스타트업 평가가 가능?B) 개발팀이 구성되어 있지 않아.. 당분간 나 혼자 full stack으로 일해야 함 : 내가 하나하나 다해야 함? C) 개발이 중심이지 않은 회사에서 일을 하는 게 적합할지? : 나의 커리어 차원에서 도움이 되는가? 위의 내용을 고려한다면, 100년 만의 개기일식이 일어나는 것과 같은 우연이 없다면 정말 만나기 어려운 인연이 아닐까?라는 생각이 듭니다. ㅜㅜ 그래도 어쩌겠습니까... 그런 인연을 찾아 나서야죠. 예전에는 엔지니어 한 분을 만나면, 리쿠르팅과 관계없이 다른 한 분을 소개 요청드리고, 또 그분에게서 다른 분을 소개받아서 계속해서 아는 분들의 영역을 넓혀가고자 노력도 해보았습니다. 그렇다면 파펨 대표가 생각하는 CTO는 어떤 분일까요? 현재의 파펨 구성원들과 아래의 일들을 함께 해나가 주실 분입니다. 1. 자체 커머스로써의 서비스 업그레이드 : 전체 팀과 함께 논의할 일 2. 알고리즘의 upagrade 반영 : 알고리즘 설계자(대표)와 함께 할 일3. 파펨 DB에서 추출할 수 있는 data를 바탕으로 마케팅 insight 발굴 : marketer와 함께 할 일4. 새로운 tool(예, GA보다 amplitude를 한번 사용해보자 등)을 소개하고 도입 이렇게 쓰면 컴퓨터 공학을 전공한 사람에게 저렇게 많은 것을 요청하는 당신은 경영학과 출신이니.. 재무, 회계, HR, 생산관리 모두 잘할 수 있는 사람인가요?라는 질문을 받을 것 같은 느낌이 들지만... ㅜㅜ 아무튼 어려운 리쿠르팅의 길을 떠나기 전에 머릿속에 생각나는 것들을 한번 써보았습니다.파펨에서 engineer를 찾습니다!! 파펨은? a. Ruby on Rails / AWS에서 서비스되고 있고, 나름 github에 히스토리 정리가 잘 되어 있고, 이전에 프리랜서로 개발에 도움을 주신 분이 체계적으로 정리해주셔서 나중에 열어보시면 뜨악하실 정도는 아닙니다. (라고 합니다. ^^;) b. 구체적인 연봉, job title 등은 상황별로 합리적인 논의를 할 준비가 되어 있습니다. C. 퓨쳐플레이와 아모레퍼시픽에서 투자를 유치하였습니다. #파펨 #스타트업 #창업가 #창업자 #마인드셋 #인사이트 #채용 #CTO #팀빌딩 #팀원
조회수 2443

Next.js 튜토리얼 5편: 라우트 마스킹

* 이 글은 Next.js의 공식 튜토리얼을 번역한 글입니다.** 오역 및 오탈자가 있을 수 있습니다. 발견하시면 제보해주세요!목차1편: 시작하기 2편: 페이지 이동 3편: 공유 컴포넌트4편: 동적 페이지5편: 라우트 마스킹 - 현재 글6편: 서버 사이드7편: 데이터 가져오기8편: 컴포넌트 스타일링9편: 배포하기개요이전 편에서는 쿼리 문자열을 이용하여 동적 페이지를 생성하는 법을 배웠습니다. 생성한 블로그 게시물 중 하나에 대한 링크는 다음과 같습니다:http://localhost:3000/post?title=Hello Next.js하지만 이 URL은 구립니다.다음과 같은 URL를 가지면 어떨까요? http://localhost:3000/p/hello-nextjs더 낫지 않나요?이번 편에서 이것을 구현할 예정입니다.설치이번 장에서는 간단한 Next.js 애플리케이션이 필요합니다. 다음의 샘플 애플리케이션을 다운받아주세요:아래의 명령어로 실행시킬 수 있습니다:이제 http://localhost:3000로 이동하여 애플리케이션에 접근할 수 있습니다.라우트 마스킹라우트 마스킹이라 불리는 Next.js의 특별한 기능을 사용할 예정입니다.기본적으로 애플리케이션에서 표시되는 실제 URL와 다른 URL이 브라우저에 표시됩니다.블로그 포스트 URL에 라우트 마스크를 추가해봅시다.pages/index.js에 다음과 같은 코드를 작성해주세요:다음의 코드 블럭을 살펴봅시다:<Link> 엘리먼트에서 "as"라는 또다른 prop를 사용하였습니다. 이는 브라우저에서 보여질 URL입니다. 애플리케이션에 표시되는 URL은 "href" prop에 지정되어 있습니다.첫 번째 블로그 포스트를 클릭하면 블로그 포스트로 이동할 것입니다.그 다음에 뒤로가기 버튼을 클릭하고 앞으로가기 버튼을 클릭해보세요. 무슨 일이 일어날까요?- 에러가 발생할 것이다- 인덱스 페이지로 돌아가고 포스트 페이지로 다시 이동할 것이다- 인덱스 페이지로 이동하지만 그 후에는 아무런 일도 일어나지 않을 것이다- 인덱스 페이지로 돌아가고 에러가 발생할 것이다히스토리 인식본 것처럼 라우트 마스킹은 브라우저 히스토리를 활용하여 잘 작동합니다. 해야 할 일은 링크에 "as" prop를 추가하는 것뿐입니다.새로고침하기home 페이지로 돌아가세요: http://localhost:3000/첫 번째 포스트 제목을 클릭하면 post 페이지로 이동합니다.브라우저를 새로고침하면 무슨 일이 일어날까요?- 예상대로 페이지가 첫 번째 포스트를 랜더링 할것이다- 페이지가 로드되지 않고 계속 로딩 중일 것이다- 500 에러가 발생할 것이다- 404 에러가 발생할 것이다 404서버에 불러올 페이지가 없기 때문에 404가 에러가 발생합니다. 서버는 p/hello-nextjs 페이지를 불러오려고 시도하지만 우리는 index.js와 post.js 두 개의 페이지밖에 없습니다.이 방법으로는 프로덕션으로 이 애플리케이션을 실행할 수 없습니다. 이 문제를 고쳐야 합니다.Next.js의 커스텀 서버 API는 이 문제를 해결할 수 있는 방법입니다.다음 편에서 이것을 사용하는 방법을 배울 예정입니다.#트레바리 #개발자 #안드로이드 #앱개발 #Next.js #백엔드 #인사이트 #경험공유
조회수 4360

자바스크립트 기초 문법 정리 Part 2 - 객체

지난 Part 1 포스팅에 이어 자바스크립트 기초 문법에 대해 정리해보았습니다. 이번 포스팅에서는 여러 객체와 그 객체에서 제공하는 각 메서드에 대해 정리하였습니다. 다루는 객체의 여러 메서드에 대해 정리하였기 때문에 전 포스팅처럼 간략하지는 않지만 이번 포스팅을 저장해 두고 자바스크립트로 개발하면서 필요할 때마다 참고하여 보기에는 좋을 것 같습니다. 다만, 메서드 사용 예의 코드는 넣지 않았으니 예제 부분이 필요하다면 필히 공식 문서를 참고해주세요. 익히는 것 자체도 공식 문서를 통하여 보는 것이 가장 좋지만 혹여 영어에 취약하신 분이라면 이 포스팅을 참고하는 것도 괜찮을 것 같습니다. :)내장 객체브라우저의 자바스크립트 엔진에 내장된 객체. String/Date/Array/Nath/RegExp Object 등이 있음.날짜 객체 DateDate 객체 생성new Date()new Date(milliseconds)new Date(dateString)new Date(year, month, day, hours, minutes, seconds, milliseconds)Date Get 메서드getDate() - 일 정보를 가져옴.getDay() - 요일 정보를 가져옴. 0(일요일)-6(토요일)getFullYear - 연도 정보를 가져옴. (yyyy)getHours() - 시간 정보를 가져옴.getMilliseconds() - 밀리초 정보를 가져옴. 0-999 (1/1000 초의 단위)getMinutes() - 분 정보를 가져옴.getMonth() - 월 정보를 가져옴. 현재 월에서 -1한 값으로 옴.getSeconds() - 초 정보를 가져옴.getTime() - 1970년 1월 1일부터 경과된 시간을 밀리초로 가져옴.Date Set 메서드setDate() - 일 정보를 설정.setFullYear() - 연도 정보를 설정. 원한다면 월과 일 정보도 설정할 수 있다.setHours() - 시간 정보를 설정.setMillseconds() - 밀리초 정보를 설정.setMinutes() - 분 정보를 설정.setSeconds() - 초 정보를 설정.setTime() - 1970년 1월 1일부터 경과된 시간을 밀리초로 설정.기타 Date 메서드now() - 1970년 1월 1일부터 지금까지의 밀리초를 반환.parse() - 날짜 형태의 문자열을 변환하여 1970년 1월 1일부터 입력한 날짜까지의 밀리초를 반환.toString() - Date 객체를 문자열로 변환.toJSON() - Date 객체를 JSON 데이터로 변환.valueOf() - Date 객체를 밀리초로 반환.숫자 객체 NumberNumber 생성var num = 1;      var num2 = new Number(1);Number 객체의 속성MAX_VALUE - 표현 가능한 가장 큰 수.MIN_VALUE - 표현 가능한 가장 작은 수.POSITIVE_INFINITY - 무한대 수 표기.NEGATIVE_INFINITY - 음의 무한대 수 표기.NaN - 숫자가 아닌 경우 표기.Number 객체 메서드toExponential(n) - 자수 표기법으로 소수점 n자리만큼 문자형 데이터로 반환.toFixed(n) - 소수점 n자리만큼 반올림하여 문자형 데이터로 반환.toPrecision(n) - 유효 숫자 n의 개수만큼 반올림하여 문자형 데이터로 반환.toString() - 숫자형 데이터를 문자형 데이터로 반환.valueOf() - 객체의 원래 값을 반환.parseInt(값) - 데이터를 정수로 변환하여 반환.parseFloat(값) - 데이터를 실수로 변환하여 반환.수학 객체 MathMath 메서드 및 상수Math.abs(숫자) - 숫자의 절댓값을 반환.Math.max(숫자1, 숫자2, 숫자3) - 숫자 중 최댓값을 반환.Math.min(숫자1, 숫자2, 숫자3) - 숫자 중 최솟값을 반환.Math.pow(숫자, 제곱값) - 숫자의 거듭제곱한 값을 반환.Math.random() - 0~1 사이의 난수를 반환.Math.round(숫자) - 소수점 첫째 자리에서 반올림하여 정수를 반환.Math.ceil(숫자) - 소수점 첫째 자리에서 무조건 올림에서 정수를 반환.Math.floor(숫자) - 소수점 첫째 자리에서 무조건 내림해서 정수를 반환.Math.sqrt(숫자) - 숫자의 제곱근 값을 반환.Math.PI - 원주율 상수를 반환.배열 객체 ArrayArray 생성var array = new Array();array[0] = 1;array[1] = 2;var array2 = new Array(1, "temp", true);var array3 = [1, true, "문자열도 가능"];Array 객체의 메서드 및 속성join(연결문자) - 배열 객체에 데이터를 연결 문자 기준으로 1개의 문자형 데이터로 반환.reverse() - 배열 객체에 데이터의 순서를 거꾸로 바꾼 후 반환.sort() - 배열 객체에 데이터를 오름차순으로 정렬.slice(index1, index2) - 배열 객체에 데이터 중 원하는 인덱스 구간만큼 잘라서 배열 객체로 가져옴.splice() - 배열 객체에 지정 데이터를 삭제하고 그 구간에 새 데이터를 삽입할 수 있음.concat() - 2개의 배열 객체를 하나로 결합.pop() - 배열에 저장된 데이터 중 마지막 인덱스에 저장된 데이터 삭제.push(new data) - 배열 객체에 마지막 인덱스에 새 데이터를 삽입.shift() - 배열 객체에 저장된 데이터 중 첫 번째 인덱스에 저장된 데이터를 삭제.unshift(new data) - 배열 객체의 가장 앞의 인덱스에 새 데이터를 삽입.length - 배열에 저장된 총 데이터의 개수를 반환.문자 객체 StringString 생성var str = "hello";      var str2 = new String("hi");String 객체 메서드 및 속성charAt(index) - 문자열에서 인덱스 번호에 해당하는 문자 반환.indexOf("찾을 문자") - 문자열에서 왼쪽부터 찾을 문자와 일치하는 문자를 찾아 최초로 일치하는 문자의 인덱스 번호를 반환. 찾는 문자가 없으면 -1 반환.lastIndexOf("찾을 문자") - indexOf와 동일하나 문자열의 오른쪽부터 찾음.match("찾을 문자") - indexOf와 동일하나 찾는 문자가 없으면 null을 반환.replace("바꿀 문자", "새 문자") - 문자열에서 왼쪽부터 바꿀 문자와 일치하는 문자를 찾아 최초로 찾은 문자를 새 문자로 치환.search("찾을 문자") - 문자열 왼쪽부터 찾을 문자와 일치하는 문자를 찾아 최초로 일치하는 인덱스 번호를 반환.slice(a, b) - a개의 문자를 자르고 b번째 이후에 문자를 자른 후 남은 문자를 반환.substring(a, b) - a 인덱스부터 b 인덱스 이전 구간의 문자를 반환.substr(a, 문자 개수) - 문자열에 a 인덱스부터 지정한 문자 개수만큼 문자열을 반환.split("문자") - 지정한 문자를 기준으로 문자 데이터를 나누어 배열에 저장하여 반환.toLowerCase() - 문자열에서 영문 대문자를 모두 소문자로 바꿈.toUpperCase() - 문자열에서 영문 소문자를 모두 대문자로 바꿈.length - 문자열에서 문자의 개수를 반환.concat("새로운 문자") - 문자열에 새로운 문자열을 결합.charCodeAt("찾을 문자") - 찾을 문자의 아스키 코드 값을 반환.fromCharCode(아스키 코드 값) - 아스키 코드 값에 해당하는 문자를 반환.trim() - 문자의 앞 또는 뒤에 공백 문자열을 삭제.브라우저 객체 모델(BOM)브라우저에 내장된 객체. window 객체브라우저 객체의 최상위 객체.window 객체 메서드open("url 경로", "창 이름", "옵션 설정") - 새 창을 열 때 사용.- open() 메서드 옵션 설정: width/height/left/top/location/status/scrollbars/tollbarsalert("메세지") - 경고 창을 띄움.prompt("질의 내용", "기본 답변") - 질의응답 창을 띄움.confirm("질의 내용") - 확인/취소 창을 띄움.- 확인 클릭시 true 반환, 취소 클릭시 false 반환.moveTo(x 위치값, y 위치값) - 창의 위치를 이동시킬 때 사용.resizeTo(너빗값, 높잇값) - 창의 크기를 변경시킬 때 사용.setInterval("스크립트 실행문", 시간 간격) - 일정 간격으로 반복하여 실행문을 실행시킬 때 사용.clearIntervar(참조 변수) - 참조 변수에 참조되어 있는 setInterval() 삭제.setTimeout("스크립트 실행문", 시간 간격) - 일정 간격으로 한 번만 실행문을 실행시킬 때 사용.clearTimeout(참조 변수) - 참조 변수에 참조되어 있던 setTimeout() 삭제.screen 객체사용자의 모니터 정보를 제공하는 객체.screen 객체 속성width/height/availWidth/availHeight/colorDepth(사용자 모니터가 표현 가능한 컬러 bit)location 객체사용자 브라우저의 주소 창에 url에 대한 정보와 새로 고침 기능을 제공하는 객체.location 객체 속성 및 메서드href - 주소 영역에 참조 주소를 설정하거나 URL 반환.hash - URL의 해시값을 반환.hostname - URL의 호스트 이름을 설정하거나 반환.host - URL의 호스트 이름과 포트 번호를 반환.port - URL의 포트 번호를 반환.protocol - URL의 프로토콜을 반환.search - URL의 쿼리를 반환.reload() - 새로 고침.history 객체사용자가 방문한 사이트 중 이전에 방문한 사이트와 다음 방문한 사이트로 다시 돌아갈 수 있는 속성과 메서드를 제공하는 객체.history 메서드 및 속성back() - 이전 방문한 페이지로 이동.forward() - 다음 방문한 페이지로 이동.go(이동 숫자) - 이동 숫자만큼의 페이지로 이동. 음의 값이면 이전 페이지로 이동.length - 방문 기록에 저장된 목록의 개수 반환.navigator 객체현재 방문자가 사용하는 브라우저 정보와 운영체제의 정보를 제공하는 객체.navigator 속성appCodeName - 방문자의 브라우저 코드명을 반환.appName - 방문자의 브라우저 이름 반환.appVersion - 방문자의 브라우저 버전 정보를 반환.language - 방문자의 브라우저 사용 언어를 반환.product - 방문자의 브라우저 사용 엔진 이름을 반환.platform - 방문자의 브라우저를 실행하는 운영체제를 반환.userAgent - 방문자의 브라우저와 운영체제의 종합 정보를 제공.문자 객체 모델(DOM)HTML 문서의 구조.선택자직접 선택자직접 문서에서 요소를 선택함. (id/class/폼 명/요소 명 등)document.getElementById("아이디 명") - 아이디를 이용해 요소를 선택.document.getElmentsByTagName("요소 명") - 요소의 이름을 이용해 요소를 선택.document.formName.inputName - 폼 요소에 name 속성을 이용해 요소를 선택.인접 관계 선택자직접 선택자를 사용해 선택해 온 문서 객체를 기준으로 가까이에 있는 요소를 선택함. (parentNode/childeNodes 등)parentNode - 선택한 요소의 부모 요소를 선택.childNodes - 선택한 요소의 모든 자식 요소를 선택. 선택한 모든 요소가 저장됨.firstChild - 선택한 요소의 첫 번째 자식 요소만 선택.previousSibling - 선택한 요소의 이전에 오는 형제 요소만 선택.nextSibling - 선택한 요소의 다음에 오는 형제 요소만 선택.문서 객체 이벤트 핸들러 적용하기onclick - 선택한 요소를 클릭했을 때 이벤트 발생.onmousevoer - 선택한 요소에 마우스를 올렸을 때 이벤트 발생.onmouseout - 선택한 요소에 마우스가 벗어났을 때 이벤트 발생.submit - 선택한 폼에 전송이 일어났을 떄 이벤트 발생.버튼document.getElementById("btn").onclick = function() {    alert("welcome");}일단은 참고하는 책을 기준으로하여 정리해보았는데 후에 시간이 될 때마다 공식 문서를 참고하여 번역한다는 생각으로 보다 세부적인 사항을 정리해도 좋을 것 같다는 생각이 드네요. 우선적으로는 빠르게 함수와 이벤트에 대해 배우고 객체에 대한 더 자세한 사항을 정리하도록 하겠습니다. 다음 포스팅은 자바스크립트의 함수와 이벤트에 대해 다룰 예정입니다!참고문헌:Do it! 자바스크립트+제이쿼리 입문 - 정인용JavaScript 튜토리얼 문서 (http://www.w3schools.com/js/default.asp)티스토리 블로그와 동시에 포스팅을 진행하고 있습니다.http://madeitwantit.tistory.com#트레바리 #개발자 #안드로이드 #앱개발 #Node.js #백엔드 #인사이트 #경험공유

기업문화 엿볼 때, 더팀스

로그인

/