스토리 홈

인터뷰

피드

뉴스

조회수 4956

업무 생산성을 높이기 위해 해야할 것과 하지 말아야 할 것

어제 문득 든 생각인데, 우리의 인생도 자연 현상과 많이 닮은 것 같다. 노를 저으면 물살을 가로지르며 나아간다. 왼팔, 오른팔 힘의 강도, 회전속도, 박자 비중에 따라 방향이 달라진다. 노를 놓으면 보트는 목적성을 잃은채 둥둥 떠다니며 정체 상태로 있는다.  하고자 하는 의지가 강하고 철저한 계획이 있다 하더라도 모두에게 공평하게 주어진 시간은 한정되어 있고, 체력 또한, 기존 체력 이상으로 무리할 수 없다.  능력도 마찬가지다. 지금 내가 갖고 있는 능력의 범위란 게 있다.    사업운영 하면서 겪은 시행착오는 결과적으론 경험이 되지만, 많은 기회비용 또한 발생한다.  경영학원론에서 생산성을 운운할 수 밖에 없는 이유가 여기에 있다. 누구나 다 알지만, 한번쯤 짚고 넘어가야 할 것들이 있는 것 같아 정리를 해보았다. DO 해야할 것 시간분배하기. 흘러가는 시간이 제일 아깝다.  사무실에서 8시간 기껏해야 오래앉으면 12시간이라 쳐도 그사이 전화응대하고 미팅하러 나가고 왔다갔다 오가는 시간도 있고 어떤 업무를 할 때 제일 시간낭비를 하는지 파악하고 그것을 최대한 자동화하면 좋다.  예를 들어,  고객들을 일일이 대응하는 시간이 오래걸릴 때에는 회사 전화 통화연결음을 ARS로 하는 것도 한 방법이다.   반복적인 업무는 루틴으로 짜기.  사실 나는 다이어리를 꼼꼼히 쓰는 편은 아니다.  대략적인 약속, 미팅은 TimeTree 라는 앱을 쓰고,  그날그날 해야할 업무목록은 GoogleDoc 에 적는다.  만약, 여러분의 경우 종이 다이어리에 꼼꼼히 오늘 할일, 일주일 할일을 적는 편이라면, 이제는 스마트폰에서 제공하는 일정앱 사용을 조심스럽게 권장한다.  요즘에 앱스토어나 구글 플레이스토어가면 무궁무진한 시간표, 일정관리 앱이 나와있다.  괜찮은 무료앱도 많고 거기에 1$언저리만 좀더 추가하면 꽤 오래 쓸만한 비서같은 앱도 있으니 한번 살펴보면 좋을 것 같다.  오전에 제일 하기싫은 일, 흥미없는 일부터 하기. 하기 싫은 일을 오전에 하는게 생산성을 제일 높여준다고 한다.반전이지 않은가.  굳이 아침에 할 필요 없다고 생각이 든다면,  다른 시간대를 고르면 된다.  가령, 점심먹고 직후 라던가,개개인차가 있겠지만, 본인이 생각하기에 제일 일잘되는 시간대가 최적의 시간대가 아닐까. Love what you do.  좋아하는 말 중의 하나.  지금 하고 있는 일이 본인이 정말 열정있게 하는 일이라고 생각하고 일하는 것.일생에서 이 일을 두번 다시 하지 못할 것처럼. 일단 시작해라.그냥 시작해라.  해야할 일은 산더미고 뭐부터 해야할지 모르겠다면, 일단 아무 일이나 시작해보자. 쉴땐 쉬어야 한다.정기적으로, 규칙적으로 쉬는게 중요하다.  장기휴가가 아닌 이상, 짧게는 몇분이더라도 휴식을 취하는게 좋다. 하루 업무시간중에서 몇시부터 몇시몇분까지는 10분 15분정도 휴식을 취하고 (나의 경우, 3시반에서 4시 사이) 다음 일을 보는 것을 권유한다.DONT 하지말아야할 것 계속되는 연속야근은 비추. 야근을 할 수 밖에 없는 상황이기에 집에 못들어가는 것은 대한민국 국민 누구나 안다. 하지만,야근을 하면 좋지 않은 이유는 그다음날, 분명히 업무에 지장이 간다.  피로는 누적되기 때문이다.  이 글을 읽으시는 분이 예비창업가이거나 스타트업이 대표라면, 야근권장은 비추하는 신문화를!  혼자서 모든것을 다하려고 하지말기.  내가 못하는 분야는 인정하고, 인지하고 전문작업자에게 아웃소싱, 외주를 주는게 비용으로나 시간절감으로나 훨씬 이득이다.   아니면 말단 직원에게 일을 주거나 원격사무보조해주는 프리랜서도 있다. 자잘한 일이나, 디자인, 영상 등 전문스킬을 요하는 작업은 맡기고, 여러분은 여러분 사업이나 업무에 있어서 더 중요한 일을 하는게 좋다.  멀티태스킹은 지양하기. 최적의 생산성을 위해선 시간대비 한가지 일에 몰두하고 하나 해치우고 그다음 일처리를 하는게 낫다. 모든 전화문의에 일일이 답변하지 말기.걸려오는 문의전화를 필터할 필요가 있다.  정말 도움이 필요한 건을 제외하고는, 본인이 직접 할 수 있는데 귀찮거나, 사이트 고객센터에 보면 답변이 나와있는데 굳이 전화로 묻는 경우가 상당하다.모든 전화에 친절히 일일이 대응할 필요는 없다.   개인 연락처를 알려주면 그다음부터는 회사전화가 아니라 개인폰으로 연락이 온다.   직급이 높거나 사장/대표라면 전화업무는 경영지원 담당자에게 넘기거나 위에서 말했듯 ARS전화연결음을 제작하거나 카카오톡 옐로아이디를 개설해서 카톡으로 상담을 받거나 고객센터 자주묻는질문 코너를 편리하게 할 필요가 있다.  현재 갖고있는 스킬에 안주하지말기. 타이핑 속도 늘리는 연습을 하는 것도 좋다. 타이핑 속도가 빠르면 보통 비례해서 가독력 속도도 빨라지는 편이니까.  사실, 타이핑은 한 예로 든거고, 뭐든지 항상 현재의 내 상태보다 더 나아지려고 노력하다보면 어느새 나의 업무 생산성은 이전보다 더 많은 양의 업무를 동일 시간대비 해치울 수 있을 것이다.  #넷뱅 #업무효율 #생산성 #인사이트 #성장 #조언
조회수 768

블록체인 진짜 하나도 모르는 디자이너의 독학일기(1)

독학을 시작했습니다. 스터디를 가려고 했는데 수많은 전문용어들이 제 영혼을 피폐하게 만드는 바람에 정신건강이 염려되었거든요. 포토샵도 혼자 배웠으니 이것도 못할까! 라고 자신있게 책을 폈는데 못할 것 같습니다.......그래도 산 책 값이 아까우니 읽고 공부한 내용들을 하나하나 정리해보고자 합니당! 블록체인 전문가님들이 혹시 이 글을 보신다면 노잼과 지루함내지는 유치함을 느끼실 수 있으니 엄빠미소로 지켜봐주시면 감사하겠습니다. 잘못된 부분이 있다면 바로 잡아주세요!!글을 쓰면서 5가지 원칙을 지킬겁니다.1. 꼭 써야하는 고유명사가 아닌 이상 어려운 단어는 쓰지 않습니다. 중학생 정도가 이해될 수준이길 제발 바랍니다...저는 블록체인을 이제 이틀 째 공부하고 있거든요.2. 가급적 팩트체크된 내용만 쓸겁니다.3. 제대로 공부하려면 경제사, IT기술, 코딩 등등..수많은 요소가 복잡하게 들어가지만 여기선 꼭 필요한 쏘옥 뽑아서 얘기할 겁니다. 4. 짧게 쓸 겁니다.5. 가끔 쓸 겁니다.(자주 쓰기 힘든 주제임..)시작합니당 :)블록체인이 왜 태어났는지 얜 뭔지부터 알아야 할 것 같아요. 그러자면 시간을 조금 되돌려서 우리는 어떻게 사고파는 경제활동을 해왔는지 살펴볼께요.1. 아주 오래전 = 기억하기종이란게 나타나기도 전 우리는 사과5개를 빨간집에서 해가 질 무렵에 씨앗10개와 교환했다. 는 걸 기억해야 했어요. 문제는 서로가 잘못 기억하거나 한 쪽이 다르게 우겨버리면 할 말이 없다는 거죠..철저히 신뢰와 기억에 의존한 거래였어요.2. 오래 전 = 나무나 가죽에 새기기원래 사람은 두 발로 직립보행 하기 전부터도 그림을 좋아했어요. 동굴에도 그리고 돌에도 그리고, 나무나 땅에도 곧잘 그림을 그렸죠. 뭔가 주고받는 물품이 많아지면서 기억하기가 힘들어지자, 이젠 가죽이나 나무 등등에 갯수를 남기기 시작했죠. 문제점은 그 가죽이나 나무가 훼손되거나 도난당하면 증명할 방법이 없다는 거에요.'동쪽 언덕 마을에서 온 또박이가 가죽3개를 사갔다.'3. 조금 오래전 = 종이에 적기(단식부기)종이가 발명되고 아라비아 숫자와 알파벳, 한글, 한자, 인도어 등등이 발달하기 시작하면서 문서를 남길 수 있게 되었어요!!! 문서를 남긴다는 건 굉장했죠!!!오랜 시간이 지나도 기록들을 잘 보관할 수 있었어요!! 거래를 할 때에도 수입과 지출을 한 번에 (가계부처럼) 적으면서 작은 종이에 많은 내용을 남길 수 있었답니다. 하지만..여전히 문제는 사람이었어요. 이를 위조하거나 없애버리면...? 또는 불에 다 타서 없어지면??4. 얼마 전 = 적은 걸 나눠가지기(복식부기)그래서 서로 함께 같은 내용을 공유하기로 했어요. 너 하나 나 하나. 그리고 그 과정을 감시하는 회계사. 이런 과정은 우리 조선시대에서도 아주 엄격했답니다. 특히 계문화가 발달했던 우리나라는 다양한 장부를 기록했는데 '용하기'라는 계의 장부기재는 정말 엄격한 원칙이 있었답니다!!1. 임시장부를 2부 작성해요. 이 때 회계담당자 이외 심지어 2명이 더 감시하고 있어요.2. 기재를 시작해요.3. 계원들이 다 모여야 하고 적은 내용을 크게 읽어요. 이 때 의심스러운게 있으면 이의제기나 수정을 해요.4. 계장과 두 명의 감시원이 있는 상태에서 최종수정해요. 그리고 계장이 서명해요.5. 중복된 장부가 있는지 확인하고 새 장부를 넣어 보관해요.엄청나죠???..놀라운 건 현재의 블록체인의 원리도 위와 비슷해요!! 다만 사람이 일일이 적고 감시하는 게 아니라 명령어에 의해 챡챡 처리되는 것 뿐이랄까요. 하지만 이것도 결국 '물질' 이다 보니....화재나 전쟁으로 인해 소실되어 버리면 그걸로 끝이었어요.5. 요즘 = 기관이나 중앙에 맡기기왕정체제가 아니라 민주주의와 시장경제가 도입되면서 은행이나 보험사, 카드사와 같이 경제활동을 담당하는 기업과 중앙기관이 생겨나기 시작했어요! 엄청나게 거대한 정보를 크으으은 서버나 금고에 보관할 수 있었어요. 그것은 영원해보이고 사람들은 오래도록 보관할 수 있다고 생각하니 관심을 끄기 시작했죠. 내 돈은 금고에 잘 있을 거니까요.하지만, 자본주의는 그런게 아니었어요. 은행은 내 돈을 다른 사람에게 대출로 빌려주고 그 이자로 돈을 벌어요. 그리고 다른 사람이 갚은 돈으로 다시 내 예금을 채우죠. 졸라 돌려막기인 거에요. 사람들이 끊임없이 돈을 빌리고 다시 갚을 수 있게 다양한 상품들을 만들어요. 이 방식은 굉장히 효율적이고 아무 문제가 없을 것 같이 보였어요.하지만, 해킹을 당했어요.은행을 털렸어요서브프라임 모지기론 사태처럼, 무리한 상품의 실패는 수백개의 기업을 무너뜨렸어요. 수많은 사람들의 돈이 한 순간에 날아갔어요.서버가 먹통이 되어 거래가 안되는 경우도 있어요.지진 등의 천재지변이 나면 내 기록은 사라지고 말아요.단순히 큰 사옥을 지닌 곳이니까 영원불멸할 것 같았던 중앙기관도 하루 아침에 무너질 수 있단 사실을 우린 수 차례 경험했어요. 그럼에도 우린 뭘 어떻게 해야할 지 몰랐어요. 우리가 할 수 있는 건 사고가 터지면 변호사를 써서 소송을 하는 것 뿐이었어요. 우린 은행의 상품이 정확히 어떤건지, 보험약관이 뭔지... 카드사는 어떤 원리로 움직이는지...내 세금은 어떻게 쓰이고 있는지...우리 돈이 어떻게 거래되고 내 돈을 가지고 그들이 무엇을 하는지 하나도 몰라요. 그냥 속수무책으로 그들만 믿고 있는 거예요. 6. 블록체인의 탄생 = 모두가 장부를 가질 수 있게그래서 생각해봤어요. 한 곳에 모여있으니 문제가 생긴다면, 쪼개면 되지 않을까? 은행 한 곳을 터는 것은 쉽지만 1,000여명을 한꺼번에 터는 것은 불가능할테니까. 계모임에서 쓰던 그 장부를 엄청나게 많이 만들어서 모두가 가지면 어떨까? 누굴 못 믿거나 위조하거나 털리거나 불나서 사라질 일이 없을 거 아냐?? 라는 생각을 말이죠. 그런데 친구가 질문을 하네요!!친구 : 그런데 어떻게??나 : 인터넷이 있잖아!! 내가 온라인상에서 거래하면 그 기록이 남잖아~ 그걸 모두가 공유하는거지! 친구 : 모두가 누군데?나 : 응 그건 이제부터 모아야해!!친구 : 그럼 어쨌든 모인 사람들에게 모두 공유하면 내가 어제 김치한포기 시킨것도 다른 사람이 알게 되는거야??나 : 아니지;;; 니가 뭘 시켰는지 그딴 건 관심없어..그냥 얼마 거래를 언제 몇시몇분몇초에 어떻게 했는가만 기록에 남는거야! 그리고 다른 사람은 그걸 직접 눈으로 볼 수 있는 게 아냐.생각해봐. 넌 브런치 로그인한 기록을 눈으로 다 볼 수 있어? 며칠 몇시에 얼마나 로그인했는지 알 방법이 없지? 하지만 그 기록이 있을까 없을까? 그렇지, 반드시 있다구. 범죄수사할때도 그러자나. 우리 화면에는 시간/내용밖엔 안뜨는 문자메시지지만, 실제로 서버에는 발신위치, 수신위치, 번호정보 등등이 모두 숨겨져 있잖아. 또 하나! 너가 네이버에서 틴트를 검색하면 나중에 페북에서 틴트광고가 뜨지 않아? 우리의 방문기록이나 클릭한 기록들이 모두 남아있기 때문이야.이렇게 우리가 눈으로 보는 화면 뒤에는 수많은 정보들이 컴퓨터만의 전기신호로 저장되어 있어. 우리가 말하는 장부도 이런 식으로 저장되어 있는거라구.  물론 필요하다면 그걸 화면으로 띄울 수 있는 명령어를 만들 수도 있겠지.친구 : 그건 이해했어, 내가 직접 볼 순 없지만 마치 사이트 방문기록처럼 어딘가에 거래내역이 다 남아있다는 얘기지?... 그런데 아까 지금부터 모아야 한다는 사람들은 어떻게 모으는거야??나 : 그건!!..바로!!!! 다음에 설명해줄께!!또 공부해서 돌아올께용!!
조회수 1161

