brunch

You can make anything
by writing

C.S.Lewis

by 아리아 Nov 13. 2017

카카오에서의 2년[3]

Pair programming으로 날씨 컬렉션 개발하기

벌써 세 번째 글이다.

그간 셀 내에서 해왔던 프로젝트가 몇몇 있지만, 기억에 남는 프로젝트가 있다.

1년 전 프로젝트에 대한 회고랄까.

처음 글(카카오에서의 2년[1])에서 언급한 방향에 맞춰서 이야기를 풀어가 볼까 한다.

프로젝트 회고
- 프로젝트 소개
- 나의 역할, 내가 강점을 드러냈던 부분
- 특정 기술 셋을 선택한 이유(생략)
- 시스템, 데이터 모델 구성도(생략)
- 회고할만한 부분


프로젝트 소개

포털 Daum과 카카오톡 내 샾(#) 검색을 통해 노출되는 날씨 컬렉션이다.

API 교체 작업부터 프론트(사용자에게 보이는 화면, UI/UX)까지 대규모의 개편 작업이었다. 

약 4개월 간 두 명이 페어로 개발했다. 나와 서핑을 좋아하는 개발자.

백문이 불여일견이라고, 아래 스크린샷을 첨부했다. 차례대로 PC와 모바일 화면이다.

모바일 화면

우리가 했던 일들을 간략하게 소개하면 아래와 같다.


1. 데이터 잘 쌓기.

데이터는 케이웨더에서 제공받고 있었고, 데이터 허브 셀에서 가공해서 우리에게 날씨 API 형태로 제공한다. 

기존 방식은 file write & read 방식으로, 기존에 쓰여있는 file과 새로 write 한 dump file의 checksum을 비교하여 데이터 갱신 작업 여부를 판단했었으나, 기존 방식대로 진행할 경우 갱신 시점마다 API call을 해야 함. 갱신하는데 엄청난 시간을 잡아먹게 할 것이 아니라면, API call 횟수를 최소한으로 줄여야 한다. 이에, API별 갱신 주기를 관리하는 테이블을 생성했고, 아래와 같은 로직 갱신으로 여부를 판단했다.


API 종류 별로 마지막 갱신 시각(lastEndDate)과 불러올 단위 시간(unit) 저장.
현재 시점(now)을 기준으로, 
갱신 이력이 존재할 경우(lastEndDate + unit > now), 해당 API 갱신하지 않음.
갱신 이력이 존재하지 않을 경우, 단위 시간만큼 API call 하여 갱신한다.
(단위 시간을 두는 이유는, 배치에 문제가 생겨 한동안 돌지 못했을 경우, 무지막지한 데이터를 긁어올 수가 있는데, 이때 타임아웃 나는 것을 방지하기 위함)


주기적으로, 동 단위별 주간예보, 초단기예보, 동 단위 예보, 기상특보 데이터를 우리 쪽 DB에 서비스에 맞는 형태로 가공 및 적재했다.


데이터를 잘 쌓고 나면,

2. 사용자에게 어떤 데이터를 보여줄 것인지에 대한 고민과 작업이 필요하다.

다양한 쿼리 유입에 대응을 해야 한다. 날씨 컬렉션이 노출되어야 할 쿼리가 '날씨', '일기예보', 혹은 '날씨는?'으로 유입될 수도 있다. 별도의 처리가 되지 않은 시스템은 저 세 개가 같은 의미를 하는 것인지 알 수 없다. 하여, 쿼리를 분석하고, 동의어와 불용어를 처리하는 과정이 필요하다.

쿼리에 맞는 화면단 대응도 필요하다. 쿼리(검색어)가 '내일 서울 날씨'라면, '서울' 지역의 '내일' 날씨가 첫 화면에 노출되어야 한다. 유저가 원하는 정보를 빠르고 편리하게 제공하기 위해서다. 

쿼리가 '다음 주 전국 날씨'라면, 특정 지역의 날씨 화면이 노출되어서는 안 된다. 또, 오늘을 기준으로 7일 후 데이터를 보여줄 것인지, 무조건 다음 주 월요일 데이터를 보여줄 것인지.. 정책에 대한 논의와 결정도 필요하다. 이런 복잡한 로직을 시스템에 담으려다 보니 기존 레거시를 활용하기가 힘들었다. 하여, 개편이라 읽히고, 처음부터 다시 개발을 하게 되었다. 대규모 프로젝트에 투입된 나는 초초 슈퍼주니어였고, 다른 한 분도 입사하신 지 몇 년 되지 않았지만, 나에 비해 경험이 더 있으신 분이었다. 우리는 페어 프로그래밍에 도전해보기로 했다. 프로젝트의 한 싸이클이 어떻게 돌아가는지, 다른 타 개발부서와 커뮤니케이션하는 방법을 배우기에도, 서로 미연의 실수를 방지하기에도 좋을 것 같았기 때문이다.


[페어 프로그래밍]
애자일 개발 방법론 중 하나. 하나의 모니터, 하나의 키보드로 두 명의 개발자가 함께 협업 개발하는 것을 말한다. 큰 방향과 로직을 제시하는 navigator, 로직을 구현하는 driver 두 개의 역할로 나뉘어 있다. 특정 시간 단위로 번갈아 가며 이 역할을 수행한다. 두 사람이 같은 로직에 대해 고민하고, 코드를 작성하는 과정을 보고 있으므로 개발 단계에서 버그 발생 확률히 현저히 줄어드는 효과를 기대할 수 있다. 


3. 화면(View) 구성

흔히들 아는 front-end 영역이다. 우리 셀에서 관리하고 있는 컬렉션들의 경우 기술 스택들이 이미 정해져 있었는데, Apache에서 나온 Java template language인 freemarker와 jQuery로 개발했다.

날씨 MO의 경우, 배경 이미지가 제공되고 있는데, 지역별, 시간별(낮/밤), 날씨별로 다른 이미지가 노출되어야 했다. 또, 기온 그래프, 습도 그래프 등 엄청나게 다양하고 많은 아이콘이 노출되어야 했다. 가벼운 스펙은 아니었다. Daum의 검색 결과에는 우리 셀에서 제공하는 컬렉션 외에도 블로그, 뉴스와 같은 타 결과도 노출해줘야 하므로, 렌더링 및 응답 속도가 늦어서는 안 되었다. 하여, 코드를 최적화하기 위해 많이 노력했다. 

아래는 프론트 코드를 최적화하기 위해 신경 썼던 것들이다.


필요 이상의 loop(iteration)이 돌지 않도록 한다.

적절치 못한 자료구조 선택으로 탐색에 더 오랜 시간이 걸리지 않도록 한다.

렌더링 속도 향상
- CSS 파일은 페이지의 제일 상단에, javascript 파일은 페이지 제일 하단에 위치.
- 초기 렌더링 시에는 Ajax call을 지양.

리소스 request 최소화
- javascript 파일 통합, CSS Sprite, 캐시 설정,...

리소스 사이즈 최소화 및 압축
- Css compressor (https://csscompressor.com/ 에서 테스트 가능)
- js minifier (https://jscompress.com/ 에서 테스트 가능)


(웹페이지 최적화에 대한 주제가 아니므로, 위에 대한 이야기는 추후 더 상세히 다뤄볼까 한다.)


4. QA와 배포

따로 QA 지원이 없어, 당시 기획자와 함께 QA를 진행했다. 

기존 유입되었던 쿼리에 대해 컬렉션이 잘 노출되는지, 유저가 원하는 데이터 셋을 초기에 보여주고 있는지, 속도가 너무 느린 것은 아닌지, 날씨/지역에 따른 background image가 잘 노출되고 있는지 등을 확인했다.

확인 및 이슈 대응 후, 성공적으로 오픈 :)




내가 한 일, 그리고 회고

서비스를 같이 만들어 나가는 사람으로서, 기획안 리뷰나 화면을 구성하면서, 데이터를 잘 보여주기 위해 최저/최고 기온에 색깔을 입히는 기획에 관련된 아이디어도 몇 제안했고, 그래프를 빠르고 예쁘게 그리기 위한 방법을 제시했다. 반영된 것도 있고, 반영되지 않은 것도 있지만 피드백을 받는 것은 언제나 꿀잼 :)


페어 프로그래밍을 진행하면서 느꼈던 점은, 서로의 코딩 스타일(네이밍...)을 맞춰나가고, 더 나은 방법에 대해 real-time으로 논의하고 맞춰 나가는 과정이 재미있었다. 혼자 코드를 작성할 때 보이지 않았던 것들, 버그들을 더 빠르게 발견할 수 있었다. 하지만, 문제가 빨리 해결되는 만큼 나 혼자 깊은 고민을 할 기회는 적어졌다. 문제 해결의 과정보다는 결과에 초점이 맞춰지게 되는 것 같았다.

페어 프로그래밍에 익숙해지다 보니, 핵심 로직만 페어로 진행하고, 단순 작업은 각자 나눠 점차 효율성을 높여나갔다. (페어를 하루 종일 하는 날도 있었는데, 강철한 체력은 필수다. 하루 종일 집중하기가 쉽지 않다. 매우 어렵다.)

프로젝트 중간에 나만 판교로 올라오게 되면서, 원격으로 페어 프로그래밍을 해야 하는 상황이 발생했다. 원활하게 진행하기 위해 Floobits를 제안 및 사용했는데, floobits는 구글 독스의 코딩 버전이랄까? 누가 어떤 라인의 코드를 수정하고 있고, 수정 중인 라인으로 이동하기 등 협업에 유용한 기능들을 제공한다.


프로젝트 도입부터 나는 TDD(Test driven development)를 주장해왔는데, 단순한 기능에 대해서도 테스트 코드를 작성하다 보니, 재설계는 물론 조금이라도 구조가 바뀌게 될 경우 테스트 코드 재작성에 대한 부담이 점점 커지게 되었다. (이 부분은 나와 동료 모두 공감했던 부분) 하여, 우리는 복잡한 로직에 대해서만 테스트를 진행하는 게 나을 것 같다 생각하여, 테스트가 필요한 로직과 필요하지 않은 로직을 구분했고, 필요한 테스트 코드만 남게 되었다. TDD를 강하게 주장했던 사람으로서, 이번 일을 계기로 깨닫게 된 것은 '절대적'으로 옳고 그른 방법은 없다는 것! 수많은 방법들 중 내게 필요한 것을 유연성 있게 사용하는 법을 아는 것이 정말 중요하다고 느꼈다. 이 프로젝트를 나 혼자가 아닌, 함께 할 수 있는 사람이 있어 더 많이 배웠다. 페어로 개발해볼 수 있는 경험을 가질 수 있어 감사했던..:)


이 프로젝트를 마지막으로 나는 검색팀을 떠났다.

매거진의 이전글 카카오에서의 2년[2]
브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari