전체 글 91

헥사고날 아키텍처

포트 - 벽에 달린 콘센트 즉 '표준 규격'이다 규격이란 인터페이스 일 뿐 스스로 아무런 일도 하지 않는다.도메인 - 드라이기의 모터처럼 실제 '일'을한다어댑터 - 플러그 또는 가전제품 본체 외부 기술을 뜻한다 포트라는 표준 규격에 맞게 제작되어 도메인에 전기를 전달해준다. in-어댑터 : Driving Adapter - 주도하는 어댑터외부의 요청을 받아 애플리케이션을 주도(Drive)하고 도메인이 이해할 수 있는 형태로 바꿔 in-port(UseCase) 를 호출한다예시로 : 컨트롤러가 있다 - HTTP 요청을 받아 JSON 데이터를 DTO객체로 변환한뒤 도메인 로직을 실행한다.두번째 예시는 메시지 큐 리스너다 - 메시지를 받아서 도메인이 이해할 수 있는 명령으로 바꿔 UseCase를 호출한다. ou..

아키텍처 2025.08.12

헥사고날 아키텍처로 가기위한 기존 코드에 solid 적용 완료

헥사고날 아키텍처로의 전환 이전에 기본 soild를 준수하기 위해서수만 줄의 코드를 수정하는 대공사를 진행했습니다. 개선 전 디렉토리 구조 ├── controller/ # REST API 컨트롤러 │ ├── AdminController.java # 관리자 기능 │ ├── AuthController.java # 인증/로그인 │ ├── CommentController.java # 댓글 관리 │ ├── NotificationController.java # 알림 기능 │ ├── PaperController.java # 롤링페이퍼 │ ├── PostController.java # 게시글 관리 │ ..

개발 2025.08.11

Cache Aside, Write Around

데이터를 캐싱할 때 사용하는 전략 Cache AsideLook Aside 또는 Lazy Loading이라고도 부른다 1. 무언가를 조회할 때 캐시에 먼저 요청보내고 없으면 DB에 요청보낸다2. 그리고 DB에서 데이터를 응답한 뒤에 레디스에 데이터를 저장하는 전략 캐시에 데이터가있으면 Cache Hit캐시에 데이터가없으면 Cache Miss Write Aroundcache Aside 전략과 자주 같이 활용 됨Cache Aside가 데이터 조회에 대한 전략이면 Wirte Around는 저장, 수정, 삭제에 대한 전략 간단하다 저장할 때 레디스에 저장하지않고 데이터베이스에만 저장하는 전략이다 Cache Aside와 Write Around를 같이 쓸 때 한계점1. 캐시된 데이터와 DB 데이터가 일치하지 않을 수..

레디스 기본 명령어

Set키, 값 을 저장한다127.0.0.1:6379> set jaeik:1 "jaeik good"OK127.0.0.1:6379> set jaeik:2 jaeikOK띄워쓰기가 필요하면 쌍따옴표로 막아야함 get키로 값을 반환한다127.0.0.1:6379> get jaeik:1"jaeik good"127.0.0.1:6379> get jaeik:2"jaeik" keys모든 키를 반환한다 여기선 잘못쳐서 jaeik이 아니라 jeaik도 하나 끼어들어감 ㅠ127.0.0.1:6379> keys *1) "jeaik:2"2) "jaeik:1"3) "jaeik:2"127.0.0.1:6379> del키로 키와값을 삭제한다127.0.0.1:6379> del jaeik:2(integer) 1127.0.0.1:6379> key..

서버 비상시 AI 분석 실시간 메시지 전송 시스템 구현

기존에는 Scouter APM을 통해 서버를 모니터링했지만, 24시간 상시 모니터링은 현실적으로 어려웠습니다. 실제로 OOM으로 서버가 종료되었을 때, 이를 몇 시간 후에나 인지하여 서비스 장애로 이어진 경험이 있습니다. 이러한 문제에 직면하며 단순한 서버 상태 알림을 넘어, 문제의 원인과 심각성을 즉시 파악하고 대응할 수 있는 지능형 모니터링 시스템의 필요성을 느꼈습니다. 이에 저는 GPT 기반의 서버 모니터링 AI를 개발하여 모니터링 부담을 줄이고, 신속하고 정확한 문제 해결을 돕고자 했습니다. 처음에는 서버 내부 API로 GPT를 호출하려 했으나 서버가 죽으면 응답을 할 수 없고 설령 서버가 죽지 않더라도 트래픽에 요청이 느려질 가능성이 있었습니다. 서버 진단 기능이 서버 내부에 있는 것은 잘못..

개발 2025.08.07

아키텍처 관점에서 Repository 계층의 접근 범위에 대한 고민 (2025년 6월 15일)