우리 운영팀에 봄이 오기를!

1. apollo stack 과 recompose 를 사용하니 별도로 redux, state 관리를 안해줘도 되서 크게 당황중. 신경쓰지 않아도 문제없이 잘 돌아간다.2. recompose 의 API들을 활용하니 대부분의 컴포넌트가 stateless 로 작성할 수 있었다. 몇 안되는 Component들도 생명주기 함수는 드물다.3. bind를 계속 묶어주는 것도 autoBind decorator 를 이용하면 this.foo = this.foo.bind(this); 도 안하고 쓸 수 있다.4. grapql dataloader 부분은 아직도 헷갈린다. 어떻게 구조화해야 batch call을 제대로 할 수 있을지..5. 뭐니뭐니해도 제일 어려운건 schema 정의하기다. 특히 DB 구조상 도메인 표현이 제대로 안되어있는데 graphql schema 로 최대한 도메인에 가깝게 표현하려다보니 쉽지가 않다.6. query, mutate를 받아주는 serverless QL 과 subscription 을 유지하는 serverQL, DB connection Pool을 유지하는 API server와 그 앞단에 redis로 서버를 구성하고 싶다. 별도의 pubsub 서비스가 필요할지 redis 로 할 수 있을지 궁금.7. 도메인 표현을 위해 더 많은 db 스키마가 필요한데 이건 scaphold 나 graphCool 의 무료 할당량을 이용해서 빠르게 구현할 예정. 보통 설계가 누락된 도메인 모델은 backoffice 를 위해 구현이 필요한 경우가 많아서 요청량이 적어 충분히 버틸 수 있어보임.8. 플레이팅 운영팀에 봄이 오기를.#플레이팅 #개발 #개발자 #개발일지 #인사이트 #경험공유
조회수 1809

모바일 데이터 분석의 시작: AARRR (해적지표)

모바일 분석의 중요성은 익히 들어 알고 있지만, 모바일 데이터를 실제 비즈니스에 어떻게 활용해야 하는지 모르겠다고 말씀하시는 고객 분들이 많으신데요. 모바일 분석 툴을 이용하여 아무리 많은 데이터를 쌓더라도, 그것이 실제 비즈니스 목표 달성에 도움이 되지 못한다면 무용지물일 것입니다.오늘은 유명한 분석 프레임워크 AARRR에 따라 비즈니스 목표를 달성하기 위한 모바일 데이터 분석 활용법을 알아보겠습니다.* AARRR: 미국의 스타트업 엑셀러레이터 500 Startups의 창립자 데이브 맥클루어(Dave McClure)가 개발한 분석 프레임워크. 스타트업이 시장 진입 단계부터 서비스/제품을 홍보하고 사용자를 확보하기 위해 단계별로 집중해야 할 지표를 정리한 성과측정모델. (1) Acquisition (사용자 획득)  모바일 앱을 출시하고 마케팅을 진행할 때, 어떤 광고 채널/캠페인이 가장 효과적인지 파악하기 위해서 어떤 데이터들이 필요할까요? 흔히 가장 많은 앱 설치수나 방문수, 페이지뷰를 일으킨 광고 채널/캠페인이 효과적이라고 생각할 수 있는데요. 하지만 데이비드 맥클루어에 따르면 해당 비즈니스에 의미 있는 이벤트 수를 가장 많이 발생시킨 채널/캠페인에 예산을 집중해야 한다고 합니다. 예를 들어, 특정 채널에서 유입된 사용자들의 앱 설치수나 방문수가 높다고 하더라도 비즈니스에 핵심적인 회원가입수, 주문수가 낮다면 효과적인 채널이라고 볼 수 없겠죠. 이 때문에 와이즈트래커에서는 마케팅 채널/캠페인별 앱설치수, 방문수, 페이지뷰 뿐 아니라 비즈니스별 맞춤 성과(회원가입수, 예약수, 리뷰수, 공유수 등) 전환 데이터를 제공합니다.→ 해당 데이터에서 Facebook과 Adwords 광고를 통한 App 설치수는 비슷하지만 주문수(페이스북: 205, 구글: 3)는 크게 차이가 납니다. 이러한 경우, Adwords 보다는 Facebook에 예산을 집중해야 합니다.  이 뿐 아니라 마케팅 채널 별로 앱 재사용율 및 삭제율을 Retention 리포트를 통해 제공하기 때문에 어떤 마케팅 채널이 고객 획득과 활성화에 효과적인지 파악할 수 있습니다.→ Facebook으로 유입된 사용자의 Retention 리포트입니다. 앱 설치 이후에 재사용율보다 삭제율이 높아 개선이 필요한 상황입니다.  마지막으로 위의 내용을 통해 가장 효과적인 채널을 확인했다면, 그 채널로 유입된 사용자들이 어떤 사람인지 파악해 보다 효과적인 타겟 마케팅을 진행할 수 있습니다. 와이즈트래커의 다차원 세그먼트 기능을 이용하면 해당 채널에 유입된 사용자의 성별, 연령, 사용국가, 기기 플랫폼 등을 파악할 수 있습니다.→ WISETRACKER 다차원 세그먼트 설정 화면. 광고를 통해 유입된 사용자들을 설정한 세그먼트에 따라 일차원 또는 다차원으로 나누어 볼 수 있습니다. 위와 같이 기기 플랫폼(iOS vs Android)과 성별로 다차원 세그먼트를 설정하면 아래와 같은 데이터가 나타납니다.   (2) ACTIVATION (사용자 활성화)사용자들이 앱을 설치했다 하더라도 첫 방문 시 사용 경험이 나쁘다면 앱을 삭제하거나 다시 방문하지 않을 확률이 높습니다. 우리 서비스가 유저들에게 만족스러운 경험을 제공하는지 확인하기 위해서는 아래와 같은 데이터를 확인해야 합니다. 우선 화면 이동경로 리포트를 통해 사용자들이 첫 화면 이후에 기획 의도 처럼 문제없이 이동하고 있는지를 확인할 수 있습니다. 예를 들어, 메인화면 이후에 서비스/상품 페이지가 아닌 엉뚱한 화면으로 이동하는 비율이 높다면 앱 UI/UX 개선이 필요하겠죠.→ WISETRACKER 화면 이동경로 리포트 또한 전환 퍼널 분석을 통해 각 화면 경로 별 전환율과 이탈율을 분석할 수 있습니다. 4단계로 이루어진 회원가입 전환 경로 분석 시,  2단계에서 이탈률이 높다면 해당 단계에서 고객에게 너무 많은 정보를 기입하게 하거나 민감한 개인 정보를 요구하는 것일 수도 있습니다.→ WISETRACKER 전환 시나리오 화면. 회원가입의 2단계(가입인증)에서 이탈율이 38.8%로 가장 높기 때문에 해당 단계를 간소화 하기 위한 작업이 필요합니다.   위의 정보들을 통해 우리 서비스가 고객들에게 긍정적인 사용자 경험을 주고 있는지 지속적으로 확인하고 서비스를 개선해나가는 작업이 필요합니다. (3) RETENTION (사용자 유지)사용자가 지속적으로 앱을 방문한다는 것은 그 서비스에 관심이 많다는 의미이므로 추후 구매 전환으로 이어질 가능성이 높습니다. 와이즈트래커의 Retention 리포트를 통해 사용자들이 앱을 지속적으로 사용하는지, 그렇지 않고 1~2일 내에 삭제하는지를 확인 할 수 있습니다. 만일 앱 설치수는 꾸준히 늘어나는데, 앱 유지율 및 삭제율 또한 점차 높아진다면 처음 방문자들에게 앱 서비스가 크게 매력적이게 다가오지 않는다는 의미로 볼 수 있겠죠.→ WISETRACKER의 Retention Report. 1월 12일부터 15일까지 앱 설치수는 크게 늘어나고 있지만, 설치 다음 날(+1d) 앱 삭제율도 증가하고 있기 때문에 소비자들이 지속적으로 앱을 사용하도록 서비스 개선이 필요한 상황입니다.     이 뿐 아니라 방문 횟수, 방문 분포 리포트를 통해 사용자들이 어떤 빈도로 앱에 방문하는지 확인할 수 있습니다. 매일 들어오는 사용자의 수가 가장 많다면 서비스의 충성고객이 많다는 의미로 볼 수 있습니다. 반대로 15-30일 주기로 들어오는 사용자가 많다면, 이들의 방문을 촉진할 수 있는 이벤트나 프로모션을 푸시 메시지로 안내하는 방안을 생각해 볼 수 있습니다.→ WISETRACKER의 방문간격 Report. 방문간격이 0일(매일 방문)인 사용자 비율이 높은 것으로 보아 충성고객 비율이 높은 것을 알 수 있습니다.  앱 사용자 분석을 통해 고객의 특성을 파악했다면 특정 사용자 그룹을 대상으로 타겟 마케팅을 진행할 수 있습니다. WISETRACKER의 오디언스 타겟팅을 이용하여 데모그래픽, 행태정보, 관심사에 따라 사용자의 ADID/IDFA를 추출하고 해당 사용자에게만 광고를 노출하거나 푸시 메시지를 보내는 것이 가능합니다.→ WISETRACKER의 Audience Targeting 설정 페이지. 위와 같은 설정으로 1월에 앱을 설치한 iOS 그룹의 IDFA만 추출하여 광고 노출 및 푸시 메시지 전송에 이용할 수 있습니다.  또한 전송된 푸시 메시지의 응답률, 실행수, 전환분석이 가능하기 때문에 사용자 방문수와 전환수를 높이는 효과적인 메시지를 파악할 수 있습니다.→ WISETRACKER 푸시 메시지 분석 리포트 (4) REVENUE (매출)매출 향상을 위해 어떤 사용자들이 매출에 많은 기여를 하는지를 파악해 유사 사용자들을 대상으로 마케팅을 진행하는 방법도 있습니다.와이즈트래커의 주문/매출액 리포트에 다차원 세그먼트 기능을 적용하여 주문 고객들의 성별, 연령대, 방문유형, 유입 채널들을 파악해 비즈니스의 가치 고객군을 파악할 수 있습니다.→ 주문/매출액 리포트를 회원 연령대로 세그먼트를 나누면, 아래와 같이 주문한 사용자들의 연령대에 따른 주문 데이터를 알 수 있습니다.  또한 고객들의 구매 횟수 분포 및 구매 행동 패턴을 파악하여 앱 내 프로모션 진행 시 활용할 수 있습니다. 예를 들어, 구매 주기가 7일인 사용자가 다수라면, 해당 주기에 맞춰 할인 쿠폰을 푸시로 보내거나 신상품을 소개하는 이메일을 보낼 수 있겠죠마지막으로 매출 측면에서 가장 인기가 많은 상품과 컨텐츠를 파악해 앱 내 관련 컨텐츠/상품을 빠르게 업데이트하고 종류를 늘려간다면 같은 기간 내 보다 높은 매출을 기대할 수 있습니다.→ WISETRACKER 상품별 주문/매출액 리포트. (5) REFERRAL (추천)비즈니스의 빠른 성장을 위해서는 제품/서비스에 무심한 고객 10,000명을 만드는 것보다 충성도가 높은 고객 100명을 만드는 것이 더 효과적이라고 하죠. 왜냐하면 그 100명은 자신들의 친구와 지인들에게 서비스를 적극적으로 홍보하기 때문에, 장기적인 네트워크 효과로 인해 10만명, 100만명의 고객을 획득할 잠재력을 가지게 됩니다.우리 비즈니스가 사용자에게 매력적으로 느껴지도록 하는 것이 가장 중요하고, 그 다음엔 사용자들이 온라인에 쉽게 공유할 수 있도록 서비스를 개선해야 합니다.만약 SNS 공유수가 낮다면, 이들에게 적절한 보상을 제공하는 마케팅 방안도 생각해 볼 수 있습니다.마무리하며AARRR 단계별 중요 지표를 데이터로 파악하고, 개선점을 찾아 빠르게 업데이트한다면 비즈니스 목표를 보다 수월하게 달성해 나갈 수 있습니다.아직까지 많은 기업들이 추측이나 감을 통해 중요한 의사결정을 내리고 있습니다. 와이즈트래커의 목표는 이러한 고객들에게 데이터를 기반으로 보다 현명한 의사결정을 내릴 수 있도록 돕는 것입니다. 비즈니스 목표를 보다 빠르고 쉽고 달성하고 싶다면, 오늘부터 우리 비즈니스에 핵심적인 지표들부터 데이터 분석을 시작해보는 것이 어떨까요?
조회수 46750

