Recent Posts
Recent Comments
Link
관리 메뉴

NaggingMachine

Global company의 Global Promotion 작업을 마무리 하며... 본문

TechnoBabbler

Global company의 Global Promotion 작업을 마무리 하며...

naggingmachine 2013. 12. 13. 11:56

그동안 약 5개월간 진행된 글로벌 프로모션 서비스의 개발 및 운영이 모두 완료되었다. 4개의 기업과 계속해서 영어로 커뮤니케이션하고 주기적으로 컨퍼런스콜을 하는 등 나에게는 잊지 못할 경험과 한단계 성숙할 수 있는 기회를 제공해 주었다. 이번 프로젝트를 통해서 알게되고 느낀점들을 적어보도록 한다. 나중의 나에게, 또는 누군가에게 도움이 될 수 있지 않을까 생각한다.


- 미국과의 작업은 역시나 시차 문제로 인해서 항상 어려움이 따른다. 이번 프로젝트의 경우에는 미국 시간 기준(PCT)으로 진행되었고, 심지어 미국 내에서도 시차가 있어서 약속을 잡고 진행하는게 쉽지 않았다. 더구나 우리 회사에는 컨퍼런스콜을 할 수 있는 별도의 장비가 마련되어 있지 않아서 매번 스카이프를 이용했는데 네트워크의 상태나 마이크의 상태에 따라서 회의가 취소되기도 했다. 시차가 다르면 한쪽은 항상 고생한다는 거.


- 글로벌 서비스는 역시나 어느 타임 존에 맞추느냐도 매우 중요하다. 예를 들면, 특정 이벤트의 시작과 끝을 어떻게 맞출 것인지. 이번의 경우에는 약간 유동적이었던게, 이벤트를 알리는 것은 주로 미국 시간 기준이었지만, 공식적인 알림은 UTC 기준으로 했다. 몇개의 국가만 선택되었어도 조금은 다르지 않았을까. 그것이 맞는지 틀린지는 아직도 잘 모르겠다. 다수의 사용자에게 가장 잘 알려질 수 있는 시간이 좋다고 생각이 되지만, 꼭 그렇지도 않을 수 있다. 특히 이번 프로모션에는 투표(voting) 시스템이 도입되어 있었으므로 시간은 굉장히 민감할 수 밖에 없다.


- 영어 때문에 오해가 생긴다. 영어를 할 수 있다고 생각하지만 역시나 네이티브는 아니므로 화상 회의나 전화 통화등을 통해 중요 사항이 결정되는 시점에서는 신경이 곤두설수밖에 없고. 마지막에 정확하게 이해했느냐 또는 이대로 결정하겠다라는 말에는 반드시 관련된 내용을 이메일로 공유해달라고 요청을 했다. 내가 요구하는 사항도 컨퍼런스콜 전 또는 후에 반드시 이메일을 통해 관련 내용을 숙지하도록 했다. 하지만 그렇게 했는데도 불구하고 특정 사안에 대한 책임을 따지게 되는 상황이 발생하기도 했는데, 참 난감했다. 다행히도 이메일 로그 덕분에 원만하게 해결되었지만 역시나 쉽지 않다. 그리고 영어 단어의 미묘한 차이를 감지하지 못하는 것도 문제다. 나는 역시나 사전을 통해 학습을 했고, 말이라는게 미묘해서 상황에 따라 다양하게 해석되는 면이 있으므로 이 부분을 간과해서도 안된다. 커뮤니케이션은 원래 어려운데 하물며 외국말은 더 하겠지.


- 24/7 작동하는 서비스를 구축하기 위해 클라우드의 도입을 고려했고 최종적으로는 Google AppEngine(GAE)를 선택했다. 이유는 관리가 용이하고 개발이 쉬우며, 내 입장에서는 서버에 대한 고려가 거의 없이도 시스템을 구축할 수 있었기 때문이다. 다만 비용이 다소 높아 사용자의 숫자에 따라서 지나치게 높은 금액이 지불될 수 있다는 점이 문제가 되었다.(다행히도 그런 문제가 발생하지 않았다) 기대했던대로 서버는 안정적으로 작동하였고 모든 이벤트를 손쉽게 관리하고 처리할 수 있었다. 하지만 GAE는 로그를 별도로 관리하거나 DataStore에 저장된 데이터를 분석하기가 용이하지 않아, 이 부분은 GAE에 의존하기 보다는 별도의 관리 도구를 개발하는 방향으로 문제를 해결했다.


