본문 바로가기

프로젝트

(35)
AWS 대신 Mac mini로 홈서버 구축하기: Minikube로 애플리케이션 이전 DB를 Minikube로 옮긴 이후에 애플리케이션을 이전을 진행하기로 했습니다. 이전하면서 CD 환경도 같이 구성을 하였습니다. 하면서 중요하게 생각했던 부분들에 대해서 작성해보려고 합니다.이미지 기반 배포 전략기존에는 애플리케이션을 컨테이너 기반으로 실행하고 있었기 때문에, 이미지를 어디에 저장하고 어떻게 가져다 쓸지가 핵심 이슈였습니다. 가장 먼저 고려한 저장소는 Docker Hub였지만, 무료로 사용할 수 있는 범위가 제한적이라 다른 대안을 찾아야 했습니다.그래서 선택한 것이 GitHub Container Registry(GHCR)입니다. ✔ GitHub 프로젝트와의 연동이 용이 ✔ 퍼블릭 저장소 기준으로는 비용이 무료 ✔ GitHub Actions와의 통합도 용이GitHub Actions..
AWS 대신 Mac mini로 홈서버 구축하기: Minikube로 MySQL 이전 Mac mini 홈서버로 전환 이유사이드 프로젝트에서 AWS 비용이 매달 약 10만 원이 발생하다 보니, 자연스럽게 대체재를 고민하게 되었습니다. 그러던 중 이미 보유하고 있던 Mac mini(M1) 기기를 활용해 홈서버를 구축해 보기로 했습니다. 전기세 등을 고려했을 때 월 1,000원 이하로 유지 가능하다는 점도 큰 매력으로 다가왔습니다.1. 유지하고 이전할 서비스 구분이미지, 동영상 등 유저가 등록한 데이터를 저장할 공간은 여전히 필요하므로 S3는 그대로 유지하기로 했습니다. 반면 가장 비용이 많이 드는 EC2에 배포된 자바 애플리케이션과 RDS(MySQL)는 홈 서버로 이전하기로 했습니다. 이 중 MySQL을 우선적으로 이전하기로 했습니다. 추가로 비용 문제로 운영하지 못했던 테스트 환경도 함께 ..
어뷰징 대응의 시작 - 고정 윈도우 기반 Rate Limit 시범 운영기 1. 투표의 신뢰를 지키기 위한 첫 대응 이전 시상식 기간 중 매크로 사용과 다중 계정 생성 정황이 포착되었고, 행동이 이상한 일부 유저에 대해 CS 인입 및 커뮤니티 내 매크로 사용법 공유 사례도 있었습니다.회사의 투표 시스템 신뢰성 강화를 위해, 이러한 어뷰징 유저 탐지 및 단속의 필요성이 높아졌습니다. 2. 작게 시작한 시범 운영, 리스크를 최소화하다 이번 시상식에서 투표 기간 중에 시범적으로 어뷰징 탐지 시스템을 만들어 운영해보기로 했습니다. 처음 적용하는 시스템이면서 해당 시스템이 우리가 예상한대로 동작했을 때 이점보다, 동작하지 않았을 때 리스크가 더 크다고 판단이 되었기 때문입니다. 고정 윈도우 기반의 간단한 탐지 체계를 구성해 특이 행동을 모니터링하고, 개발자가 수동으로 판단 및 조치하는 ..
반복되는 장애, 우리는 어떻게 대응하고 있을까? 1. 장애 대응 과정에서 보였던 한계들우리 팀은 주로 고객센터(CS) 인입을 통해 장애를 인지하곤 했다. CS 인입이 없으면 문제를 모르는 경우도 많았고, 문제가 확인된 이후에는 개발팀이 임시 조치를 한 뒤 사용자에게 안내하는 방식이 반복되었다. 처음에는, 이 방식이 자연스럽다고 여겼지만 반복될수록 여러 문제점이 보이기 시작했다. 💢 CS 인입 정보 공유 지연예를 들어 5월 19일에 들어온 고객 문의가 4~5일 뒤에야 저에게 전달되었고, 그사이 대응이 늦어질 수밖에 없었다. 💢 상황 공유의 부재개발팀에서 조치하고 있는지, 근본 원인이 무엇인지 등 중요한 정보가 CS팀과 공유되지 않았다. 이에 따라 CS팀은 사용자에게 명확한 설명을 할 수 없어 불완전한 대응으로 이어졌다. 💢 임시 조치 후 회고 없음..
개발 환경의 시간대 차이가 만든 버그: LocalDateTime 이슈 해결기 1. 문제 사항중국 음원 사이트에서 데이터를 수집해 차트 정보를 생성하는 스크래핑 로직이 있었는데 로컬에선 정상 작동하지만 서버 환경에서는 예상과 다르게 동작하는 이슈가 있었습니다. 스크래핑 대상 사이트는 요청 시 현재 시간을 기준으로 ±15분 범위 내의 요청만 허용하는 정책을 갖고 있었고 이 로직에서는 해당 기준에 맞는 현재 시간을 생성해 요청 값에 포함시켜야 했습니다. 함께 작업하던 동료가 시간 생성 방식에 문제가 있을 수도 있다는 점을 짚어주었고 함께 해당 부분을 확인해 보았습니다. 실제로 시간을 생성하는 로직에서 LocalDateTime.now()를 사용하고 있었고 이로 인해 로컬(UTC+9)과 서버(UTC)의 시간대 차이로 서버에선 조건을 만족하지 못하는 요청이 만들어지고 있었습니다. 이 문제를..
코틀린 Data Class와 Mybatis 같이 사용할 때 주의점 Mybatis 기본 생성자가 없는 경우Mybatis에서는 기본 생성자가 없는 경우 Mapper에 정의된 규칙을 사용하지 않는다. 주 생성자의 파라미터와 조회해 온 데이터를 순서대로 매핑을 한다. DefaultResultSetHandler 클래스에서 createResultObject를 통해서 확인을 할 수 있다.hasDefaultConstructor 메서드는 파라미터 개수가 0인 생성자 여부를 알려주며, 이것이 충족하지 않을 때 Mybatis에서 정한 규칙에 따라 자동으로 객체와 데이터를 매핑을 해준다.   ✅ DefaultResultSetHandler.java private Object createResultObject(...){ if (hasTypeHandlerForResultObject(rsw, r..
Redis Scan으로 Key 삭제하기 무엇을 하고 싶은가?버그 수정 및 적용을 위해 실서버 환경에서 Redis 캐시(데이터) 갱신이 필요했다. 캐시 전략은 Cache-aside Pattern을 사용하고 있기 때문에 삭제를 통해 필요한 유저만 갱신하기로 했다. 패턴 조회를 통해 필요한 버그에 관련된 key값만 골라 삭제해 주기로 했다. 어떻게 할 수 있는가?패턴을 통한 삭제는 Redis 명령어 keys, scan을 통해서 처리를 할 수 있다. keys를 사용하면 전체 키를 조회해서 삭제를 할 수 있지만, Redis는 기본적으로 싱글 스레드로 동작을 하기 때문에 key가 많을 경우 다른 요청을 받아서 처리할 수 없는 특징이 있다. 실제 운영이 되고 있는 Redis에 keys를 날릴 경우 서비스에 장애를 가져다줄 수 있다. 운영 서비스에 영향을 ..
시간 유효성 검사에서 시간 값 생성 시점 생각하기API 요청은 상품의 만료 기간이 "12:00"라고 가정 했을 때 "11:59 59.959"에 들어온 요청은 상품을 사용할 수 있도록 해주어야 하는 것일까? 사용자 입장에서는 정상적으로 상품 사용이 가능해야 한다. 회사 서비스에서는 저와 같은 상황을 연출하고 테스트 했을 때 상품을 사용할 수 없었다. 이유는 비교해야 하는 현재 시간을 API 호출 시점이 아닌 유효성을 검사할 때 생성해서 사용을 하고 있었기 때문이다. 유효성으로 가는 과정에서 "12:00"가 지나버린 것이다.사용자를 중점으로 이루어져야 하는 것이 서비스이기에 위와 같은 경우 상품을 사용할 수 있도록 해주는 것이 맞는 것 같다. 그래서 문제가 되는 기능이라고 생각을 해 수정 요청을 했다. 생성 시점은 언제로?생성 시점은 언제로 해야할..