2. 작성자는…
• Java 웹 개발자
• Spring framework를 주무기로
• SI로 시작, 업무 도메인을 자주 바꾸는게 싫어서
어쩌다 게임 개발로 전향
• 도메인만 게임으로 바뀌었고 기술 스택은 그대로
3. 모바일 게임서버를 웹으
로
• 왜?
• 실시간 서비스가 곤란하다
• 비연결형 서비스에 최적
• 밀리언 아서가 성공해서?
4. 프로젝트와 만남
• 개발 시작 2년정도
• 투입 당시 3개월 후에 론칭한다고
• 전담 서버 개발자 없었어요.
• Java 웹서버는 게이트웨이 및 흐름제어정도
5. (어디든) 기획은 굴곡진
다
• 아이템 기획을 새로?
• 인벤토리는 캐릭터 귀속? 계정 귀속?
• 반복성 있는 속성에 대한 다양화 기획!?
• 동일 로직인데 대상이 달라
6. Stored Procedure(SP) 가 어때서?
• DBA가 튜닝과 로직을 동시에 책임
• 웹앱은 DB분산에 대한 흐름관리만
• SP 안에서 트랜잭션(TX) 스콥은 최대한 짧게
• 문제는 CS로 해결
• 테이블 쓰임은 SP에서 확인
7. SP 가 어때서?
• 흐름은 웹 앱에서, 세부 로직을 확인하려면 SP를 확인
• 버그 처리 역할과 책임이 분할, 소통비용 발생, 일단 혼자니
그다지
• 이쪽 저쪽 확인하기 귀찮…
• SP 작성시 성능 고려, 인덱스만 서너개씩? include 인덱스
는 캐시?
• SP 안에서 SP를 호출, Depth가 서너번인 것을 서너번 반복
• DB에서 직접 수정하면 버전관리는??
• 의존성 확인을 위한 정적 분석이 곤란(테이블/컬럼 삭제하
면?)
• 추상화? 동일 로직 복붙 & 테이블/컬럼명 변경!
8. PHP에서 Java/Spring으
로
• 회사내 기존 모바일 게임서버는 PHP +
SQLServer
• PHP와 SQLServer 에서 궁합이 않좋았다고
• PHP는 아마 밀리언아서 때문에?
• Java는 커넥션 풀이라는 것을 쓸수가 있대!!!
• 웹 언어를 바꿔도 로직이 DB에 있으면!!!
• 웹은 거들 뿐이었죠!
9. 말만 Java/Spring
• Map/List 로 떡칠.
• 타입? DTO? 그런거 없어요.
• 제네릭? 우걱우걱
• Servlet Container는 상태를 가지는 가지게 할 수
있는 서버인데
• DB간 흐름만 관리하기만 하지도 않아요
10. 일정은 고무줄?
• 아이템.. 또 재기획(8차래요!? 론칭할때는 12차?)
• 서버 개발자는 일단 혼자.
• 바꿀수 있는 시간이 생겼어요!
• 반발을 줄여라! 점진적으로…
• 개발에 지장을 주면 안되요!!!
11. 장애는 안되! 개발서버
라도!
• 훈련은 전투다! 각개전투!
• 실전과 같은 훈련으로 지상전의 승리자가 된다!
• 서버 개발자 한명이 40~50명을 놀게 한다.
• DB Schema 변경은 증분으로, SP 후방 가변(기본
인자)
• 웹 무중단 패치? 아주 잠깐 몇몇은 불안정해도?
12. 무엇부터 할까?
• 바꾼 것이 괜찮음을 확신 할 수 있어야
• API 시나리오 테스트를 만들어요!
• 매번 게임 계정을 새로 생성하게 합니다.
• 개인 컨텐츠 위주입니다.
• Logic In DB… 어차피 단위 테스트는 못합니다!
13. 무엇부터 할까?
• 가장 많이 중복되는 것 => 효과가 크다
• 되돌리기 쉬운 것 => 일괄 치환하자
• 중요하게 여기지 않는 것 => 그러려니 넘어가 줘
요
• 결과 코드 반환하는 부분부터 => DTO를 만들어
서 처리 => Output Param (Multi ResultSet=>
Single ResultSet)
14. DB는 소중해요
• Scale Up 해야 하는 자원
• 개인 데이터는 Scale Out 하게, But 바란스를 맞추
려면…
• 길드, 친구 같은 소셜컨텐츠는 Scale Up…
• 랭킹은 DB 잡아먹는 괴물!!
• Select 수를 줄이고 싶습니다.
• 로직을 웹앱으로
15. Map -> DTO
• 네 노가다 좀 했어요
• 변환은 MyBatis가 해줘요
• Request도 Map에서 DTO로
• if ((int)map.get(“xxx”) == 0)
• controller 의 requestMapping 메서드의 return은
못바꿨어요.. Map에다 DTO 개체들을….
16. 에러코드를 웹앱으로
• 에러코드를 문서화 하기 위해 에러를 Checked
Exception으로 변환해서 Controller까지 전달시킵
니다.
• RollbackFor도 RuntimeException이 아니라
Exception으로 바꿨어요.
• 에러코드도 상수화해서 모았어요.
17. 로직을 서서히 웹앱으로
• 과감히 브랜치를 생성
• SP를 CRUD만 하도록
• 로직을 웹으로
• TX도 웹에서
• 리팩토링은 정규업무가 아니잖아요?!
• 서서히 단위 테스트도 만들어 봅니다.
18. DB 부하 줄인다면서?
• 개인 게임 데이터는 최대한 Session에 넣습니다.
• Non-Sticky라서 memcached-session-manager를 썼
어요.(L7쓰고 싶었습니다.)
• 기초/기준/상수 데이터는 myBatis 캐시 썼어요 =>
Spring Cache로…(MyBatis도 걷었어요)
• 그래도 SP는 남아 있어요. 쿼리 플랜 캐시? PSMT도
되는데…
• ORM은 아직 안되요!!
19. 무엇이 바뀌었나?
• 반복 감소: 아이템 옵션, 충전성 재화, 랭킹
• 책임 위치 분리와 의존성 가시화
• 코드 정적 분석 : PMD, STAN4j, Dependency
Metrics
• 계정, 캐릭터, 경제, 전투, 소셜 순서로 계층적 의
존
• 고가용성 증가 : DB ScaleUp 여유확보, 웹서버 추
가
• 단위 테스트 가능
• 이벤트 기능은 AOP나 Intercepter로 처리가능
20. 무엇이 바뀌었나?
• 최대한 자동화 : 빌드, 상수데이터 exp/imp, SQL
• 최대한 버전관리
• svn -> git
• 타겟서버 = git branch 이름
• 코드리뷰
• batch/shell script 수
21. ‘R&D 프로젝트’라네요
• NoSQL 2가지 사용, 2가지 R&D
• Redis, memcached, infinispan, cassandra
• 웹앱 TX, 웹앱 로직, Session, Cache 사용
• SQLServer : BCP, SQLCMD를 이용한 배포자
동화
• CI 부분 적용
• DBA에게 통계 업무할 여유가 생긴 것 같아요.
사내 첫 지표 자율화 프로젝트!
22. 마치며..
• 뿌듯함..
• 론칭과 운영
• 성능 테스트 그럭저럭 큰탈없이
• 대용량 트래픽
• 종합적인 흐름, 아키텍처를 보는 안목
• 코드 리뷰, 협업, 주거니 받거니
23. 마치며..
• 아쉬움..
• 상용서버처럼 개발서버도…
• ORM, Sticky Session, L7
• 실시간 컨텐츠-소켓도 Java로..
• 소셜 컨텐츠는 MSA로 분리 했으면..
• CI를 믿고 DevOps!
• API 로그를 남겼으면
• 개발 언어, 환경에 대해 공유 노력을 많이 했어야
• 라이브러리는 좀 더 검토해야