- GAE는 사용하는 만큼 비용을 지불하는 서비스지만, 그렇다고 해서 모든 서비스를 무한정 사용할 수는 없다. 예를 들면, 이메일은 하루에 5,000(??)정도밖에 안되고 그 이상에서는 오류가 발생한다. 상식적으로는 무한정 보내는게 맞다고 생각이 되지만 돈과 상관없이 제한이 걸려있다. 다른 몇가지 서비스들도 마찬가지다. 해결하는 방법은 Billing시에 Premium Account로 등록하여 제한을 없애거나 숫자를 높일 수 있다. 하지만 Premium Account로 등록하기 위해서는 별도의 오프라인 검증 과정을 구글과 함께 진행해야 하는 번거로움이 있다. 또한 온라인에서 간단하게 신청할 수 있도록 되어 있지만 아무리 기다려도 소식이 없어 결국 구글 코리아의 도움을 받아 진행하게 되었다는 점은 다소 의아했다. 그런데 이 과정에서 이메일은 SendGrid라는 3rd party 툴을 활용하는게 더 낫다는 사실도 알게 되었으며 구글이 적극적으로 이 방법을 추천했다. GAE는 외부 서버로의 호출이 자유롭기 때문에(마찬가지로 비용 지불) 얼마든지 외부의 자원을 활용할 수 있다. SendGrid를 사용하면 메일을 무한정 보낼 수 있다.


- 페이스북 로그인은 가끔 실패한다. 사용자가 웹 브라우저에서 페이스북으로 로그인을 하면 Access Token을 얻을 수 있는데, 서버에서는 해당 Access Token을 이용하여 사용자를 인증한다. Python 라이브러리를 이용하면 Facebook 서버에서 사용자 계정 정보를 가져오고 해당 사용자가 정상 사용자인지를 판단할 수 있는데, 문제는 가끔(?) 페이스북 로그인이 실패할 때가 있다. 처음에 개발할 때에는 Facebook API에서 실패가 발생하지 않을거라고 생각했기 때문에 이 부분에 대한 고려를 하지 못했다가 나중에 반영했다.


- 로그를 잘 남겨야 한다. 서비스를 운영하면 다양한 상황에 처하게 된다. 악의적인 공격이라든지 여러가지 시도들. 이런 것들을 사전에 파악하기 위해서 로그를 남기게 되는데, GAE에서는 로그의 양에 따라서 서버 비용이 발생하므로(그렇게 크지는 않음) 로그를 스마트하게 남겨야 한다. 물론 이건 비용 뿐만 아니라 분석할 때에도 고생하게 되니까 당연한 일이겠지만. 이번 프로젝트의 경우 로그를 지나치게 남긴 면이 있어서(분석에 도움은 됐다), 나중에 좀 후회하기도 했다. :-)


- 비용을 줄이는데 캐시(Cache)만 한게 없다. 서버를 처음 설계하면서부터 가장 중점적으로 염두해두었던 부분은 캐시의 활용에 관한 것이었다. 비용과 효율성, 속도에 이르기까지 모든 면에서 큰 영향을 미치기 때문이다. 따라서 사용되는 모든 데이터의 생명주기를 분석하고 각 데이터에 대해서 valid, invalid를 잘 구분해 두었다. 덕분에 서버에서 hit ratio는 80% 수준이었고 비용도 매우 절감할 수 있었다. hit ratio가 더 높아지지 못한데에는 사용자가 투표를 할 때마다 갱신되는 정보를 어쩔 수 없었기 때문이다.


- 버전 관리는 필수다. 절대로 발생해서는 안되지만 아무래도 혼자서 개발하다 보니까(단위 테스트를 수행했음에도 불구하고), 라이브 서버에 올린 최종 버전에 문제가 발생하기도 했다. 올려보면 error 로그가 주루룩 뜨고 나도 눈물이 주루륵 난다. ㅠㅠ 다행히도 GAE는 모든 instance에 버전이 존재하므로 해당 버전으로 급하게 롤백하면 된다. 그래서 버전 이름을 명확하게 지정하는게 필요한데, 대략 이런 식이었다. [서비스-v버전-날짜] 그리고 오래된 버전이라고 하더라도 하나의 버전에는 로그가 함께 저장되어 있으므로 섣불리 삭제하지는 말자. 로그 복구가 안된다.