'영업'은 여러분이 생각하는 그런 일이 아닙니다

 우리 모두는 '영업직'이라는 말을 들으면 반사적으로 어떤 이미지를 떠올린다. 무더운 날씨에 넥타이를 동여매고 한 손에 자켓을 든 채 땀범벅이 되어 돌아다니고, 실적 압박에 마음고생하며, 무슨 일만 터졌다 하면 가서 고개숙여 사과하는 사람의 이미지. 사실 그렇게 틀린 건 아니다. 고급 외제차에 핸드메이드 스리피스 수트를 입고 환한 미소를 짓는 영업사원은 없으니까. 주변에 그런 영업사원이 있다면, 집에 옥장판이 필요하지 않는 한 멀리하는 게 좋다. 명함에 보석 이름이 써있거나 할 가능성이 높다.·대충 이런 느낌이고, 실제로 이런 느낌이다. 그렇기 때문에, 대부분 구직자들은 영업직군을 상당히 기피하는 경향이 있다. 사실 한국에서 '영업'이라는 단어가 휴대폰을 팔거나, 정수기를 팔거나, 보험을 팔거나...하여간 고객에게 찾아가 뭘 팔아야 영업이라는 인식이 있다. 물론 그게 아주 중요한 역할임에는 틀림없지만, 사실 꼭 그렇지만은 않다. 그래서 오늘은 영업이 무엇인가를 설명해보려 한다.1. 기업의 손과 발 A라는 회사가 있다. 뛰어난 기술력으로 기존 시장에 대파란을 불러일으킬 제품을 만들었다. 광고도 끝내주게 뽑았으니 이제 팔기만 하면 된다. A사 사장은 떼부자가 될 꿈에 젖어 주문 결제 목록을 확인했다. 하지만 주문 건수는 0건이었다. A사는 영업부가 없었기 때문이다. 아무리 좋은 것을 만들더라도, 그것이 왜 좋은 지 고객과 얼굴을 맞대고 설명할 사람이 없다면 아무런 의미가 없다. 이제 막 출시된 제품을 놓고 고객에게 먼저 연락이 와서 '제발 우리에게 이 물건을 팔아주십시오!'라고 말하는 일 따위는 절대로 일어나지 않는다. 아무리 뛰어난 기술과 제품도 제 스스로 구매자를 찾아가 돈과 바꿔오진 않기 때문이다. 이것이 뭐가 얼마나 어디에 좋은 지, 어떤 효과를 낼 수 있는 지 설명할 수 없다면 어떤 제품도, 어떤 서비스도 팔리지 않는다. 기술 영업이라는 직군이 생긴 이유도 바로 이것이다. 세상에는 생각보다 팔아야 할 것들이 많고, 그것들을 팔기 위해서는 영업사원의 부지런한 노력이 필요하다. 영업은 여러분이 생각하는 그 이상으로 중요한 직군이다. 머리로 아무리 좋은 아이디어를 떠올리더라도, 실제로 이행할 손과 발이 있어야 의미가 있는 것이다. ·반짝이는 아이디어에는 금손이 필요하다.2. 사과하는 기계가 아니라 기업의 얼굴이다 기획자, 마케터, 디자이너, 개발자, 경영지원팀....이런 직군은 사과할 일이 거의 없다. 있어도 회사 내부적인 일을 해결하기 위한 것이 대부분이다. 개발자나 디자이너가 고객에게 가서 머리숙여 사과하는 광경을 본 적이 있는가? 자기 회사에서 그런 광경을 본 사람이 있다면 당장 도망치라고 말하고 싶다. 다음 차례는 당신이 될 테니까. 내가 하지도 않은 일을 가지고 누군가에게 사과하러 간다는 건 분명 즐거운 일은 아니다. 잘못은 다른 사람이 했는데, 왜 가서 굽신거리는 건 나인가. 당연히 불합리한 일이다. 그러나 제품이나 서비스를 팔기만 해서는 기업이 제대로 돌아가지 않는다. 사후지원과 고객만족 관리도 영업이 하는 중요한 일 중 하나이다. CS부서를 따로 둘 정도로 규모가 큰 기업이라도, 어지간한 일은 영업사원 선에서 해결이 된다. 영업사원에게 단정하고 정돈된 옷차림을 요구하는 것도 기업의 얼굴로서 해줘야 할 일이 있기 때문이다. 실제로 증권사 시절 겪은 일이다. 나의 고객 중 한 명이 고령으로 세상을 떠났다. 상당한 자산가였고, 잘 찾아오지 않는 자식들이 있었다. 그리고 그들은 고객이 생전에 구매한 채권을 가지고 시비를 걸기 시작했다. '앞으로 살 날이 몇 년이나 남았다고 10년 만기 채권을 사게 한 거냐' '노인에게 이런 걸 팔다니 제정신이냐' 등등, 온갖 매도의 말이 전화상으로 울려퍼졌다. 기록을 찾아보니, 그 채권을 사고싶다고 먼저 제안해 온 건 그 고객이었다. 일단은 검은 넥타이를 매고 장례식장으로 향했다. 사실 금융회사 영업직으로 일하게 된다면 심심찮게 보는 장면이긴 하지만, 재산 분할을 놓고 가족들이 아귀처럼 서로를 물어뜯는 광경은 썩 보기 좋은 일은 아니다. 일단 가자마자 멱살을 쥐어잡히기도 했고. 일본에서는 사망 사실을 인지한 순간 증권사가 고객의 모든 계좌를 동결시키고 상속과 재산분할에 대한 협의가 끝날 때 까지 아무 것도 할 수 없게 만든다. 그들은 바로 그게 불만이었던 것이다. 담담하게 설명을 시작했다. 일단 망인이 그 채권을 사겠다고 한 것은 채권 발행 주체가 신용도가 매우 높은 기업이었고, 은행 이자율과 비교해서 상당히 높은 수익을 얻을 수 있기 때문이었으며, 현재 계좌가 동결된 상태이지만 상속과 재산 분할에 대한 합의가 끝나는 대로 합의된 비율에 따라 각 상속자의 계좌로 이관될 것이다. 연로한 분에게 10년 만기 채권을 팔게 된 점은 윤리규칙상 아무런 문제가 되는 일은 아니나, 가족들에게 불편을 끼쳐 매우 죄송하다. 그리고 나는 고객이 타계하기 전 나에게 감사의 의미로 써주었던 손편지를 꺼내 가족들에게 건넸다. '제게도 할머니 같은 분이셨습니다.' 이 한 마디로 모든 불만은 사라졌다. 그 날 제일 슬퍼하던 건 가족들이 아니라 오히려 나였을지도 모르겠다. 만약 CS부서에서 이 일을 전화로 해결하려 했다면 FINMAC의 중재까지 받아야 하는 일이 되었을 것이다. 비록 사는 사람과 파는 사람으로서 관계를 맺고 있지만, 실제로 얼굴을 마주보고 대화를 나눈다는 것의 힘은 생각보다 강력하다. 영업사원은 편의점 직원이 아니다. 말 한 마디 없이 물건을 받고 돈을 내기 위해 영업사원을 부르는 사람은 없다. 자연스레 주변 얘기도 하고, 궁금한 것에 대해 물어보고, 앞으로의 경제 상황이 어떻게 돌아갈 지 대화를 나누다 보면, 싫더라도 유대감이라는 것이 생긴다. 그리고 그 관계는 굉장히 다양한 곳에서, 생각지 못하게 활용되기도 한다. 사과는 아무나 할 수 있는 게 아니다. 오로지 기업의 얼굴로 활약하는 영업직만이 할 수 있는 일이다.3. 대부분의 영업사원은 실적의 노예가 아니다 특히 보험이나 정수기, 카드처럼 단기적인 실적에 집중하는 회사에서 이런 일이 많다. 물론 증권사도 마찬가지지만, 화이트보드에 이름이나 1과, 2과, 3과 하는 식으로 부서를 죽 써놓고, 그래프를 그리거나 숫자를 써놓거나 하며 독려라는 이름의 압박을 넣는다. 일본에서는 이런 할당량을 '노르마(Norma)'라고 하는데, 증권사 중에서는 노무라 증권이 사람을 개미핥기처럼 훑어내기로 유명하다. 오죽하면 노르마 증권이라고 하는 별명도 있을 정도로. 여기서, 여러분이 흔히 떠올리는 대기업에 그런 영업사원의 이미지가 있는 지 한 번 생각해보자. 그리고 그 회사들에 영업부가 있는지 생각해보자. 물론 내부적으로 실적의 압박이 있는 건 어쩔 수 없는 일이다. 어떤 기업도 '이만큼이면 많이 벌었지 뭘'하면서 만족하지 않는다. 기업의 최전선에서 활동한다는 건, 탐욕의 최전선에서 움직이고 있다는 것과 다르지 않은 말이다. 그 탐욕을 온 몸으로 받아내는 일이 쉬울 리는 없다. 하지만 카드사나 보험사 영업직처럼 사람을 쥐어짜내는 건 생각보다 그리 흔하지 않다. 이런 곳은 애초에 위촉직이니 계약직이니 하면서 자기네 사원으로도 안 쳐준다. 동료 내지는 같은 그룹의 소속원으로서의 유대감조차 필요없다는 뜻이다. 오히려 일반적인 기업의 영업사원은 만화 '미생'에 가깝다. 회사에 필요한 거래를 위해 밤을 새며 일하기도 하고, 전국을 돌며 쪽잠을 자기도 하지만 만화 속 인물들이 괴로워하는 건 일과 실적이 아니라 사람과 직장 내 파벌 같은 것들이 원인이다. ·현실의 많은 영업사원은 이쪽에 더 가깝다.4. 모든 부서의 교집합 회사에서, 제품이나 서비스를 만들 때는 다양한 과정을 거친다. 지금 보고 있는 더 팀스 서비스를 예로 들자면, 기획파트에서 생각한 기획안이 백엔드 개발자에게 넘어가 기능적인 기반을 짜고, 디자이너가 디자인을 하면, 프론트엔드 개발자가 실제로 어떻게 나타낼 것인가를 구현한다. 마케팅파트에서는 이 기획에 대한 브랜딩이나 마케팅 방법을 생각하고, 그렇게 모든 사람들이 만들어 낸 서비스를 내가 가져다 영업하고 있다. 영업을 하기 위해서는 그 과정의 모든 것을 알면 알수록 좋다. 현장에서 무리한 요구를 하거나 흰구름 잡는 소리를 해도 대응이 가능하기 때문이다. 그래서 모든 부서의 교집합이라고 할 수 있다. 우리는 기술영업, 제품영업 식으로 굳이 분류를 나누지만, 모든 영업은 사실 하나다. 제품을 판다고 해서 기술을 모를 순 없다. 하다못해 정수기를 팔래도 이 정수기가 뭐가 좋은 지 알아야 하는 것이다. 여러 사람들이 힘겹게 만든 것을 그저 팔기만 하면 되는 일이지만, '그저' 팔기만 하기 위해서도 상당히 많은 노력이 필요하다. 그래서 영업현장과 동떨어진 기획안은 반드시 망하고(안 팔아주니까), 기획의도를 무시한 영업은 나중에 큰 문제에 휘말린다(대충 파니까). 기업의 모든 부서가 쥐어짜낸 정수를 머릿속에 담고, 다른 사람 앞에서 퍼포먼스를 하는 것이다. 그래서 난 영업을 기업의 종합예술이라고 생각한다.·말하자면 이런 느낌이다.5. 스타트업의 영업 대부분의 스타트업은 영업을 크게 중요하다고 여기지 않는 것 같다. 사실 크게 틀린 일은 아니다. 영업부를 두어가면서 뭘 팔 정도면 스타트업 수준은 아니지 않을까. 하지만 영업에 힘을 쏟는 걸 터부시하는 듯한 느낌을 가끔 받을 때가 있는데, 이건 확실히 틀렸다. 현장에서 영업사원으로 일하던 사람의 관점에서 말하는 것이지만, 스타트업 업계에서는 영업을 '낡은 관습'이라고 생각하는 것 같은 느낌을 받는다. 굳이 우리가 만든 서비스를 돌아다니면서 팔지 않아도, 정말 좋은 것이니까 누군가 사줄 것이라는 믿음이 있는 것 같다. 온라인이나 기타 마케팅 채널은 충분히 활용하고 있으니까. 사실 처음 스타트업에서 일하기 시작할 때, 초반 2개월 정도는 '스타트업은 샤이한 사람들만 하는 건가?'하는 의문이 들 정도였다. 전혀 그렇지 않다. 굳이 영업부나 영업팀을 둘 필요까진 없더라도, 반드시 누군가는 그 직무를 소화해야 한다. 회사의 대표나 마케팅 팀이 겸업하는 형태로라도, 영업은 무조건 필요한 것이다. 좋은 마케팅 수단을 이용해서 이미지나 브랜드를 알리는 것 역시 필수적인 일이다. 하지만 좋은 마케팅 수단은 영업직군이 해야 할 일을 줄여줄 순 있어도 완전히 대체할 순 없다. 현장의 사람들이 느끼는 것들을 체크하고, 직접 발로 뛰며 브랜드를 알리는 것 만큼은 꼭 필요하다. 여차할 때 전화 걸어 '어 그거 어떻게 되고 있어요?'같은 질문을 걸 수 있는 사람은 있어야 하지 않는가. 나의 경우도, 부족하나마 기획 회의에 참여하기도 하고, CS업무를 맡거나, 경영지원 업무를 동시에 하면서 영업 직무를 수행하고 있다. 아직까지는 영업파트로서의 일이 크게 필요하지 않지만, 그래도 사람이 있고 없고는 다를 것이라고 생각하고 있다. 외연 확장이 중요한 만큼, 전담해서 할 사람도 필요할 것이다.·스타트업의 영업부서는 배우자 같다. 어릴때는 있으면 좋고, 없어도 크게 아쉬울 것은 없다.그리고 나이가 들면 그 좋은 점을 알게 된다. 영업에 대해서 죽 말했지만, 결론은 여러분이 생각하는 것처럼 무작정 힘들고, 짜증나고, 실적 압박에 목이 조여오는 그런 직군은 아니라는 것이다. 만약 그랬다면 다른 직군보다 돈을 많이 줘서 사람을 끌어모았거나, 아예 다른 직무로 대체했을 것이다. 영업부가 없는 회사를 본 적 있는가? 가장 흔하다는 것은 가장 필요하다는 것과 같은 말이다. 어느 정도 규모 이상에서,  영업사원이 필요없는 회사를 난 한 번도 본 적이 없다. 누구나가 구한다는 것은 누구나가 필요로 한다는 것이다. 물론 독특하고 더 재미있을 법한 직군은 세상에 많다. 하지만 영업도 나름의 재미와 보람이 있다. 이 재미와 보람을 느끼는 법에 대해서는 다음에 쓰려고 한다. 개발자, 디자이너, 기획, 마케팅...잠깐 생각해도 세상엔 수많은 직군이 있다. 그리고 세상의 모든 일은 노동력을 제공하고 대가를 받는다는 공통점을 가지고 있다. 노동은 분명 신성하지만, 즐겁고 행복한 것은 아니다. 그래서 노동을 하면 돈을 받는 것이다. 영업이 힘든 만큼 다른 직군도 저마다의 힘든 점이 있다. 바꾸어 말하면, 영업은 다른 직군이 힘든 만큼 힘든 일이다. 세상에 합법적으로 편하게 버는 돈은 복권밖에 없다. 여러분이 다른 직군을 알아보고 생각하는 만큼, 영업직군에 대해서도 진지하게 고려하는 시간을 가졌으면 좋겠다.#더팀스 #THETEAMS #영업 #인사이트 #경험공유 #직무분석