2025년 6월 15일의 고민 노션에서 옮겨오고 있습니다. 고민 최근 데이터엑세스 코드를 수정하면서 레포지토리 계층에서 DTO나 인터페이스에 접근하는 것이 아키텍처에 어긋나는지 고민에 빠졌다. 일반적으론 Repository에서 바로 비즈니스 로직을 거치지않고 바로 DTO에 접근하는 것은 맞지 않다고 느껴진다. 하지만 그건 JPA의 관점이 아닌가? 마이바티스는 일반적으로 바로 DTO에 접근하는데? JPA의 더티체킹에 익숙해져서 서비스 -> 엔티티 -> 레포지토리 구조에 빠져버린건가? 특히 QueryDSL의 프로젝션 기능을 사용하면 복잡한 조회 쿼리도 깔끔하게 DTO로 매핑할 수 있는데, 이런 경우에도 아키텍처 원칙 때문에 포기해야 하나 하는 고민이 들었다. 같은 애플리케이션에서 기술에 따라 다른 패턴을 사..

알림 읽음 처리에 대한 고민 (2025년 4월 29일)

2025년 4월 29일의 고민 노션에서 옮겨오고 있습니다 고민 알림을 읽을 때 마다 DB에서 update 쿼리를 요청하면 불 필요한 부하가 생긴다.불 필요한 부하라기엔 필요한 로직일 수도 있지만 알림을 읽는다는 역할의 중요성을 생각해 보았을 때 차후에 만약 사용자가 많아진다면 대안을 생각하는 것이 필요한 부분이라고 생각한다.당장은 사용자가 적어 문제가 되지 않지만 만약 사용자가 많아진다면? 스케일 아웃이나 스케일 업은 피할 수 없는 선택지가 되겠지만 그 선택을 하기전까진 대안과 최적화로 할 수 있는만큼은 기존 서버만으로 트래픽을 받고 싶다. 해결알림 읽음과 삭제 상태를 프론트의 로컬 스토리지에서 관리하고 5분마다 서버로 전송하여 DB에 반영하는 방식을 선택했다.그리고 사용자가 5분도 이용하지 않고 떠났을..

게시판 유저 상호작용 부하 테스트 및 성능 개선

목차1. 서론1.1 테스트 목적1.2 핵심 성과 요약 및 개선 범위2. 부하 테스트 수행 및 문제점 분석2.1 테스트 환경 및 시나리오2.2 테스트 결과 요약2.3 정상 요소2.4 문제점 분석 (우선순위별)2.4.1 우선순위 상: N+1 쿼리 문제 (병목 지점)2.4.2 우선순위 중: 20초 Stop-The-World GC, 인덱스 미설정2.4.3 우선순위 하: DB 커넥션 부족 현상3. 성능 개선 구현 및 검증3.1 우선순위 상 개선: N+1 문제 해결3.2 우선순위 중 개선: GC 부하 감소 및 인덱스 설계3.3 우선순위 하 개선: DB 커넥션 최적화4. 성능 개선 효과 검증4.1 개선 전후 성능 비교4.2 목표 달성도 평가4.3 API별 상세 개선 결과5. 결론 및 향후 과제5.1 개선 성과 종합5..

롤링페이퍼 유저 상호작용 부하 테스트 및 성능 개선

롤링페이퍼 유저 상호작용 부하 테스트 및 성능 개선 종합 리포트 목차1. 서론 1.1 테스트 목적 1.2 핵심 성과 요약 및 개선 범위 2. 부하 테스트 수행 및 문제점 분석 2.1 테스트 환경 및 시나리오 2.2 테스트 결과 요약 2.3 문제점 분석 (우선 순위 별) 2.3.1 우선순위 상: Connection Refused (병목 지점) 2.3.2 우선순위 중: CPU 사용량 급상승의 원인 2.3.3 우선순위 하: GC 스파이크, N+1 문제 및 불 필요 컬럼 조회, 동기화 이슈 3. 성능 개선 구현 및 검증 3.1 우선순위 상 개선: Connection Refused 해결 3.2 우선순위 중 개선: DB 커넥션 최적화 ..

추가적인 보안 관련 고민 (2025년 4월 26일)

2025년 4월 26일의 고민 노션에서 옮겨오고 있습니다. 고민1차 테스트 서버에서 모의 해킹결과 GET요청에 민감 데이터를 넣어서 프론트에서 민감데이터 처리를 하는 바람에 서버로 직접 요청해서 응답을 탈취하는 경우가 있었음. HTTPONLY쿠키 SAMESITE STRICT SECURE 설정 다 했기 때문에 CSRF나 쿠키탈취 가능성은 적음 그리고 서버 시큐리티에서 권한 검사 함 다만 서버에 직접 요청이 가능한 점 프론트를 통해서만 서버에 접근 가능하는 것도 생각해보았지만 ELB에서는 루트를 분기하는 기능만 있고 서버에 접근해도 신원검사와 보안을 해놓았기 때문에 신원을 검사하지 않는 GET요청의 민감 데이터를 내려주지 않으면 될 듯 함해결 민감데이터 처리는 프론트에서 하지말고 서버에서 해야함 그리고 서버..