- 로컬에서 충분히 테스트하자. GAE는 로컬 서버만으로도 거의 모든 기능을 테스트할 수 있다. 비용을 측정하기 위해서라도 로컬 테스트가 필요하다. 단위 테스트에도 필요하다.


- 블랙리스트를 잘 활용하자. GAE는 최대 100개까지 IP 기준으로 블랙리스트를 등록할 수 있다. 서버를 운영해보니 악의적인 접근들이 있었고, 상당히 많은 IP를 블록할 수 밖에 없었다.(물론 IP를 차단하기까지 로그 분석을 해야 하는 수고로움은 따른다) 다행히도 GAE가 최근 시간 기준으로 접근이 많은 IP들을 추천(?)해주기 때문에 몇가지 후보군들을 뽑아볼 수 있다. 


- Index를 잘 설계하자. DataStore는 RDB 형태의 쿼리가 불가능하다. 모든 데이터에 조건을 걸어서 검색하는건 불가능하다. 이때 검색이 되느냐 안되느냐의 기준은 Indexing을 사전에 설정해두었느냐 아니냐에 따라 다른데, 나중에 조건 검색을 하려고 했더니 검색이 안된다는 둥, 그래서 망했다는 둥의 어려움을 겪게 된다. 따라서 본인이 관심을 갖는 데이터의 종류와 성격, 그것들간의 관계를 사전에 잘 파악해두고 당연히 Index에 속할 수 있도록 해야 한다. 나 같은 경우에는 정말 필요한 데이터였는데 index가 걸려있지 않아 검색이 불가능했고 결국에는 데이터를 따로 구해서 연산을 통해 처리하는 불편함이 있었다. 머리가 멍청하면 몸이 고생이다. index의 중요성은 MySQL만 사용한 사람은 모른다. 힝~


- 서비스 운영에는 책임감이 따른다. 이미 세상 사람 모두가 알고 있는 진리라고 할까. 그것이 아무리 간단하고 보잘것 없어도 다른 사람이 사용할 수 있도로 세상에 내 놓았다면 거기에는 무한의 책임이 따른다. 그리고 그 책임을 어느 정도까지 본인이 실감하고 있느냐에 따라서 서비스는 더 나아지기도 또는 망가지기도 한다. 2000년도에 처음으로 EBS에 납품되는(10만개 분량) 소프트웨어를 개발했을 때에 느꼈던 심리적 부담감, 2001년도에 안철수 연구소에서 백신 치료 데이터(최소 1,000만명 기준)를 작성하면서 매주 엔진데이터 갱신되기 전에 느꼈던 심리적 부담감. 이전 직장에서 사람의 목숨과 국가의 미래가 걸려있다는 부담감은 매번 내가 일에 집중할 수밖에 없는 이유이기도 했다. 이번 프로젝트는 대기업의 프로모션일 뿐만 아니라, 그것이 SNS를 통해서 무한 공유될 수 있다는 부담감이 너무 커서 항상 노트북을 소지하고 다니고, 새벽에 중간에 깨어나서 로그 확인하고, 매일 아침이면 제일 먼저 메일부터 확인하는 등 심리적 부담감이 컸다. 더구나 도와줄 사람이 없다는게 함정. 세상의 모든 서비스들이 문제 없이 돌아갈 수 있도록 애쓰는 보이지 않는 분들에게 박수를 보내고 싶다. :-)


이외에도 너무 많은 일들이 있었지만, 모두 다 언급하기에는 개인적인 치부(?)가 너무 많아 힘들것 같고, 결론적으로는 이번 미션이 잘 완수된것 같아 다행스럽게 생각하고 있다. 긴 미션을 통해 1등으로 선발된 분께도 축하의 말씀을 드리고, 그동한 수고한 GAE에도 감사의 말씀을 전하고 싶다. 사실 개발에는 오랜 시간이 걸리지 않았다. Python도 땡큐~