조회수 9926

파이썬의 시간대에 대해 알아보기(datetime.timezone)

안녕하세요. 스포카 크리에이터 김두리입니다.  스포카는 많은 프로덕트에서 국제화 서비스를 제공하고 있습니다. 그래서 시간대와 시간을 제대로 정확하게 처리하는 것은 중요합니다. 하지만 파이썬의 datetime.datetime은 날짜(datetime.date)와 시각(datetime.time)의 정보를 담고 있고, 시간대(datetime.timezone)의 정보는 담거나 담지 않을 수도 있으므로 헷갈리는 부분이 존재합니다.     시간을 처리할 때 시간대는 왜 중요할까요? 시간대가 명시되지 않은 시각은 충분한 정보를 내포하고 있지 않습니다. 저는 얼마 전, Google Calendar API를 이용하여 작업할 때 골치 아픈 일을 겪었습니다. 오늘의 일정을 불러오고 싶어서 오늘 0시~24시로 데이터를 요청했지만, 계속해서 결괏값에 다음 날의 일정도 포함되어서 반환되었습니다.   왜 다음날 일정도 포함되었던 걸까요? 아래와 같은 코드를 작성하여 Google Calendar API에 요청했습니다.   today = datetime.date.today() from_ = datetime.datetime(today.year, today.month, today.day, 0, 0, 0) to = datetime.datetime(today.year, today.month, today.day, 23, 59, 59) events = get_events_from_google_calendar(from_, to)   몇 시간 동안 머리를 싸매고 코드를 한 줄 한 줄 따져가며 고민을 했습니다. 결국, 제가 요청한 시각에 시간대가 지정되어 있지 않아 get_events_from_google_calendar() 함수 내부에서 from_과 to가 의도하지 않은 시간대의 시각으로 인식되어서 발생했던 문제라는 것을 알게 되었습니다.  # 원래 의도했던 시간대: 대한민국 시간대(KST)에서 오늘 0시 0분 0초 KST = datetime.timezone(datetime.timedelta(hours=9)) from1 = datetime.datetime(today.year, today.month, today.day, 0, 0, 0, tzinfo=KST) # get_events_from_google_calendar()가 받아들인 시간대: UTC 시간대에서 오늘 0시 0분 0초 from2 = datetime.datetime(today.year, today.month, today.day, 0, 0, 0, tzinfo=datetime.timezone.utc)   위 예제에서 from2 - from1를 하게 되면 timedelta(hours=9)가 계산됩니다. 우리가 원했던 것은 KST 기준 오늘 0시부터의 일정이었지만, Google Calendar API에서는 시간대를 UTC로 취급하여 KST 기준 오늘 9시부터 다음날 9시까지의 일정을 불러왔던 것입니다.  이렇듯 시간 관련 작업을 할 때 시간대에 대해 제대로 알고 있지 않으면 의도치 않게 많은 시간을 소모하게 될 수도 있습니다.  오늘은 제가 파이썬으로 시간대 관련 처리를 하며 모았던 정보를 정리하여 공유하고자 글을 작성하게 되었습니다.  시간대  나라 또는 지역마다 살아가는 시각이 다르기 때문에 시간대에 따른 편차가 존재합니다. 이 차이가 피부로 잘 와닿지 않은 채 살아가더라도 캘린더 API나 국제화 서비스 준비 등등 시간과 관련된 작업을 진행하다 보면 시간대 문제에 직면하게 됩니다.  시간대는 영국의 그리니치 천문대(본초 자오선, 경도 0도)를 기준으로 지역에 따른 시간의 차이, 다시 말해 지구의 자전에 따른 지역 사이에 생기는 낮과 밤의 차이를 인위적으로 조정하기 위해 고안된 시간의 구분 선을 일컫는다. 시간대는 협정 세계시(UTC)를 기준으로 한 상대적인 차이로 나타낸다.     UTC에 대한 더 자세한 내용은 여기를 참고해주세요.   시간대에 대한 더 자세한 내용은 여기를 참고해주세요.   파이썬의 datetime.datetime.now()는 실행 환경의 시간대에 따라서 시각을 표시합니다.  2019-01-01 00:00:00 +09:00에 시간대가 Asia/Seoul로 설정된 제 랩탑에서 현재 시각을 가지고 오면, 아래와 같은 시각이 표시됩니다.  >>> print(datetime.datetime.now()) 2019-01-01 00:00:00.000000   그런데, 같은 시각에 Asia/Taipei로 설정된 랩탑에서는 현재 시각이 아래와 같이 표시됩니다.  >>> print(datetime.datetime.now()) 2018-12-31 23:00:00.000000  위의 예제처럼 시간대에 따라 시각이 다를 수 있다는 것을 알 수 있습니다.  나라별 시간대 비교해보기  UTC를 기준으로 시간이 빠르면 +시차, 시간이 느리면 -시차로 표시합니다.                                                                                                                                시간대나라코드UTC-5미국(동부)ESTUTC영국GMTUTC+8대만TWUTC+9대한민국KSTUTC+9일본JSTUTC+10오스트레일리아(동부)AEST     나라별 시간대 차이에 대한 더 자세한 내용은 여기를 참고해주세요.   시간대를 명확히 표시하지 않은 시각은 혼동을 일으킬 수 있습니다. 예를 들어서, 서울에 살고 있는 점주가 2019년 1월 1일 0시 0분에 방문한 고객을 알고 싶어 한다고 가정해봅시다. 이 데이터를 파이썬으로 표현하면 아래와 같이 적을 수 있습니다.  KST = datetime.timezone(datetime.timedelta(hours=9)) korea_1_1 = datetime.datetime(2019, 1, 1, 0, 0, 0, tzinfo=KST)   만약, 대만에 사는 점주가 이를 요청했다면 아래와 같이 적을 수 있습니다.  TW = datetime.timezone(datetime.timedelta(hours=8)) taipei_1_1 = datetime.datetime(2019, 1, 1, 0, 0, 0, tzinfo=TW)   위 예제에서 보이는 것 같이 대한민국과 대만에 있는 점주가 같은 시각을 요청했더라도, 시간대(KST/TW)에 따라서 별도로 처리해야 합니다.  assert korea_1_1 != taipei_1_1 assert taipei_1_1 - korea_1_1 == datetime.timedelta(hours=1) # 같은 시각이지만 시간대에 따라서 시간차가 있습니다.   그렇기 때문에 시간대가 표시되어 있지 않은 2019년 1월 1일이라는 정보만으로는 정확한 시각을 알 수 없습니다.  naive_1_1 = datetime.datetime(2019, 1, 1, 0, 0, 0) assert korea_1_1 != naive_1_1 assert taipei_1_1 != naive_1_1   이런 상황을 해결하기 위해 시각은 어떤 한 시각을 기준으로 하여 그 차이가 표시되어야 합니다. 그 기준으로 정한 것이 UTC입니다. 대한민국은 UTC를 기준으로 아홉시간 빠르기 때문에 korea_1_1의 시각을 UTC 시간대로 표현하면 2018-12-31 15:00:00+00:00입니다. 대만은 UTC를 기준으로 여덟시간 빠르기 때문에 taipei_1_1의 시각을 UTC 시간대로 표현하면 2018-12-31 16:00:00+00:00입니다. 위의 시각은 각각 대한민국(2019-01-01 00:00:00+09:00), 대만(2019-01-01 00:00:00+08:00)으로 표시할 수 있습니다. 이렇게 시간대와 같이 표시하면 혼란 없이 정상적으로 처리할 수 있습니다.  datetime  datetime은 파이썬에서 기본으로 제공하는 표준 라이브러리로, 간단하거나 복잡한 방식으로 날짜와 시각을 조작하기 위한 클래스를 제공합니다.  The datetime module supplies classes for manipulating dates and times in both simple and complex ways.  datetime은 시간대 포함 여부에 따라서 naive datetime, aware datetime 두 가지로 나눕니다.  naive datetime / aware datetime  datetime의 타입을 알아봅시다. 파이썬에서 시간 관련 연산을 하다 보면 종종 아래와 같은 에러 문구를 만날 수 있습니다.  >>> a = datetime.datetime.now() >>> b = datetime.datetime.now(datetime.timezone.utc) >>> a - b Traceback (most recent call last): File "", line 1, in TypeError: can't subtract offset-naive and offset-aware datetimes      naive datetime : naive datetime 객체는 그 자체만으로 시간대를 찾을 수 있는 충분한 정보를 포함하지 않습니다. (e.g. datetime.datetime(2019, 2, 15, 4, 58, 4, 114979))   aware datetime(timezone-aware) : 시간대를 포함합니다. (e.g.datetime.datetime(2019, 2, 15, 4, 58, 4, 114979, tzinfo=)) aware datetime 객체는 자신의 시각 정보를 다른 aware datetime 객체와 상대적인 값으로 조정할 수 있도록 시간대나 일광 절약 시간 정책 혹은 적용 가능한 알고리즘 정보를 담고 있습니다.   tzinfo는 UTC, 시간대 이름 및 DST 오프셋에서 로컬 시간의 오프셋을 나타내는 방법을 담고 있습니다. 더 자세한 내용은 공식 문서를 확인해주세요.  naive datetime은 어느 시간대를 기준으로 하는 시각인지 모호하므로 aware datetime을 이용하는 것을 권장합니다.  직접 확인해보기  준비한 몇 가지 코드를 보며 확인해봅시다. naive datetime과 aware datetime의 차이를 확인하고, 시간대 지정 방법에 대한 내용을 다룹니다.  개발환경     Python 3.7   pytz   여기서는 datetime을 쉽게 다루기 위해 pytz 라이브러리를 사용합니다. pytz는 아래와 같은 장점이 있습니다.    시간대를 시간차가 아닌 사람이 알아보기 쉬운 지역 이름으로 비교적 쉽게 설정할 수 있습니다.   원하는 시간대의 aware datetime으로 변경해주는 localize() 메소드를 제공합니다.   pytz 사용에 앞서, pytz가 제공하는 시간대 식별자를 확인하시려면 다음을 따라 해주세요. import pytz for tz in pytz.all_timezones: print(tz)  혹은 여기를 참고하셔도 좋습니다.  naive datetime  naive datetime은 날짜와 시각만을 갖습니다.  import datetime datetime.datetime.utcnow() # UTC 기준 naive datetime : datetime.datetime(2019, 2, 15, 4, 54, 29, 281594) datetime.datetime.now() # 실행 환경 시간대 기준 naive datetime : datetime.datetime(2019, 2, 15, 13, 54, 32, 939155)   aware datetime naive datetime과 달리 aware datetime은 시간대 정보(tzinfo) 도 갖습니다. import datetime from pytz import utc utc.localize(datetime.datetime.utcnow()) # UTC 기준 aware datetime : datetime.datetime(2019, 2, 15, 4, 55, 3, 310474, tzinfo=)   now는 UTC를 기준으로 현재 시각을 생성합니다. 하지만, naive한 시각입니다.  now = datetime.datetime.utcnow()   이 시각은 naive한 시각이므로 pytz.timezone.localize를 통해 timezone-aware한 시각으로 변환된 시각과 동일하지 않습니다.  assert now != utc.localize(now)   시간대 제대로 지정하기  시간대가 무엇이고, 명시하는 것이 왜 중요한지 알게 되셨다면 시간대를 원하는 의도에 맞게 지정하는 방법에 대해 알아봅시다.  import datetime from pytz import timezone, utc KST = timezone('Asia/Seoul') now = datetime.datetime.utcnow() # UTC 기준 naive datetime : datetime.datetime(2019, 2, 15, 4, 18, 28, 805879) utc.localize(now) # UTC 기준 aware datetime : datetime.datetime(2019, 2, 15, 4, 18, 28, 805879, tzinfo=) KST.localize(now) # UTC 시각, 시간대만 KST : datetime.datetime(2019, 2, 15, 4, 18, 28, 805879, tzinfo=) utc.localize(now).astimezone(KST) # KST 기준 aware datetime : datetime.datetime(2019, 2, 15, 13, 18, 28, 805879, tzinfo=)   replace() 메소드로 날짜나 시간대를 변경할 수 있습니다.  KST = timezone('Asia/Seoul') TW = timezone('Asia/Taipei') date = datetime.datetime.now() # datetime.datetime(2019, 2, 15, 13, 59, 44, 872224) date.replace(hour=10) # hour만 변경 # datetime.datetime(2019, 2, 15, 10, 59, 44, 872224) date.replace(tzinfo=KST) # tzinfo만 변경 # datetime.datetime(2019, 2, 15, 13, 59, 44, 872224, tzinfo=) date.replace(tzinfo=TW) # tzinfo만 변경 # datetime.datetime(2019, 2, 15, 13, 59, 44, 872224, tzinfo=)   하지만 replace는 그 속성 자체만을 바꿔버리는 것이기 때문에 사용에 주의할 필요가 있습니다.  now = datetime.datetime.utcnow() assert utc.localize(now) == now.replace(tzinfo=utc) assert KST.localize(now) != now.replace(tzinfo=KST) assert TW.localize(now) != now.replace(tzinfo=TW)  그뿐만 아니라 replace()를 이용할 경우 의도하지 않은 시간대로 설정될 수도 있으므로 유의해야 합니다. 그 이유는 아래와 같습니다.     시간대는 생각보다 자주 바뀝니다(더 자세한 내용은 스포카의 규칙 2번을 참고해주세요). 이렇게 변경되는 사항들은 tz database에 기록되는데, pytz는 이에 기반합니다. pytz의 버전이 2018.9와 같은 날짜로 되어있는데 2018.9 버전은 2018년 9월 기준 시간대 테이블을 기준으로 시간대를 만들어주는 버전입니다. 이 버전에선 Asia/Seoul의 시간대는 UTC+9입니다.   pytz는 무슨 이유에서 인지 datetime.replace()나 datetime.astimezone()에서 호출될 때 이 tz database 타임 테이블의 맨 첫 번째(가장 오래된) 기록을 가지고 변환을 시도합니다. 서울의 경우 초기에 UTC+8:28이었기 때문에 이 정보를 기반으로 변환합니다.   그래서 pytz를 사용할 때는 pytz.timezone.localize()를 항상 써야 하고, .astimezone()같은 파이썬의 표준 메서드들을 사용하고 싶다면 datetime.timezone을 사용해야 합니다.  스포카의 규칙 스포카에서 datetime을 다룰 때 흔히 따르는 두 가지 큰 원칙이 있습니다.  1. naive datetime은 절대 사용하지 않습니다. 가장 큰 이유는 naive datetime과 aware datetime을 서로 섞어서 쓰지 못한다는 것입니다.  >>> from datetime import datetime, timezone >>> datetime.utcnow() + datetime.now(tz=timezone.utc) Traceback (most recent call last): File "", line 1, in TypeError: unsupported operand type(s) for +: 'datetime.datetime' and 'datetime.datetime'   동적 타입 언어에서 쓸 수 있는 가장 간단한 타입 검사 수단인 isinstance() 체크로도 이 둘을 구별할 수가 없으므로, 코드의 어느 지점에서 naive datetime이 섞이기 시작하면 예기치 않은 지점에서 버그 발생 가능성이 급격히 올라갑니다. Python 2에서 str과 unicode를 섞으면 안 되는 것과 비슷한 이유라고 생각하시면 됩니다.  2. 장기적으로 보존해야 하는 datetime은 항상 UTC를 기준으로 저장합니다. 지역 시간대는 지정학적 또는 정치적인 이유로 생각보다 자주 바뀝니다. 예컨대 1961년 이전까지 한국은 UTC+08:30을 지역 시간대로 사용했었고, 1988년 올림픽 즈음에는 일광 절약 시간대를 시행하고 있었습니다. 시간대 데이터베이스(tz database)는 이런 변경 내역을 담고 있고, pytz가 제공하는 시간대 객체의 동작에도 반영되어 있습니다. 그 때문에 시간대 데이터베이스가 제때 업데이트되지 않거나, 갑작스러운 시간대 변경으로 데이터베이스에 반영이 늦어지거나 하면, 시간 계산에서 오차가 발생할 여지가 있습니다. 또한 같은 aware datetime 이어도 서로 다른 시간대를 가진 datetime끼리 연산하거나 하는 상황도 문제를 복잡하게 만들고, DB나 다른 서비스의 API를 사용할 때, 그 서비스가 시간대를 제대로 다루는 데에 필요한 복잡도를 감수하는 대신 단순히 UTC 기준의 고정 오프셋 시간대만 사용하는 등의 이유로 서로 지원 범위가 맞지 않아 곤란을 겪을 수도 있습니다.  혼선을 줄일 수 있는 좋은 규칙 중 하나는, str과 unicode를 다루던 것과 비슷하게 모든 내부적인 계산에서 UTC 기준의 aware datetime만 사용하고, 사용자에게 보여줘야 할 때만 필요한 시간대로 변환해서 보여 주는 것입니다.  스포카에서는 메인 서버의 dodo.datetime 유틸리티 모듈도 이런 규칙을 따르고 있으며, 대부분의 SQLAlchemy DB 모델 객체의 DateTime 컬럼에서 timezone=True 옵션을 켜서 사용하고 있습니다.  정리  시간 관련 작업을 하신다면 아래 사항을 꼭 기억해주세요.시간대를 명시합시다.시각을 애플리케이션 로직이나 데이터베이스에서 저장할 때는 UTC로 사용하고, 유저에게 표시할 때만 유저의 시간대로 변환하여 보여주도록 합시다.    백엔드 서버끼리 통신할 때도 항상 UTC를 사용한다는 가정을 하면, 시간대가 없더라도 robust하게 처리할 수 있습니다.
조회수 1100

