배경서비스를 운영하면서 디버깅 시 어려움을 겪었습니다. 특히 예외가 발생하지 않았지만 오류인 경우를 파악하기 어려웠습니다. 예를 들어, 사용자는 A 옵션을 선택했다고 생각했으나 클라이언트 앱에서 잘못 처리되어 B로 전송되는 경우가 있었습니다. 이런 상황에서는 서버 입장에서 정상적으로 처리되기 때문에 예외 로그가 남지 않지만, 실제로는 사용자 의도와 다른 결과가 발생하는 문제였습니다. 기존에는 사용자가 어떤 요청을 했는지 로그 포맷이 따로 정해져 있지 않아 필요한 시점에 개별적으로 로그를 추가하는 방식으로 작업했기 때문에 다음과 같은 문제점이 있었습니다.API 요청/응답 흐름을 추적하기 어려움일관되지 않은 로그 형식문제 발생 시 원인 파악에 시간이 오래 걸림새로운 로그가 필요하다면 재배포가 필요함 해결 방..
제가 개발하고 있는 서비스는 이미지를 많이 다루기 때문에 썸네일 서버가 필수적입니다.기존에는 줌(zum.com)의 썸네일 서버를 함께 사용했으나,사용 중 이슈가 발생했고 외부 의존성을 제거하기 위해 썸네일 작업을 자체적으로 처리하기로 결정했습니다. 그래서 구글링을 통해 찾을 수 있었던 대표적인 라이브러리들을 비교해서 적합한 라이브러리를 선택하기로 했습니다. 비교 대상 라이브러리Graphics2D - Java 기본 APIImage.getScaledInstance() - Java 기본 APIImgscalr - 간단하고 효율적인 리사이징 전용 라이브러리Thumbnailator - 사용하기 쉽고 기능이 풍부한 라이브러리Marvin - 이미지 처리 프레임워크 이 중에서 저희 서비스는 Imgscalr를 사용하기로 ..
동생이 우리 집에 자주 놀러 오는데, 그때마다 "언제 놀러 오는 거야?", "언제 와서 언제 나가?"라는 질문을 계속 해야 했다. 이 과정을 반복하는 것이 너무 불편해서 사이드 프로젝트로 '우리집 예약 시스템'을 만들기로 했다. 사용한 테크 스택DB: MySQLBE: Java 17, Spring, jOOQFE: Next.js (v0.dev의 도움을 받았다)사내에서 JPA도 물론 사용하지만, jOOQ도 사용해보게 되었는데, jOOQ만의 매력이 있는 것 같아 사이드 프로젝트를 하면 꼭 사용해보고 싶었다. 카카오톡 알람으로 서로에게 알람 메시지를 보내려고 했는데, 이 부분은 회원가입이 이미 되어있는 유저들만 가능 해서 개발 하는 시간 내에 구현을 다 하지 못할 것 같아 빠르게 구현하기 위해 나에게 채팅 보내기..
CORS(Cross-Origin-Resource-Sharing)란?서로 다른 출처(Origin)에서 리소스를 공유하는 것을 말합니다. URL의 구조URL은 다음과 같은 6가지 요소로 구성됩니다.https://www.domain.com:8080/member?query=name&page=1#firsthttps:// www.domain.com :8080 /member ?query=name&page=1 #firstProtocol: https://Host: www.domain.comPort: :8080Path: /memberQuery string: ?query=name&page=1Fragment: #first여기서 Protocol, Host, Port 부분이 Origin(출처)입니다. CORS 설정이 되어 있지 ..
1. Redis와 Kafka를 활용해서 물건 구매 로직을 구현한 이유1. Redis를 이용한 실시간 재고 관리물건 구매 요청이 들어오면 Redis에서 물건 수량을 즉시 감소하도록 설계했습니다. 서비스는 예약된 시간에만 오픈되기 때문에, 서비스 시작 전 Redis에 물건의 초기 수량을 미리 저장해두는 방식으로 준비하고 있습니다. 현재는 물건 수량 감소 로직만 구현되어 있지만, 추후 서비스가 안정화되면 Redis에 물건 수량을 미리 저장하는 로직도 추가할 계획입니다.2. Kafka를 이용한 순차적 DB 반영한 번에 대량의 구매 요청이 들어올 경우를 대비해 Kafka를 사용하여 데이터의 순차 처리를 보장하고자 했습니다. 물건 구매 요청이 발생하면 해당 요청을 Kafka에 기록하고, Kafka의 Consumer..
서비스를 개발할 때 UUID를 Primary Key로 사용하는 방법이 있습니다. 하지만 저는 Member 클래스에만 UUID를 필드로 추가하였고, 그 이유를 정리해 보았습니다. 1. 왜 UUID 사용하지 않아야 할까?UUID는 전역적으로 고유한 식별자를 생성할 수 있어 데이터베이스의 ID로 자주 사용됩니다.하지만 프로젝트를 진행하면서 저장 공간 효율성과 검색 성능을 고려해 UUID를 ID로 사용하지 않기로 결정 했습니다. 1.1. 저장 공간 효율성UUID는 128비트로 길이가 길어, 숫자형 ID보다 더 많은 저장 공간을 차지합니다. 1.2. 검색 성능UUID는 랜덤하게 생성되기 때문에 데이터베이스에서 인덱스를 생성할 때 정렬되지 않은 상태로 저장됩니다.이로 인해 데이터베이스 검색 시 성능이 떨어질 수 있..