백승찬 주요 역량
Last updated: 27 days ago
# 성장 목표
- 기술적으로 Back-end 분야에 깊은 전문성을 기반으로 여러 기술 분야에도 꾸준히 관심을 두어 동료들과 함께 어떠한 문제도 해결할 수 있는 테크 전문가로 성장할 것입니다. Back-end 분야에서는 공통 게임플랫폼과 MMO게임서버를 개발/운영하며 대용량 트래픽 처리 경험을 쌓았고, 초기 스타트업에서 동료들과 함께 업무의 영역을 넓혀 웹/앱/NFT 등 비즈니스에 필요한 기술을 습득하고 Full-stack 을 지원하며 개발했습니다. 동료들에게 믿음을 주고 평생 동료가 되어 모두 함께 유저에게 임팩트를 주는 성공 경험을 만들고 싶습니다.
# 성격과 업무상 장단점
- 업무상 성격 : 일을 좋아하고 많이 하고싶기 때문에 어떻게하면 주어진 일을 빠르고 완벽히 해내어 또 다른 일을 해볼 수 있을지를 고민합니다.
- 업무가 완료되어도 추가적인 요구사항은 없을지 확장을 고려하고 Edge 케이스를 찾기 위해 리뷰하고 테스트케이스를 추가하여 안정성을 높입니다.
- 업무가 완료되면 내 동료의 업무도 이해하고 내 것처럼 찾아서 도와줍니다.
- 업무 중 불필요한 반복적인 작업은 기록하여 자동화하고, 동료들과 공유하여 팀 전체의 생산성을 높이고자 합니다.
- 단점으로는 누가 일을 끊어줘야 하고, 종종 일을 많이 하는 것을 좋게 보지 않는 동료가 있다면 스스로 스트레스를 받을 때가 있습니다.
- 업무 외 성격 : 몰입해서 업무를 하는 시간 외에는 친구/동료들과 어울려 노는 것을 좋아합니다.
- 모두에게 말을 걸어 관심을 주고 분위기를 띄우는 편입니다.
- 학창 시절부터 동아리 회장을 맡기도 하고, IT 동아리 YAPP을 수료한 IT 업계 400명 이상의 카톡 방 커뮤니티를 만들어 지금도 운영되고 있습니다.
- 다른 사람에게 이미지 : 업무에 몰입하며 열심히 노력하는 개발자로 인식되고 있습니다.
- 그 서비스를 담당하면 자꾸 표정들이 안 좋아서 승찬님한테 부탁해도 될지 생각났어요. (팀장님)
- 그렇게 재밌나? 인제 그만 집 좀 가자. (실장님)
- 프로젝트 초기 멤버로 적합한 이유는 승찬님이 새로운 것에 거부감이 없어서다. (팀장님/대표님)
- 자주 못나 오는 승찬이 형이지만 형이랑 술 마시면 제일 재밌다. (동아리 동생)
# 대용량 트래픽 처리 경험 (CCU 30만)
- CCU(동시접속자수) 약 30만의 대용량 트래픽을 처리하며 겪은 이슈들과 해결해 본 경험을 통해 안정적인 서비스를 설계/개발/운영할 수 있습니다.
- 역할별로 분산되고 각각이 Scale-out 되도록 설계된 환경에서 로그, CPU, Memory, APM, Connection Pool 등 적극적으로 모니터링하며 동료들과 함께 장애를 이겨내왔습니다.
- TPS, QPS를 높이고 결론적으로 유저에게 빠른 응답을 줄 수 있습니다.
- Lock을 최소화하기 위한 트랜잭션 분석과 효율적인 테이블 설계에 능숙합니다.
- RDBMS의 인덱스를 이해하고 Slow Query 모니터링을 하며 쿼리를 튜닝합니다.
- 캐싱을 고려할 땐 그에 따라 얼마나 메모리를 쓸지, 갱신 시점에 영향 등을 고려합니다. Cache stampede와 같은 현상을 해결한 경험이 있습니다.
- 필요시 트랜잭션 발생 시점에 따라 갱신되어 빠르게 조회할 수 있는 별도의 모델을 설계하거나 반정규화합니다.
- DeadLock이 발생하지 않도록 지속적 트랜잭션 개선에 대한 끊임없는 고민과 사라질 때까지 끈질기게 도전하며 업무가 과중할 때는 어느 테이블들이 참여하는 트랜잭션에 문제가 있는지 에러로그 통계를 자동화합니다.
- 도메인과 처리량에 따라 삽입이 많다면 RDBMS의 auto_increment 키 기반 대신 분산 환경을 커버하는 Key Generator 전략이나 NoSQL을 고려하고, 그에 따라 Front-end에서 UX를 고려한 API 설계를 합니다.
# 다양한 트러블슈팅 역량
- Memory Leak으로 인해 CPU 사용률 95% 가 지속된 이슈를 해결한 경험이 있습니다.
- Profiler를 통해 Memory 사용량을 확인해 보니 꽉 차서 우상향 지그재그 그래프 모양이었으며 Memory Leak으로 인해 GC가 무한히 돌고 있는 것을 직감했습니다.
- 1달 동안 무배포 상황에서 발생한 것이었기 때문에 재현이 오래 걸릴 수 있다고 판단되었고, 해당 노드에만 세션이 1만 명인 상황이었기에 즉시 새로운 노드를 띄우고 서버를 내려 임시로 CPU 사용률을 낮추는 방법을 사용했습니다.
- 병렬적으로 동료들과 함께 TTL 설정이 잘 안된 캐시가 있는지 찾거나, 개발 서버에 주기적인 Heap Dump를 자동화해 Memory Leak 지점을 찾고자 노력했습니다.
- 결국 Singleton인 세션매니저가 Zombie 세션을 제대로 제거하지 못해 발생한 문제였음을 확인했고 수정하여 해결했습니다.
- Slow Query로 인해 DB Connection이 급격히 증가하여 CPU 사용률 95% 가 지속된 이슈를 해결한 경험이 있습니다.
- 특정 api를 시작으로 다른 api들까지 점점 느려지는 현상을 발견했습니다.
- APM을 통해 먼저 느려진 api를 통해 Slow Query가 지속해서 발생하고 있음을 확인하였고, 쿼리를 튜닝하여 트랜잭션을 짧고 빠르게 처리하도록 해결했습니다.
- TCP Socket이 연결된 Stateful 서버 재부팅시 APM을 통해 응답시간이 급격히 올라가는 문제를 해결한 경험이 있습니다.
- 수천 명의 클라이언트가 재접속하며 아직 캐싱 되지 않은 공통 데이터를 동시에 재요청하는 Cache Stampede 현상이었으며, 서버 부팅 시점에 사전에 캐싱하는 로직으로 기존보다 APM 응답속도를 90% 줄였습니다.
- 그런데도 더 줄여야 할 10% 정도의 APM 응답시간은 수천 명의 클라이언트의 재접속 retry 시간을 3~5초로 랜덤하게 분산시키는 jitter 방식을 통해 근본적인 요청 수를 분산시켜 해결했습니다.
- TCP Socket이 연결된 Stateful 서버에서 클라이언트에게 새 버전 패치 알림 송신시 APM응답시간이 급격히 올라가는 문제를 해결한 경험이 있습니다.
- 새버전 패치 알림을 100명 단위로 분산시켜 송신하여 근본적인 급격한 요청 수를 줄였습니다.
- 다양한 Dead Lock을 경험했고 동료들과 함께 이슈를 해결한 경험이 있습니다.
- 발생 시 show innodb engine status 와 에러로그로 발생 지점을 찾아냅니다.
- 불필요한 Lock을 최소화하고, 트랜잭션 내에서 Lock을 획득할 데이터 순서를 정하여 DeadLock을 방지합니다.
- 또한, Queue 처리를 통해 하나의 갱신 트랜잭션으로 통일하여 DeadLock을 방지한 경험이 있습니다.
- 프로세스가 긴 트랜잭션이 종종 Lock Wait Timeout으로 인해 실패하는 문제를 해결한 경험이 있습니다.
- 트랜잭션 내에서 획득한 Lock 시간을 최소화하기 위해, 내부에 실시간 갱신이 필요 없는 업데이트들은 비동기로 분리하여 새 트랜잭션으로 실행함으로써 긴 트랜잭션을 짧게 줄여 Lock Wait Timeout을 방지했습니다.
- 선착순 처리 시 DB auto_increment 키를 이용해 큐를 구성하고 배치처리를 했음에도 종종 Lock Wait Timeout으로 인해 실패하는 문제를 해결한 경험이 있습니다.
- 스케줄러가 insert 된 레코드를 가져와 Lock을 획득하고 상태처리를 하는데, auto_increment로 insert 시 테이블에 Lock을 획득하여 다른 스케줄러가 대기하게 되는 문제였습니다. (일반 요청에 의한 트랜잭션도 해당 레코드에 Lock을 획득할 수 있는 상황)
- 논의를 통해 운영적으로 동일한 millisecond에 대해서는 순서를 매길 필요 없게 되어 auto_increment 대신 timestamp를 조합한 key로 큐 테이블을 재구성해 해결했습니다.
# Mission-Critical 데이터 처리 역량
- 포인트 시스템
- 상품을 현금뿐만 아니라 포인트로도 구매할 수 있었기에 사실상 포인트가 일정의 현금화 가치가 있었고 발행량이 너무 많으면 회사의 부채로 작용할 수 있습니다.
- 유저의 행위에 따라 트랜잭션을 명확히 하여 포인트를 발행하고, 사용할 수 있도록 개발/운영했습니다.
- 포인트는 여러 종류가 있을 수 있으며 상호 간 일정 비율로 교환할 수 있어, 포인트를 타입별 추상화하여 관리합니다.
- 운영이 오래되면 포인트 발행처가 다양해지고 관리하기 힘들어지기 때문에, 발행 이벤트 방식별로 로그 테이블을 설계하고 Admin 툴에서 추적할 수 있도록 했습니다.
- 1만 개의 재고를 팔기 위해 상점을 현지화하고 10개국 환율을 적용해 판매한 경험
- 아이돌 팬들에게 인기가 많아 트위터에 업로드하면 글로벌 팬들의 주문이 첫날 5천 건이 폭주하는 상황이 발생했으며, CPU 사용률 추이를 보고 서버를 Scale-out 하였습니다.
- 일일 판매 가능 재고량을 맞추어 주문받고, 접속 국가에 따른 환율을 적용해 노출하고 주문을 받고, Admin 툴을 통해 배송 상태를 갱신하는 시스템을 개발했습니다.
- 해외 유저의 주소를 잘못 입력받아 들어온 CS를 근본적으로 해결하기 위해 Google Place API 기반의 AutoComplete input을 도입했습니다.
- 유저가 오프라인으로 구매한 물품을 온라인에 인증 경험 (O2O)
- 스타트업에서 아이돌 팬덤 플랫폼 프로젝트에서 팬이 오프라인으로 구매한 아이돌의 앨범 내 고유 QR코드로 팬 인증 시스템을 개발하고 운영했습니다.
- 유저가 예측 불가능한 고유키를 발행해 실제 오프라인 앨범 내에 등록해서 전 세계 매장으로 판매되기에 발행한 고유키를 잃어버리면 안되며, 구매한 유저만이 인증할 수 있어야 했습니다.
- 선착순 경품 이벤트
- 고가의 유명 NFT 들을 커뮤니티 유저들에게 선착순으로 나눠주고, 유저들이 트위터에 업로드로 자랑하는 이벤트이기 때문에 중복 당첨이나 누락 없이 정확해야 합니다.
- Lock을 최소화 하기 위 요청 큐 테이블과 선착순 판정 스케줄러를 구성하고 자연스러운 연출을 위해 비동기 API를 설계하여 CS 없이 성공적으로 운영했습니다.
# 테스트케이스 작성에 미치게 된 이유
- 리팩토링 실패 경험
- 테스트케이스를 작성하면 리팩토링이 쉬워지며, 코드의 변경에 대한 안정성과 개발자가 자신감을 느끼고 빠른 속도로 생산성을 올릴 수 있습니다.
- SaaS 플랫폼 개발팀에서 테스트케이스가 단 하나도 없는 10만 line의 Legacy 프로젝트 담당을 맡았을 때, 약 3천 개의 테스트로 테스트커버리지를 60% 이상으로 높이고 리팩토링을 진행하며 SaaS 이용 개발팀에 안정성을 홍보할 수 있었습니다.
- 누적 형 컬럼 폭증 사건 경험
- 1회 or 2회 실행 시에는 문제가 없었지만, 3회 실행 시에는 값이 폭증하는 이슈가 발생했습니다.
- 이후 누적 형 데이터의 경우 3회 이상 실행하여 기댓값을 검증하는 테스트케이스를 꼭 작성해 미리 예방할 수 있습니다.
- 사이드이팩트 빠른 피드백
- 젠킨스 CI/CD를 통해 빌드/테스트/배포 자동화를 구축하였고, 테스트케이스를 작성하여 빠른 피드백을 받아 개발 속도를 높였습니다.
- 테스트 자동화가 안 되는 코드는 테스트를 가능하게 작성
- 시스템에서 제공되는 현재시간 객체를 직접 사용하기보다는, 테스트케이스에서 전역적으로 현재시간을 주입할 수 있는 Wrapping 된 시간을 사용하여 특정 시간 발생할 이벤트를 테스트할 수 있도록 작성합니다.
- 여러 트랜잭션이 중첩되어 동작하는 기능은 별도의 TransactionRunner를 작성해 테스트케이스인 경우 하나의 트랜잭션으로 실행해 검증할 수 있도록 작성합니다.
- 배치 스케줄러는 해당 Task를 테스트케이스에서 동기적으로 직접 호출해 실행할 수 있도록 스케줄 Trigger 로직과 Task를 분리해서 작성합니다.
- 이슈 재현과 증명을 위한 도구
- 이슈 발생 시 먼저 테스트케이스로 재현하고, 동료와 기술적인 논의를 할 때도 테스트케이스를 통해 증명하며 효율적인 의사소통을 할 수 있었습니다.
# 업무 개선 / 운영 자동화 역량 (업무 개선과 품질을 보증하며 본질에 집중)
매번 똑같은 작업을 반복하는 것은 신경이 쓰이게 하여 실수를 유발할 수 있습니다. 손으로 10초 정도 걸리는 일을 하루 종일 시간을 투자해 스크립트를 작성하고 자동화하는 것을 선호하며 제품의 품질이 보장된다고 믿습니다. 또한 동료들의 업무를 스마트하게 개선하여 팀 전체의 생산성을 올리는 것을 즐깁니다.
- Admin 개발/운영 경험
- 사내 여러 프로젝트가 사용하는 공용 플랫폼 (채팅서버/버전체크서버/데이터패치서버) 들의 Admin 툴을 개발/운영했습니다.
- 게임 서버의 dev/qa/live 환경별 env 데이터를 갱신하는 Admin 툴을 개발/운영했습니다.
- 커머스 운영을 위해 주문 상태, 배송지 출력, 배송 시 상태 변경 등을 할 수 있는 Admin 페이지를 개발/운영했습니다.
- 사내에서 유저 지표, 매출 등을 한눈에 볼 수 있는 대시보드를 개발/운영했습니다.
- 플랫폼 유저의 DIY 게임 생성 요청을 승인/거절하는 Admin 페이지를 개발/운영했습니다.
- 기획/운영팀의 업무 효율 개선
- 기획자분의 서비스 로직 개선을 돕기 위해, 설정 데이터가 담긴 Excel 파일이 업로드되면 서버가 데이터를 읽어 DB에 저장하고 캐시를 갱신하도록 자동화해 빠르게 여러 번 실험해 볼 수 있도록 제공했습니다.
- 업로드된 데이터로 인해 게임의 Skill Tree 가 끊겼을 경우 자동으로 끊긴 부분을 찾아 알림을 보냈습니다.
- Critical 한 리워드 데이터의 정합성을 체크해주는 툴을 개발해 운영팀이 데이터를 자신감 있게 다룰 수 있도록 제공했습니다.
- 100만 개의 데이터를 한 번에 삽입할 수 있는 Admin 페이지를 개발했습니다.
- Front-end 개발팀의 업무 효율 개선
- 수정된 결과물을 배포된 환경에서 언제나 확인할 수 있도록, main 브랜치로 git push 시 AWS S3 업로드와 CloudFront캐시 갱신을 자동으로 처리하는 gitlab ci 스크립트를 작성했습니다.
- 스타트업에서 CS가 들어오기 전에 Front-end 팀이 먼저 확인해서 해결할 수 있도록 Sentry를 도입해 SDK를 심고 알람을 생성했습니다.
- 커뮤니케이션 자동화
- 서버 재배포 시 동료 간 커뮤니케이션 자동화를 위해, 배포 대기시간을 입력할 수 있게 하고 (디폴트 대기시간 30초) 사내 메신저에 먼저 알림을 보내고 30초 뒤에 재배포되도록 스크립트를 개선했습니다.
- Protobuf 스키마에 기존 메시지/필드가 변경되거나 삭제 시 모두가 알 수 있도록 변경 사항을 사내 메신저에 알림을 보내는 스크립트를 작성했습니다.
- 코드 리뷰 프로세스 개선
- 코드 리뷰 전에 해당 브랜치에서 먼저 Spotbugs플러그인과 적절한 bug filter를 적용해 정적분석을 자동화하고 리포팅하여 코드 리뷰어가 더욱 효율적으로 코드 리뷰를 할 수 있도록 도와주었습니다.
- 너무 많은 테스트케이스를 가진 Admin 툴의 GUI 테스트 자동화
- 여러 프로젝트에서 공통으로 사용하는 Admin 툴에 코드 수정이 있을 때 Front-end에 깊은 depth에 사이드이팩트가 자주 발생하고 케이스가 많아 테스트에 시간이 너무 오래 걸리는 문제가 있었습니다.
이를 위해 Selenium을 이용해 JUnit으로 로그인부터 해당 depth까지 진입하고 모든 케이스들을 전부 테스트해 보도록 테스트케이스를 자동화했습니다.
실제 브라우저를 실행하고 gui테스트가 가능하도록 기존의 linux 빌드머신에서 mac 머신으로 변경해 구축했습니다.
- 여러 프로젝트에서 공통으로 사용하는 Admin 툴에 코드 수정이 있을 때 Front-end에 깊은 depth에 사이드이팩트가 자주 발생하고 케이스가 많아 테스트에 시간이 너무 오래 걸리는 문제가 있었습니다.
- 종종 발생하는 Dead Lock과 Lock Wait 이슈들의 해결 우선순위를 정하기 위한 자동화
- Dead Lock이나 Lock Wait이 재현하기 힘들게 종종 발생하는 경우 업무가 과중한 상태에서 팀원들이 전부 붙잡기 힘든 상태였습니다.
- 그리고 대부분 특정 트랜잭션에 반복적으로 나타나는 경향이 있다고 판단되어 에러 로그 수집 테이블에서 특정 트랜잭션들의 발생 빈도를 확인하기 위해, 주 단위로 발생 빈도가 높은 테이블 그룹을 묶어 우선순위를 정하여 사내 메신저에 알림을 보내는 스크립트를 작성했습니다.
# 사내 공통 라이브러리 개발 / 공통 플랫폼 개발 역량
- 오픈소스 라이브러리를 개선해 품질과 생산성 개선
- 직렬화 라이브러리 Flatbuffers가 생성한 Java 소스코드가 Builder Pattern을 제공해 주지 않아 모든 패킷마다 응답 객체 생성 코드에 변수명을 짓고 장황해지는 문제가 있었습니다.
이를 위해 Flatbuffers Java 소스코드 생성 후 별도의 builder 패키지에 Builder Pattern 소스코드를 생성하는 라이브러리를 개발해 사내 프로젝트에 적용했습니다.
- 직렬화 라이브러리 Flatbuffers가 생성한 Java 소스코드가 Builder Pattern을 제공해 주지 않아 모든 패킷마다 응답 객체 생성 코드에 변수명을 짓고 장황해지는 문제가 있었습니다.
- 공통 플랫폼 개발
- R&D 조직에서 모든 라이브 서비스에 공통적인 채팅 및 알림 서버, 버전 체크 및 데이터 패치를 여러 라이브 서비스에 제공하도록 개발/운영했습니다.
- 많은 트래픽을 처리해야 하는 특성이 있습니다. 다양한 이슈를 해결해 본 경험이 있으며 이를 통해 안정적인 서비스를 설계/개발/운영할 수 있습니다.
- 여러 서비스에서 서로 다른 요구사항을 위해 환경변수가 많은 특성이 있습니다. 테스트케이스를 꼼꼼히 작성하여 품질을 보증했습니다.
# 신규 프로젝트 초기 멤버 경험, 초기 스타트업 재직 경험
- 다양한 규모 개발조직 경험
- 넷마블F&C에서 대규모 개발 조직 내에서 게임서버, 게임플랫폼을 개발하고 운영한 경험이 있습니다.
- 스타트업에서 2~4명의 개발 조직 내에서 팬덤 플랫폼, SNS, Gig Economy 플랫폼을 개발하고 운영한 경험이 있습니다.
- CI/CD 구축 경험
- 넷마블F&C에서 프로젝트 규모가 커짐에 따라 빌드시스템과 Jenkins Job을 개선하고, 신규 게임프로젝트에서 Jenkins Pipeline으로 구축했습니다.
- 스타트업에서는 Gitlab CI 로 빌드 및 CDN 까지 배포를 자동화했습니다.
- CI단계에서 코드 정적분석, 테스트케이스 실행, 이미지 푸쉬를 자동화하고, CD단계에서 모델데이터 갱신부터 원격지 서버 배포까지 자동화했습니다.
- 운영 서버 구축
- 스타트업에서 AWS ECS를 활용해 프로젝트/환경별 클러스터를 구성해 운영했습니다.
- 자본이 부족한 상황에서의 인프라 선정 경험
- git 레파지토리로써 gitlab을 사용할지 github를 사용할지, 불필요하게 유지되고 있는 인프라가 있는지 정리해 생산성을 고려한 최소 비용을 산정하여 적용한 경험이 있습니다.
- Stand alone으로 운영 가능한 개발 환경은 비용 절감을 위해 고정 비용인 AWS light sail 인스턴스를 활용하고 프로젝트별로 DB 스키마를 분리해 운영했습니다.
- 서비스 매각 경험
- 스타트업에서 개발한 프로젝트가 해외 기업에 매각되어 타사 개발자들과 소통하며 직접 마이그레이션과 문서화/인수인계까지 완료한 경험이 있습니다.
- 프로젝트 기반 전환 경험
- Native App에서 Full Web으로 전환 : 스타트업에서 해외여행객들 대상 앱 설치에 거부감이 있다는 피드백을 수용하여 Full Web으로 변경하며 인증 sdk를 웹으로 변경해 재개발한 경험이 있습니다.
- Pure React.js 에서 Next.js으로 전환 : Gig Economy 플랫폼을 개발하며 판매자 프로필의 SEO가 곧 플랫폼의 경쟁력이라는 피드백을 수용하여 Next.js 로 클라이언트사이드 인증을 서버사이드로 변경한 경험이 있습니다.
- 게임 개발시 svn에서 git으로 전환 경험이 있으며 lfs를 구성해 본 경험이 있습니다.
글로벌 서비스 개발 역량 (90% 해외 매출)
- 서로 다른 언어/시간대/환율의 유저들을 대상으로 서비스하며 안정적인 글로벌 서비스를 설계/개발/운영할 수 있습니다.
- GMT 시간 기반으로 MMO 게임서버를 개발/운영하며 프로젝트의 90% 이상의 매출은 북미/중동 등 해외 고객이었습니다.
- 또한 게임 플랫폼 엔지니어로서 15개 언어 번역키 발급/관리/배포 시스템을 SaaS로 개발하고 운영해 본 경험도 있습니다.
- 위 역량으로, 스타트업에서 상점을 현지화하고 환율을 적용해 글로벌 유저들에게 제품을 주문/결제/배송하는 시스템을 개발/운영해 회사의 목표였던 약 1만 개의 재고를 안정적으로 판매했습니다.
내가 만드는 서비스의 열렬한 유저가 되고자 노력합니다.
- 제가 만드는 게임에 소비하고, 제가 만드는 팬덤 플랫폼에 입점한 아이돌의 콘서트 티켓과 굿즈로 사무실 자리를 채우고, 제가 만드는 NFT 커뮤니티에서 영어로 소통하며 유저들과 친구가 되었습니다.
- 개발자가 공급자가 아닌 유저의 시각으로 바라봐야 UX 친화적인 API를 설계할 수 있다고 믿습니다.