이곳을 이렇게 바꿔주세요.(빙빙돌려 설명하지 않기)

이젠 좀 질릴 정도로 진부한 소재가 되었습니다. 그런 거 있잖아요. 너무 밝지 않은 화이트톤, 빈티지하면서도 뭔가 개성이 살아있는 느낌..등의 표현말예요. 그래서 오늘은 서론을 길게 끌지 않겠습니다. 짧게 정리하고 바로 넘어갈께요. 1. 클라이언트가 디자이너의 용어를 알 필욘 없습니다.2. 하지만 그게 아무말이나 하란 얘긴 아닙니다.네, 사실 핵심은 이겁니다. 명도니 채도니, 레이아웃이니 이런 용어들 안쓰셔도 됩니다. 모르는 게 당연합니다. 디자이너들도 클라이언트가 이런 용어 모른다고 막 불평하고 답답해하고 그러면 안됩니다. 어차피 서로 일하는 분야가 다른 것일 뿐입니다. 디자이너도 클라이언트 업계에서 쓰는 용어 모르는 건 매한가지니까요. 다만, 서로 뭔가 말을 할 때 '명확하게' 말할 필요는 있습니다. 지금부터 땋땋 찝어드릴 께용. 오늘은 짤이 없어요!!! 텍스트만 재미없게 우르르 써놓을 거예요.ㅋㅋ왜냐면 오늘은 딱히 짤이 어울리지 않는 쒸익쒸익 내용이거든요!1. 채도는 색의 진하기를 말합니다. '진하게/연하게' 라고 표현합니다. 2. 명도는 밝기를 말합니다.(색과 관계가 없습니다.) '밝게/어둡게' 라고 표현합니다.3. 색상은 '계열'이란 말로 표현합니다. 빨강계열, 노랑계열이라고 말합니다. '느낌' 이 아닙니다. 빨강느낌, 노랑느낌...이 아닙니다. 노랑느낌은 어떤 느낌인가요. 뭔가 간이 안좋아보이는 느낌이랄까. 느낌 쓰지 않습니다. 느낌싫어. 느낌아니예요. 4. 색앞에 형용사는 하나만 붙입니다! .(진한 빨강 / 연한 빨강 / 밝은 빨강 / 어두운 빨강) 이렇게 씁니다. 두 개 붙이지 않습니다. '어두운데 밝은 빨강 느낌....' 이렇게 말하지 않습니다. 5. 한 문장에 하나씩만 지시합니다. 이 로고 지워주시고, 타이틀 좀 크게 해주고...어쩌고.이렇게 기차놀이 하지 않습니다. 반드시 넘버링을 하고, 각 번호엔 하나씩만 지시합니다. 1)상단 로고 지워주세요.2)타이틀 글자 조금만 키워주세요.3)이미지에 선을 굵게 해주세요. 등등6. ~했으면 좋겠습니다..이런 어미는 되도록 피하세요.물론 예의차리려고 하는 말인건 알지만, 괜히 문장만 길어지고 난잡해집니다. 해라! 마라! 정확하게 끝맺음 해주시는 게 좋아요. 좀 강해보이기도 하구요. 이를 테면 이런 식입니다.어려우시겠지만, 이미지 부분을 조금 더 밝게 바꾸면 어떨까 싶은데, 디자이너님 생각은 어떠세요? 너무는 말고 약간만 밝게해서 글자가 조금 잘 보였으면 해서요 ㅎㅎㅎ..부탁드리겠습니다.ㅠㅠ이렇게 안하셔도 됩니다.- 글자가 잘보이도록 이미지 밝기 조정 부탁드립니다.라고 말하시면 됩니다.7. 위에서부터 말해주세요. 상단부터 수정사항을 순서대로 말해주세요. 위 아래 위위 아래 와리가리 하다보면 뭔가 엉망진창이 되거나 기껏 맞춰놓은 무언가가 또 틀어지곤 합니다. 8. 큰 것부터 작은 순서대로배경/이미지/전체 톤/컨셉이 바뀌는 게 먼저입니다. 자잘자잘한 텍스트 수정이나 굵기 수정 이런건 큰 것들이 맞춰진 뒤에 하는 겁니다. 보통 피드백줄 때 의식의 흐름대로 막 넘버링하면 마구 섞이기 마련입니다. 일단 수정 할 걸 다 나열한 뒤에 순서대로 넘버링해주세요. 이건 비단 클라이언트 뿐 아니라 디자이너도 마찬가집니다. 뭔가 할 말이 있거나 요청사항이 있다거나..또는 시안전달시에 설명을 덧붙일 때도 큰 틀부터 세부사항으로 말하는 겁니다.9. 미리 드렸어야 하는데..란 말은 하지마세요.미리 주셨어야 하는 건 미리 주셔야 합니다. 이를테면 컨셉 레퍼런스라던가, 바뀐 텍스트라던가, 꼭 써야만 하는 이미지파일 등등 말입니다. 혹시나 다른 팀에서 받아야 하는데 다른 팀원이 나를 견제하는 중이라서 파일을 안넘겨주고 있다면 "이러저러해서 이틀정도 늦어질 것 같아. 그 전에 다른 작업부터 부탁드린다."이런 식으로 언지가 있어야 합니다. 물론 나도 당신이 이기길 바라기 때문에 이틀정도는 충분히 기다려드릴 수 있습니다. 승전보와 함께 파일을 주시기 바랍니다.10. 빈티지한 느낌 어쩌고 이런 말 하지마세요.그런 컨셉을 얘기하는 거라면 차라리 본인이 예쁘다고 생각했던 이미지파일을 주세요. 이런 컨셉이면 좋을 것 같다~ 라고. 하나만 주면 눈치채기가 좀 어렵습니다. 보통 2,3개 정도는 받아봐야 그 레퍼런스들의 공통점을 분석할 수 있거든요. 그러니 서로 피곤하게 '세련되면서도 인간미가 있는 느낌...' 이런 우주적인 표현말고 그냥 그림으로 얘기하도록 합시다.11. 자꾸 모순된 표현을 하는 이유.'밝은데 탁한 느낌, 어두운데 너무 어둡진 않은 느낌' ....얼핏보면 말도 안되는 오퍼같지만 이게 무조건 잘못된 건 아닙니다. 예를 들면 기괴한데 아름다운 느낌. 팀 버튼이랄지, 길예르모 델토로 감독의 영화들을 떠올려보시면 쉽게 이해가 되시죠? 어둡고 음침한 배경에 인간미넘치는 괴물과 꽤나 희망적인 사랑을 얘기하고 있잖아요. 또는 쓸쓸하면서도 찬란한 느낌도 가능은 하겠네요. 총천연색의 오렌지빛 배경에 쓸쓸한 피사체 하나랄까요. 근데 이것들을 가만 보면, 공통점이 있습니다. 그렇죠. 배경의 톤은 하나입니다. 그 내부의 사물이나 인물이 부가적인 분위기를 만들어내는 거죠. 셰이프오브워터란 영화에서 사랑얘기를 빼버리면 그냥 인어괴수 영화가 되버리고 맙니다. 크리스마스의 악몽에서도 잭이 뭔갈 깨닫는 씬이 없었다면 그냥 악몽 그 자체로 끝나버릴 이야기에요. 우리가 흔히 얘기하는 '빈티지하지만 세련된' 느낌이란 건 굳이 풀자면 배경은 빈티지하지만 그 안에 오브젝트는 세련된 느낌일 거에요. 1980년대의 올드한 집이 배경이지만 내부의 소품들은 굉장히 고풍스럽고 고급진 금장이 군데군데 박힌 상태죠. 네, 무슨 말인지는 잘 알겠습니다. 다만 표현을 저렇게 해버리면 안되는 거예요. 앞으로 굳이 저런 식의 주문을 해야한다면 배경은 어떻게 / 사물,사람은 어떤 상태를 나누어서 얘기해주세요. 그냥 앞뒤 다 잘라버리고 한꺼번에 얘기해버리면 굉장히 난해해지고 맙니다.오늘의 이야기 끝 :) 
조회수 1251

QA 끝! ADB 설치부터 사용까지

Overview안드로이드 개발자라면 모두 ADB(Android Debug Bridge)를 사용합니다. 안드로이드 SDK에 포함되어 있는 기능인데요. 쉽게 말하면 에뮬이나 안드로이드 단말과의 연결고리, 도구를 의미합니다. 특히나 QA(Quality Assurance)를 진행할 때 ADB를 사용하면 아주 유용하고, 있어 보입니다. 이번 글에서는 ADB를 잘 모르는 QA직군들을 위해 설치 방법과 간단한 사용법을 공유하려고 합니다. SDK, ADB 설치하기앞서 ADB는 SDK에 포함된 기능이라고 했죠? 우선 여기를 클릭해 SDK를 설치해주세요. 참, 안드로이드는 JAVA가 기본 언어! JAVA도 설치하고 환경 변수도 설정해주세요!SDK를 설치했다면 plalform-tools 폴더 안의 adb.exe파일을 찾아야 합니다. 저의 설치 경로는(C:\Users\brandi_171205_02\android-sdks\platform-tools) 네요.경로를 찾았다면 JAVA 환경 변수 설정하듯 ADB도 환경변수를 설정해야 합니다. ‘내 컴퓨터 마우스 오른쪽 > 속성 클릭’해주세요.고급 시스템 설정 클릭 (개인정보라 지웠습니다.)환경변수 클릭시스템변수 영역 path클릭 > 편집 클릭윈도우10은 앞뒤로 ;를 추가하지 않아도 됩니다. ADB 경로를 추가해주세요. (C:\Users\brandi_171205_02\android-sdks\platform-tools)cmd창을 열고 ADB를 입력하고, 엔터를 눌러주세요.아래와 같이 나오면 성공!잘 따라왔나요? 그 다음은 단말기입니다. 개발자 옵션 > usb디버깅 허용 후 단말을 pc와 연결해주세요. CRM창에서 adb devices 를 입력해주세요. 이 명령어는 에뮬이나 단말 연결을 확인하는 명령어 입니다.ADB 설치를 마쳤습니다. 참 쉽죠? 지금부턴 자주 쓰는 ADB 명령어를 알려드립니다. 한 번 사용해보세요. 한 번 써봤다는 사람은 봤어도, 한 번만 썼다는 사람은 못 봤습니다.자주 쓰는 ADB 명령어단말 재시작QA진행하시면 재시작 많이 하죠? 단말초기화..!adb rebootapk설치 내컴퓨터 > 단말 > 다운로드할 필요가 없어요. 바로 설치!!adb install -r [파일명].apkapk 삭제adb uninstall [패지지명]Android버전 확인adb shell getprop ro.build.version.releaseScreenshotadb shell /system/bin/screencap -p 장치내경로동영상 녹화 QA일하면서 필수입니다. 정말 유용해요.adb shell screenrecord /sdcard/[저장할파일명].mp4텍스트 입력 로그인, 텍스트 입력 테스트 진짜 좋습니다.adb shell input text “[입력할 텍스트]”마치며ADB엔 엄~청나게 많은 명령어가 있습니다. 더 많은 정보를 알고 싶다면 adb help를 입력해보세요. 명령어 도움말이 툭 나올 겁니다. ADB가 있다면 이슈 등록과 이슈 관리 정말 편해집니다. 우선 알려드린 7번까지만 사용해보세요. 당신의 QA가 편안해질 겁니다. 지금까지 브랜디 QA 문지기, 김치영이었습니다.글김치영 대리 | R&D PM팀[email protected]브랜디, 오직 예쁜 옷만#브랜디 #개발자 #개발팀 #인사이트 #경험공유
조회수 1090

AWS Batch 사용하기

OverviewAWS Batch는 배치 컴퓨팅 작업을 효율적으로 실행할 수 있게 도와줍니다. 배치 작업량과 리소스 요청을 기반으로 최적의 리소스 수량 및 인스턴스 유형을 동적으로 프로비져닝합니다. AWS Batch에서는 별도의 관리가 필요 없기 때문에 문제 해결에 집중할 수 있습니다. 별도의 추가 비용은 없습니다. 배치 작업을 저장 또는 실행할 목적으로 생성된 AWS 리소스(인스턴스 등)에 대해서만 비용을 지불하면 됩니다. 이번 포스팅에서는 간단한 튜토리얼로 AWS Batch 사용 방법을 크게 11개의 Step으로 알아보겠습니다. 이렇게 진행하겠습니다.AWS에서 제공하는 Dockerfile, fetch&run 스크립트 및 myjob.sh 다운로드Dockerfile를 이용하여 fetch&run 스크립트를 포함한 Docker 이미지 생성생성된 Docker 이미지를 ECR(Amazon Elastic Container Registry)로 푸쉬간단한 샘플 스크립트(myjob.sh)를 S3에 업로드IAM에 S3를 접속 할 수 있는 ECS Task role 등록Compute environments 생성Job queues 생성ECR을 이용하여 Job definition 생성Submit job을 통해 S3에 저장된 작업 스크립트(myjob.sh)를 실행하기결과 확인 STEP1. AWS에서 제공하는 Dockerfile, fetch&run 스크립트 및 myjob.sh 다운로드AWS Batch helpers페이지에 접속합니다.    2. /fetch-and-run/에서 Dockerfile, fetchandrun.sh, myjob.sh 다운로드합니다.STEP2. Dockerfile을 이용하여 fetch&run 스크립트를 포함한 Docker 이미지 생성Dockerfile을 이용해서 Docker 이미지를 빌드합니다.잠시 Dockerfile의 내용을 살펴보겠습니다.FROM amazonlinux:latestDocker 공식 Repository에 있는 amazonlinux 의 lastest 버젼으로 빌드RUN yum -y install which unzip aws-cliRUN을 통해 이미지 빌드 시에 yum -y install which unzip aws-cli를 실행ADD fetch_and_run.sh /usr/local/bin/fetch_and_run.shADD를 통해 Dockerfile과 같은 디렉토리에 있는 fetch_and_run.sh를 /usr/local/bin/fetch_and_run.sh에 복사 WORKDIR /tmp컨테이너가 동작할 때 /tmp를 기본 디렉토리로 설정USER nobody컨테이너 실행 시 기본 유저 설정 ENTRYPOINT [“/usr/local/bin/fetch_and_run.sh”]컨테이너 실행 시 /usr/local/bin/fetch_and_run.sh를 call shell에 docker 명령을 통해 이미지 생성shell : docker build -t fetch_and_run . 실행하면 아래와 같은 결과가 출력됩니다.[ec2-user@AWS_BRANDI_STG fetch-and-run]$ docker build -t fetch_and_run . Sending build context to Docker daemon 8.192kB Step 1/6 : FROM amazonlinux:latest latest: Pulling from library/amazonlinux 4b92325dc37b: Pull complete Digest: sha256:9ee13e494b762db41b9db92a200f6784b78da5ac3b0f974fb1c38feb7f636474 Status: Downloaded newer image for amazonlinux:latest ---> 81bb3e78db3d Step 2/6 : RUN yum -y install which unzip aws-cli ---> Running in 1f5293a2294d Loaded plugins: ovl, priorities Resolving Dependencies --> Running transaction check ---> Package aws-cli.noarch 0:1.14.9-1.48.amzn1 will be installed --> Processing Dependency: python27-jmespath = 0.9.2 for package: aws-cli-1.14.9-1.48.amzn1.noarch --> Processing Dependency: python27-botocore = 1.8.13 for package: aws-cli-1.14.9-1.48.amzn1.noarch --> Processing Dependency: python27-rsa >= 3.1.2-4.7 for package: aws-cli-1.14.9-1.48.amzn1.noarch --> Processing Dependency: python27-futures >= 2.2.0 for package: aws-cli-1.14.9-1.48.amzn1.noarch --> Processing Dependency: python27-docutils >= 0.10 for package: aws-cli-1.14.9-1.48.amzn1.noarch --> Processing Dependency: python27-colorama >= 0.2.5 for package: aws-cli-1.14.9-1.48.amzn1.noarch --> Processing Dependency: python27-PyYAML >= 3.10 for package: aws-cli-1.14.9-1.48.amzn1.noarch --> Processing Dependency: groff for package: aws-cli-1.14.9-1.48.amzn1.noarch --> Processing Dependency: /etc/mime.types for package: aws-cli-1.14.9-1.48.amzn1.noarch ---> Package unzip.x86_64 0:6.0-4.10.amzn1 will be installed ---> Package which.x86_64 0:2.19-6.10.amzn1 will be installed --> Running transaction check ---> Package groff.x86_64 0:1.22.2-8.11.amzn1 will be installed --> Processing Dependency: groff-base = 1.22.2-8.11.amzn1 for package: groff-1.22.2-8.11.amzn1.x86_64 ---> Package mailcap.noarch 0:2.1.31-2.7.amzn1 will be installed ---> Package python27-PyYAML.x86_64 0:3.10-3.10.amzn1 will be installed --> Processing Dependency: libyaml-0.so.2()(64bit) for package: python27-PyYAML-3.10-3.10.amzn1.x86_64 ---> Package python27-botocore.noarch 0:1.8.13-1.66.amzn1 will be installed --> Processing Dependency: python27-dateutil >= 2.1 for package: python27-botocore-1.8.13-1.66.amzn1.noarch ---> Package python27-colorama.noarch 0:0.2.5-1.7.amzn1 will be installed ---> Package python27-docutils.noarch 0:0.11-1.15.amzn1 will be installed --> Processing Dependency: python27-imaging for package: python27-docutils-0.11-1.15.amzn1.noarch ---> Package python27-futures.noarch 0:3.0.3-1.3.amzn1 will be installed ---> Package python27-jmespath.noarch 0:0.9.2-1.12.amzn1 will be installed --> Processing Dependency: python27-ply >= 3.4 for package: python27-jmespath-0.9.2-1.12.amzn1.noarch ---> Package python27-rsa.noarch 0:3.4.1-1.8.amzn1 will be installed --> Processing Dependency: python27-pyasn1 >= 0.1.3 for package: python27-rsa-3.4.1-1.8.amzn1.noarch --> Processing Dependency: python27-setuptools for package: python27-rsa-3.4.1-1.8.amzn1.noarch --> Running transaction check ---> Package groff-base.x86_64 0:1.22.2-8.11.amzn1 will be installed ---> Package libyaml.x86_64 0:0.1.6-6.7.amzn1 will be installed ---> Package python27-dateutil.noarch 0:2.1-1.3.amzn1 will be installed --> Processing Dependency: python27-six for package: python27-dateutil-2.1-1.3.amzn1.noarch ---> Package python27-imaging.x86_64 0:1.1.6-19.9.amzn1 will be installed --> Processing Dependency: libjpeg.so.62(LIBJPEG_6.2)(64bit) for package: python27-imaging-1.1.6-19.9.amzn1.x86_64 --> Processing Dependency: libjpeg.so.62()(64bit) for package: python27-imaging-1.1.6-19.9.amzn1.x86_64 --> Processing Dependency: libfreetype.so.6()(64bit) for package: python27-imaging-1.1.6-19.9.amzn1.x86_64 ---> Package python27-ply.noarch 0:3.4-3.12.amzn1 will be installed ---> Package python27-pyasn1.noarch 0:0.1.7-2.9.amzn1 will be installed ---> Package python27-setuptools.noarch 0:36.2.7-1.33.amzn1 will be installed --> Processing Dependency: python27-backports-ssl_match_hostname for package: python27-setuptools-36.2.7-1.33.amzn1.noarch --> Running transaction check ---> Package freetype.x86_64 0:2.3.11-15.14.amzn1 will be installed ---> Package libjpeg-turbo.x86_64 0:1.2.90-5.14.amzn1 will be installed ---> Package python27-backports-ssl_match_hostname.noarch 0:3.4.0.2-1.12.amzn1 will be installed --> Processing Dependency: python27-backports for package: python27-backports-ssl_match_hostname-3.4.0.2-1.12.amzn1.noarch ---> Package python27-six.noarch 0:1.8.0-1.23.amzn1 will be installed --> Running transaction check ---> Package python27-backports.x86_64 0:1.0-3.14.amzn1 will be installed --> Finished Dependency Resolution Dependencies Resolved ================================================================================ Package                              Arch   Version            Repository                                                                           Size ================================================================================ Installing:  aws-cli                              noarch 1.14.9-1.48.amzn1  amzn-main 1.2 M  unzip                                x86_64 6.0-4.10.amzn1     amzn-main 201 k  which                                x86_64 2.19-6.10.amzn1    amzn-main  41 k  Installing for dependencies:  freetype                             x86_64 2.3.11-15.14.amzn1 amzn-main 398 k  groff                                x86_64 1.22.2-8.11.amzn1  amzn-main 1.3 M  groff-base                           x86_64 1.22.2-8.11.amzn1  amzn-main 1.1 M  libjpeg-turbo                        x86_64 1.2.90-5.14.amzn1  amzn-main 144 k  libyaml                              x86_64 0.1.6-6.7.amzn1    amzn-main  59 k  mailcap                              noarch 2.1.31-2.7.amzn1   amzn-main  27 k  python27-PyYAML                      x86_64 3.10-3.10.amzn1    amzn-main 186 k  python27-backports                   x86_64 1.0-3.14.amzn1     amzn-main 5.0 k  python27-backports-ssl_match_hostname                                       noarch 3.4.0.2-1.12.amzn1 amzn-main  12 k  python27-botocore                    noarch 1.8.13-1.66.amzn1  amzn-main 4.1 M  python27-colorama                    noarch 0.2.5-1.7.amzn1    amzn-main  23 k  python27-dateutil                    noarch 2.1-1.3.amzn1      amzn-main  92 k  python27-docutils                    noarch 0.11-1.15.amzn1    amzn-main 1.9 M  python27-futures                     noarch 3.0.3-1.3.amzn1    amzn-main  30 k  python27-imaging                     x86_64 1.1.6-19.9.amzn1   amzn-main 428 k  python27-jmespath                    noarch 0.9.2-1.12.amzn1   amzn-main  46 k  python27-ply                         noarch 3.4-3.12.amzn1     amzn-main 158 k  python27-pyasn1                      noarch 0.1.7-2.9.amzn1    amzn-main 112 k  python27-rsa                         noarch 3.4.1-1.8.amzn1    amzn-main  80 k  python27-setuptools                  noarch 36.2.7-1.33.amzn1  amzn-main 672 k  python27-six                         noarch 1.8.0-1.23.amzn1   amzn-main  31 k Transaction Summary ================================================================================ Install 3 Packages (+21 Dependent packages) Total download size: 12 M Installed size: 51 M Downloading packages: -------------------------------------------------------------------------------- Total 1.0 MB/s | 12 MB 00:12 Running transaction check Running transaction test Transaction test succeeded  Running transaction   Installing : python27-backports-1.0-3.14.amzn1.x86_64                    1/24   Installing : python27-backports-ssl_match_hostname-3.4.0.2-1.12.amzn1    2/24   Installing : python27-setuptools-36.2.7-1.33.amzn1.noarch                3/24   Installing : python27-colorama-0.2.5-1.7.amzn1.noarch                    4/24   Installing : freetype-2.3.11-15.14.amzn1.x86_64                          5/24   Installing : libyaml-0.1.6-6.7.amzn1.x86_64                              6/24   Installing : python27-PyYAML-3.10-3.10.amzn1.x86_64                      7/24   Installing : mailcap-2.1.31-2.7.amzn1.noarch                             8/24   Installing : python27-ply-3.4-3.12.amzn1.noarch                          9/24   Installing : python27-jmespath-0.9.2-1.12.amzn1.noarch                  10/24   Installing : python27-futures-3.0.3-1.3.amzn1.noarch                    11/24   Installing : python27-six-1.8.0-1.23.amzn1.noarch                       12/24   Installing : python27-dateutil-2.1-1.3.amzn1.noarch                     13/24   Installing : groff-base-1.22.2-8.11.amzn1.x86_64                        14/24   Installing : groff-1.22.2-8.11.amzn1.x86_64                             15/24   Installing : python27-pyasn1-0.1.7-2.9.amzn1.noarch                     16/24   Installing : python27-rsa-3.4.1-1.8.amzn1.noarch                        17/24   Installing : libjpeg-turbo-1.2.90-5.14.amzn1.x86_64                     18/24   Installing : python27-imaging-1.1.6-19.9.amzn1.x86_64                   19/24   Installing : python27-docutils-0.11-1.15.amzn1.noarch                   20/24   Installing : python27-botocore-1.8.13-1.66.amzn1.noarch                 21/24   Installing : aws-cli-1.14.9-1.48.amzn1.noarch                           22/24   Installing : which-2.19-6.10.amzn1.x86_64                               23/24   Installing : unzip-6.0-4.10.amzn1.x86_64                                24/24   Verifying  : libjpeg-turbo-1.2.90-5.14.amzn1.x86_64                      1/24   Verifying  : groff-1.22.2-8.11.amzn1.x86_64                              2/24   Verifying  : unzip-6.0-4.10.amzn1.x86_64                                 3/24   Verifying  : python27-pyasn1-0.1.7-2.9.amzn1.noarch                      4/24   Verifying  : groff-base-1.22.2-8.11.amzn1.x86_64                         5/24   Verifying  : aws-cli-1.14.9-1.48.amzn1.noarch                            6/24   Verifying  : python27-six-1.8.0-1.23.amzn1.noarch                        7/24   Verifying  : python27-dateutil-2.1-1.3.amzn1.noarch                      8/24   Verifying  : python27-docutils-0.11-1.15.amzn1.noarch                    9/24   Verifying  : python27-PyYAML-3.10-3.10.amzn1.x86_64                     10/24   Verifying  : python27-botocore-1.8.13-1.66.amzn1.noarch                 11/24   Verifying  : python27-futures-3.0.3-1.3.amzn1.noarch                    12/24   Verifying  : python27-ply-3.4-3.12.amzn1.noarch                         13/24   Verifying  : python27-jmespath-0.9.2-1.12.amzn1.noarch                  14/24   Verifying  : mailcap-2.1.31-2.7.amzn1.noarch                            15/24   Verifying  : python27-backports-ssl_match_hostname-3.4.0.2-1.12.amzn1   16/24   Verifying  : libyaml-0.1.6-6.7.amzn1.x86_64                             17/24   Verifying  : python27-rsa-3.4.1-1.8.amzn1.noarch                        18/24   Verifying  : freetype-2.3.11-15.14.amzn1.x86_64                         19/24   Verifying  : python27-colorama-0.2.5-1.7.amzn1.noarch                   20/24   Verifying  : python27-setuptools-36.2.7-1.33.amzn1.noarch               21/24   Verifying  : which-2.19-6.10.amzn1.x86_64                               22/24   Verifying  : python27-imaging-1.1.6-19.9.amzn1.x86_64                   23/24   Verifying  : python27-backports-1.0-3.14.amzn1.x86_64                   24/24 Installed:   aws-cli.noarch 0:1.14.9-1.48.amzn1        unzip.x86_64 0:6.0-4.10.amzn1   which.x86_64 0:2.19-6.10.amzn1   Dependency Installed:   freetype.x86_64 0:2.3.11-15.14.amzn1   groff.x86_64 0:1.22.2-8.11.amzn1   groff-base.x86_64 0:1.22.2-8.11.amzn1   libjpeg-turbo.x86_64 0:1.2.90-5.14.amzn1   libyaml.x86_64 0:0.1.6-6.7.amzn1   mailcap.noarch 0:2.1.31-2.7.amzn1   python27-PyYAML.x86_64 0:3.10-3.10.amzn1   python27-backports.x86_64 0:1.0-3.14.amzn1   python27-backports-ssl_match_hostname.noarch 0:3.4.0.2-1.12.amzn1   python27-botocore.noarch 0:1.8.13-1.66.amzn1   python27-colorama.noarch 0:0.2.5-1.7.amzn1   python27-dateutil.noarch 0:2.1-1.3.amzn1   python27-docutils.noarch 0:0.11-1.15.amzn1   python27-futures.noarch 0:3.0.3-1.3.amzn1   python27-imaging.x86_64 0:1.1.6-19.9.amzn1   python27-jmespath.noarch 0:0.9.2-1.12.amzn1   python27-ply.noarch 0:3.4-3.12.amzn1   python27-pyasn1.noarch 0:0.1.7-2.9.amzn1   python27-rsa.noarch 0:3.4.1-1.8.amzn1   python27-setuptools.noarch 0:36.2.7-1.33.amzn1   python27-six.noarch 0:1.8.0-1.23.amzn1   Complete! Removing intermediate container 1f5293a2294d  ---> 5502efa481ce Step 3/6 : ADD fetch_and_run.sh /usr/local/bin/fetch_and_run.sh  ---> 1b69173e586f Step 4/6 : WORKDIR /tmp Removing intermediate container a69678c65ee7  ---> 8a560dd25401 Step 5/6 : USER nobody  ---> Running in e063ac6e6fdb Removing intermediate container e063ac6e6fdb  ---> e5872fd44234 Step 6/6 : ENTRYPOINT ["/usr/local/bin/fetch_and_run.sh"]  ---> Running in e25af9aa5fdc Removing intermediate container e25af9aa5fdc  ---> dfca872de0be Successfully built dfca872de0be Successfully tagged awsbatch-fetch_and_run:latest docker images 명령으로 새로운 로컬 repository를 확인할 수 있습니다.shell : docker images [ec2-user@AWS_BRANDI_STG fetch-and-run]$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE fetch_and_run latest dfca872de0be 2 minutes ago 253MB amazonlinux              latest              81bb3e78db3d        2 weeks ago         165MB STEP3. ECR에서 repository 생성아래는 ECR 초기 화면입니다.fetch_and_run이란 이름으로 Repository 생성합니다. 3. Repository 생성이 완료되었습니다.STEP4. ECR로 빌드된 이미지를 pushECR에 docker login후 빌드된 Docker 이미지에 태그합니다. shell : aws ecr get-login --no-include-email --region ap-northeast-2 빌드된 docker 이미지에 태그하세요.shell : docker tag fetch_and_run:latest 000000000000.dkr.ecr.ap-northeast-2.amazonaws.com/fetch_and_run:latest 태그된 docker 이미지를 ECR에 push합니다.shell: docker push 000000000000.dkr.ecr.ap-northeast-2.amazonaws.com/fetch_and_rrun:latest 아래는 ECR fetch_and_run Repository에 푸쉬된 Docker 이미지입니다.STEP5. 간단한 샘플 스크립트(myjob.sh)를 S3에 업로드아래는 간단한 myjob.sh 스크립트입니다.#!/bin/bash date echo "Args: $@" env echo "This is my simple test job!." echo "jobId: $AWS_BATCH_JOB_ID" sleep $1 date echo "bye bye!!" 위의 myjob.sh를 S3에 업로드합니다.shell : aws s3 cp myjob.sh s3:///myjob.sh STEP6. IAM에 S3를 접속할 수 있는 ECS Task role 등록Role 등록 화면에서 Elastic Container Service 선택 후, Elastic Container Service Task를 선택합니다.AmazonS3ReadOnlyAccess Policy를 선택합니다.아래 이미지는 Role에 등록 하기 전 리뷰 화면입니다.Role에 AmazonS3ReadOnlyAccess가 등록된 것을 확인합니다.STEP7. Compute environments 생성AWS Batch 콘솔에서 Compute environments를 선택하고, Create environment 선택합니다.Compute environment type은 Managed와 Unmanaged 두 가지를 선택할 수 있습니다. Managed는 AWS에서 요구사항에 맞게 자원을 관리해주는 것이고, Unmanaged는 직접 자원을 관리해야 합니다. 여기서는 Managed를 선택하겠습니다.Compute environment name을 입력합니다.Service Role을 선택합니다. 기존 Role을 사용하거나 새로운 Role을 생성할 수 있습니다. 새 Role을 생성하면 필수 역할 (AWSBatchServiceRole)이 생성됩니다.Instnace Role을 선택합니다. 기존 Role을 사용하거나 새로운 Role을 생성할 수 있습니다. 새 Role을 생성하면 필수 역할(ecsInstanceRole)이 생성됩니다.EC2 key pair에서 기존 EC2 key pair를 선택합니다. 이 key pair를 사용하여 SSH로 인스턴스에 접속할 수 있지만 이번 글의 예제에서는 선택하지 않겠습니다.Configure your compute resources Provisioning Model은 On-Demand와 Spot이 있습니다. 차이점은 Amazon EC2 스팟 인스턴스를 참고해주세요. 여기서는 On-Demand를 선택합니다.Allowed instance types에서는 시작 인스턴스 유형을 선택합니다. optimal을 선택하면 Job queue의 요구에 맞는 인스턴스 유형을 (최신 C, M, R 인스턴스 패밀리 중) 자동으로 선택합니다. 여기서는 optimal을 선택하겠습니다.Minimum vCPUs는 Job queue 요구와 상관없이 Compute environments에 유지할 vCPU 최소 개수입니다. 0을 입력해주세요.Desired vCPUs는 Compute environment에서 시작할 EC2 vCPU 개수입니다. Job queue 요구가 증가하면 필요한 vCPU를 Maximum vCPUs까지 늘리고 요구가 감소하면 vCPU 수를 Minimum vCPUs까지 줄이고 인스턴스를 제거합니다. 0을 입력해주세요.Maximum vCPUs는 Job queue 요구와 상관없이 Compute environments에서 확장할 수 있는 EC2 vCPU 최대 개수입니다. 여기서는 256을 입력합니다.Enable user-specified Ami ID는 사용자 지정 AMI를 사용하는 옵션입니다. 여기서는 사용하지 않겠습니다.Networking VPC Id 인스턴스를 시작할 VPC를 선택합니다.Subnet을 선택합니다.Security groups를 선택합니다.그리고 EC2 tags를 지정하여 생성된 인스턴스가 이름을 가질 수 있게 합니다. Key : Name, Value : AWS Batch InstanceCreate을 클릭해 Compute environment를 생성합니다.아래 이미지는 생성된 Compute environment입니다.STEP8. Job queues 생성AWS Batch 콘솔에서 Job queues - Create queue를 선택합니다.Queue name을 입력합니다.Priority는 Job queue의 우선순위를 입력합니다. 우선순위가 1인 작업은 우선순위가 5인 작업보다 먼저 일정이 예약됩니다. 여기서는 5를 입력하겠습니다.Enable Job queue가 체크되어 있어야 job을 등록할 수 있습니다.Select a compute environment에서 Job queue와 연결될 Compute environment을 선택합니다. 최대 3개의 Compute environment를 선택할 수 있습니다.생성된 Job queue, Status가 VALID면 사용 가능합니다.STEP9. ECR을 이용하여 Job definition 생성AWS Batch 콘솔에서 Job definitions - Create를 선택합니다.Job definition name을 입력하고 이전 작업에서 만들 IAM Role을 선택하세요, 그리고 ECR Repository URI를 입력합니다. 000000000000.dkr.ecr.ap-northeast-2.amazonaws.com/fetch_and_runCommand 필드는 비워둡시다.vCPUs는 컨테이너를 위해 예약할 vCPU의 수, Memory(Mib)는 컨테이너에 제공할 메모리의 제한, Job attempts는 작업이 실패할 경우 다시 시도하는 최대 횟수, Execution timeout은 실행 제한 시간, Ulimits는 컨테이너에 사용할 사용자 제한 값입니다. 여기서는 vCPUs는 1, Memory(MiB)는 512, Job Attempts는 1로 설정, Execution timeout은 기본값인 100 그리고 Limits는 설정하지 않습니다.vCPUs: 컨테이너를 위해 예약할 vCPU의 개수Memory(Mib): 컨테이너에 제공할 메모리의 제한Jop attempts: 작업이 실패할 경우 다시 시도하는 최대 횟수Execution timeout: 실행 제한 시간Ulimits: 컨테이너에 사용할 사용자 제한 값User는 기본값인 nobody로 선택 후, Create job definition을 선택합니다.Job definitions에 Job definition이 생성된 것을 확인할 수 있습니다.STEP10. Submit job을 통해 S3에 저장된 작업 스크립트(myjob.sh)를 실행하기AWS Batch 콘솔에서 Jobs를 선택합니다. Job을 실행할 Queue를 선택하고 Submit job을 선택합니다.Job run-time1)Job name을 입력합니다.2)Job definition을 선택합니다.3)실행될 Job queue를 선택합니다.Environment Job Type을 선택하는 부분에서는 Single을 선택합니다. Array 작업에 대한 자세한 내용은 어레이 작업 페이지를 참고해주세요.Job depends on은 선택하지 않습니다.자세한 내용은 작업 종속성 페이지를 참고해주세요.Environment Command에서 컨테이너에 전달할 명령을 입력합니다. 여기서는 [“myjob.sh”, “30”] 를 입력해주세요. vCPUs, Memory, Job attempts와 Execution timeout은 job definition에 설정된 값을 가져옵니다. 이 Job에 대한 설정도 가능합니다.Parameters를 통해 job을 제출할 때 기본 작업 정의 파라미터를 재정의 할 수 있습니다. Parameters에 대한 자세한 내용은 작업 정의 파라미터 페이지를 참고해주세요.Environment variables는 job의 컨테이너에 환경 변수를 지정할 수 있습니다. 여기서 주의할 점은 Key를 AWS_BATCH로 시작하면 안 된다는 것입니다. AWS Batch에 예약된 변수입니다.Key=BATCH_FILE_TYPE, Value=script Key=BATCH_FILE_S3_URL, Value=s3:///myjob.shSubmit job을 선택합니다.Job이 Submitted 된 화면입니다.Dashboard를 보시면 Runnable 상태로 대기 중인 것을 확인할 수 있습니다.STEP11. 결과 확인CloudWatch > Log Groups > /aws/batch/job에서 실행 로그를 확인할 수 있습니다.Conclusion간단한 튜토리얼로 AWS Batch를 설정하고 실행하는 방법을 알아봤습니다.(참 쉽죠?) 다음 글에서는 AWS Batch의 Array 또는 Job depends on등의 확장된 기능들을 살펴보겠습니다. 참고1) AWS Batch – 쉽고 효율적인 배치 컴퓨팅 기능 – AWS2) AWS Batch 시작하기 - AWS Batch3) Amazon ECR의 도커 기본 사항 - Amazon ECR글윤석호 이사 | 브랜디 [email protected]브랜디, 오직 예쁜 옷만#브랜디 #개발문화 #개발팀 #업무환경 #인사이트 #경험공유
조회수 1128

세계로 뻗어 나가는 팀그레이프 무역사업부

멋진 옐로모바일 패밀리사의 서비스와 팀문화를 소개하는 옐친소, 그 22번째 이야기! 이번 주인공은 바로바로 패션 이커머스 기업 팀그레이프의 ‘무역사업부’입니다:) 그들이 전망하는 앞으로의 의류시장 트렌드는 무엇일까요? 김기덕 대리와의 인터뷰를 통해 팀그레이프 무역사업부는 어떤 비즈니스를 하고 있는지, 어떤 팀 문화를 만들어 나가고 있는지 이야기를 들어봤습니다.안녕하세요:) 옐로인들에게 ‘팀그레이프 무역사업부’에 대한 소개 부탁 드립니다. 안녕하세요, 옐로 가족 여러분! 팀그레이프 무역사업부를 대표해 소개할 김기덕 대리입니다. 저희 팀그레이프 무역사업부에는 저를 포함해 총 10명의 팀원들이 함께 하고 있습니다. 저희 부서가 새롭게 팀그레이프에 합류한지는 1년 되었습니다! 비교적 최근에 합류해 이렇게 저희 부서에 대해 소개해 드릴 수 있어 설레는 마음입니다. 무역사업부는 구체적으로 어떤 업무를 담당하고 있나요?기본적으로는 바이어가 원하는 퀄리티의 GMT(가먼트)를 생산하여 공급하고 있습니다. 해외 브랜드 오더를 받는 것부터 시작해서 바이어가 원하는 타이밍에 완성된 물건을 전달하는 모든 프로세스를 담당하고 있다고 보시면 되는데요. 그 과정속에는 원단구매, 품질관리, 스케쥴 관리, 샘플 관리 등 정말 많은 일들이 있죠.예를 하나만 들어 주시면 더 쉽게 이해가 될 것 같아요!  우선 잘 알려진 해외브랜드인 POLO에서 어떤 스타일의 드레스를 만들고 싶다는 오더를 받았다고 가정해 보면, 그에 대한 가격 및 납기를 협상하고 원부자재를 구매하여 필리핀에 있는 공장으로 보냅니다. 그럼 그 공장에서 제품을 생산해 바이어가 원하는 지역으로 선적하죠. 그 중간 중간에 원단 퀄리티도 하나하나 다 찾아서 컨펌을 받아야 하는 등, 다 설명할 수 없는 수 많은 과정들을 거쳐야 합니다. 이로 인한 스트레스 또한 어마무시하죠. ㅎㅎ이런 옷들을 만든답니다! 팀그레이프에는 많은 소호몰들이 함께 하고 있는데요, 그들과도 협업을 하시나요?저희 무역사업부는 예전부터 미국 바이어의 까다로운 제품 퀄리티와 기준을 준수하고 있습니다. 미국이 원단 퀄리티에 대한 기준이 굉장히 까다롭거든요. 그런 기준으로 팀그레이프 산하 소호몰들의 제품 퀄리티 관리를 진행했죠. 추후에는 필리핀 공장을 이용해 다량의 GMT를 생산하여 납품할 수 있을 것 같습니다. 어떤 해외 브랜드와 파트너로 협력하고 있나요? 폴로와는 굉장히 오래 협력하고 있습니다. 벌써 4년째 파트너로 일하고 있는데요, 까다로운 미국 바이어와 몇 년 동안 함께 일한다는 것은 그만큼 신뢰가 쌓인 증거라고 할 수 있죠! 큰 자부심을 가지고 일하고 있어요. 기존에는 미국인 세 명 중 한명이 입는 유명 브랜드 ‘존스 그룹’의 파트너였는데요. 얼마전 그룹이 해체가 됐어요. 거기서 따로 나온 캐스퍼(Kasper)와 함께 일하게 됐습니다. 또 GBG, MAGGY LONDON 과도 일하고 있고요:)팀그레이프의 무역사업부의 가장 큰 강점 혹은 차별점이 무엇인가요? 해외 공장을 가지고 있다는게 큰 강점으로 작용하는 것 같아요. 사실 공장이 없이도 수출 진행은 가능하지만, 남의 공장을 사용해야 하기 때문에 퀄리티 관리 등 많은 부분에서 어려움이 있습니다. 저희는 현지에서 공장을 운영 중이기 때문에 바이어가 지정한 타이밍에 원하는 퀄리티를 보다 편하게 맞춰드릴 수 있죠.  해외 어느 곳에 공장을 운영하고 있나요? 필리핀과 베트남 현지에 자체 공장 뿐 아니라 DEAHAN등 유명한 공장들과 파트너십을 맺고 있습니다:)현지 공장독특한 팀 문화가 있나요? 여성분들의 비율이 높게 구성되어 있다 보니, 점심에 회식을 하는 문화가 있어요. 저녁에 술과 고기보다는 점심에 분위기 있는 곳에서 우아한(?) 회식을 진행하고 있어요ㅎㅎㅎ 또 워크샵도 1년에 한번은 꼭 가고 있고요. 작년 여름에는 가평으로 놀러갔었는데, 올해는 어디로 갈지 기대됩니다!즐거웠던 작년 워크샵얼핏 보니, 분위기가 굉장히 자유로워 보여요! 네, 맞습니다! 예전에는 보고와 미팅을 위한 미팅이 잦아서 업무를 처리할 시간이 부족했어요. 직원들의 의견을 반영해 보고 체계를 최소화하고 개인 선에서 처리 가능한 일은 보고 없이 알아서 처리하고 있습니다. 딱딱한 미팅이 아니라 캐주얼한 자리에서 서로 의견도 굉장히 자유롭게 내고 있고요.앞으로 의류시장의 트렌드는 무엇이라고 생각하나요? 과거를 보면 미래가 보인다고 하는데요, 과거에 소품종 소량생산에서 소품종 대량생산, 그리고 다품종 소량생산, 다품종 대량생산으로 변화하고 있습니다. 유니클로나 Forever21 등이 빠르게 성장하는 것을 보면 현재 우리는 다품종 대량생산의 시대에 살고 있다고 생각해요. 앞으로는 IT와의 결합이나 특수 원단을 사용한 기능성 GMT의 소품종 소량생산의 길로 가지 않을까 하는 의견입니다. 이것이 생산성이 높아지면 다시 다품종 대량생산으로 변할 수도 있고요. IT를 접목한 옷이라! 예를 들면 어떤 것이 있을까요?이미 개발은 많이 되고 있어요. 체온을 빨리 떨어트려주는 옷이나 체온을 보호해주는 옷은 이미 많은 스포츠의류 브랜드에서 출시하고 있습니다. 이 외에도 혈압이나 맥박을 재주는 옷, 다이어트에 도움이 되는 옷, 색깔이 변하는 옷 등 개발은 되고 있으나 아직 상용화 되지 않은 의류들이 있죠. 색깔 변하는 옷은 클럽 용일 것 같은 느낌적인 느낌이…이외에도 다양하게 활용하실 수 있을 것 같아요. ㅎㅎ열일중인 무역사업부 (feat.꼬깔콘 시강) 올해 목표가 무엇인가요? 캐스퍼에 다이렉트로 오더를 수주하여 매출을 증대시키는 것이 올해 목표입니다!  마지막으로 한 말씀 부탁드립니다:)새로운 시대에 걸 맞는 젊은 회사 팀그레이프와 함께 대한민국 대표 GMT 회사가 될 수 있도록 노력하겠습니다! Go 팀그레이프!
조회수 1425

[INterview] 자란다를 키우는 사람들 1. 호카이 님

자란다 INterview 시리즈 첫 번째 주인공이 되신 ‘호카이’ 박지인 님에게는 #단아함 #차분함 #웃음 이라는 단어가 참 잘 어울립니다. 업무 중에는 엄청난 집중력으로 범접할 수 없는 아우라를 온 몸에 두르고 있지만, “저, 호카이 님...” 하고 부르는 순간 얼른 고개를 돌리는 표정은 생기 넘치는 미소 그 자체인 분이시지요. 선선한 바람이 불어오는 가을날 아침, 향긋한 커피 한 잔을 앞에 두고 박지인 님을 만나 즐거운 담소의 시간을 가져보았습니다.  '호카이' 박지인 님 ⓒ자란다자기소개를 부탁 드려요.안녕하세요, 자란다에서 닉네임 호카이(Hawk Eye)로 불리우고 있는 박지인입니다. 5살, 3살 두 아들을 키우며 회사 출근과 육아 출근 양쪽으로 고군분투 하고 있어요. 자란다와 함께한지는 이제 한달 반 쯤 되었고요, 내부 살림을 잘 꾸려나가기 위해 여러 업무를 차례로 배우고 있습니다.구체적으로 자란다에서의 역할은 무엇인가요?admin 이라고 말하는 영역의 일들 대부분을 맡고 있습니다. 총무, 재무, 회계, 급여, 인사 등 행정지원 업무가 주를 이루어요. 덕분에 예전보다 더 많은 전문용어를 접하고 있는데요, 사실 한동안 육아에 전념하던 제가 다시 업무 현장으로 돌아와 이런 일들을 맡게 되었을 때 무척 많이 긴장했었어요. 가끔 꿈에서도 회사 일이 등장하곤 했거든요 (웃음). 그랬지만 일과 가정을 함께 돌보는 것이 당연하게 여겨지는 회사 분위기 덕분에 제 나름대로의 페이스가 많이 돌아왔습니다. 닉네임 호카이(호크-아이)처럼 예리하고 꼼꼼하게 자란다의 안살림을 잘 살피고, 팀원들의 고충 해결을 위해 노력하려고 해요.  그 동안 자란다의 일원으로 지내온 이야기를 들려주세요.저는 주20시간 근무로 자란다에 입사했어요. 아침 10시부터 오후 2시까지 사무실에서 일을 하고, 아직 어린이집을 다니는 아이들의 하원 시간에 맞추어 퇴근합니다. 통근 거리가 만만치 않아서 몸이 좀 피곤하긴 해도 요즘 중요한 화두인 ‘워라밸’을 유지하기에는 무리가 없네요. 늘 다급한 마음으로 퇴근하느라 함께 일하는 분들과 충분히 소통하지 못하는 아쉬움이 있다가도, 하원 시간에 활짝 웃으며 엄마에게 달려오는 아이들을 보면 ‘이 자리에 있기를 참 잘했다’는 생각이 들곤 합니다. 또 재미있는 것은 팀원들 모두 각자의 닉네임을 정해서 서로 부르는 것이 자란다 안에서의 규칙인데요, 수평적이고 자유로운 분위기를 만드는 데에 웃기고 재미난 닉네임이 톡톡히 한 몫을 하고 있어요. 제 닉네임 호카이는 저희 둘째 아이가 어벤저스 시리즈의 인물 중 호크-아이를 워낙 좋아해서 얼른 고른 이름입니다. 제가 조금 더 날렵하고 날카로워져야겠지요?‘소비자’ 부모님으로 자란다 서비스를 어떻게 생각하시나요?사실 자란선생님을 아직 한 번만 만나봤기 때문에 제가 ‘자란다는 00이다’ 라고 표현하기에는 조금 섣부른 감이 있어요. 그래도 선생님을 신청하고 자란다를 통해 매칭이 되어 아이가 선생님과의 놀이 시간을 실제로 가져보기까지 과정을 돌이켜본다면... ‘한땀 한땀’ 이라는 말이 생각납니다! 교통편이 좋지 못한 저희 동네로 오실 자란선생님을 신청하고, 상담을 하면서 아이와 성격이 잘 맞는 선생님과 매칭되기까지의 시간이 짧았던 것은 아니에요. 하지만 요즘 불만으로 가득 차 있던 첫째가 막상 자란선생님을 만난 순간, 우리 가족 모두에게 새로운 세상이 열렸다고 해야 할까요 (웃음). 기다린 시간이 무색할 만큼 아주 알찬 하루가 되었지요.  호카이 님에게 ‘일을 한다는 것’은 어떤 의미인가요?‘오롯이 제 자신으로 있을 수 있는 시간’ 입니다. 누구 엄마, 누구 와이프, 누구 딸, 누구 며느리… 수많은 명찰이 저에게 있지만 그 중 어느 것에도 해당하지 않는, 오직 제 이름만으로 존재할 수 있는 공간과 시간이네요. 이 사회의 구성원이 된 느낌도 좋고, 아이들에게도 엄마가 ‘엄마’ 역할 뿐 아니라 다른 모습도 가지고 있다는 것을 알려주고 싶어요.자란다의 일원으로 다른 부모님이나 선생님에게 하고싶은 말이 있다면?밖에서 보시는 것보다 자란다에서 한 아이와 한 선생님을 매칭시키기까지 정말 많은 시간과 정성이 들어간답니다. 우아한 백조의 바쁜 발처럼 열심히 움직이는 자란다의 노력을 조금만 더 알아주셨으면 좋겠습니다! (큰 미소)'호카이' 박지인 님 ⓒ자란다비록 길지 않은 글로 정리하였지만, 호카이 님과의 인터뷰 두 시간은 정말 솔직담백한 대화의 시간이었습니다. 자란다 입사 전에는 이런 서비스의 존재조차 몰랐다는 호카이 님은, 인터뷰 중에 무려 “저는 자란다를 단숨에 좋아하게 되었어요!” 라고 외치기도 하셨는데요. 다정하고 세심한 호카이님과 함께 아이들의 즐거운 시간을 더 많이 만들기 위해 자란다도 열심히 노력하겠습니다.ⓒ inside-interviewer MAUMC[자란다]는 부모와 아이의 행복한 성장을 응원합니다.#자란다 #교육기업 #팀원인터뷰 #팀원소개 #팀원자랑 #조직문화 #기업문화

기업문화 엿볼 때, 더팀스

로그인

/