[SpringBoot] 로그에 찍힌 의문의 PROPFIND 요청, 해킹 공격일까? (feat. Spring Security)
·
ServerDev/SpringBoot
서버 로그에 찍힌 의문의 'PROPFIND', 온프레미스 서버를 지키기 위한 고군분투기평화롭게 서버 로그를 확인하던 중, 한 번도 본 적 없는 낯선 에러가 제 눈을 사로잡았습니다.운영 중인 서버 로그에 평소라면 보이지 않아야 할 IP와 생소한 HTTP 메서드가 기록되어 있더군요. 바로 이런 내용이었습니다. (그동안 회사 내부망에서만 테스트하던 프로젝트를 드디어 운영 환경으로 전환하고, 외부망에 공개했습니다. 이제 본격적인 운영인가 싶어 설레는 마음으로 로그를 확인하던 차에, 평소 보지 못했던 기괴한(?) 에러가.. ) org.springframework.security.web.firewall.RequestRejectedException: The request was rejected because the ..
[Architecture] MSA(Microservices Architecture), 무조건 정답일까? (Monolith vs Modular Monolith 비교)
·
Architecture
개발자 채용 공고를 보면 우대사항에 빠지지 않고 등장하는 단어가 있습니다. 바로 MSA (Microservices Architecture)입니다. 넷플릭스, 아마존 같은 테크 자이언트들이 MSA를 통해 엄청난 트래픽을 감당한다는 성공 사례가 알려지면서, MSA로 구성된 서비스를 많이 접했습니다. 오늘은 제가 느낀 MSA의 핵심 개념과 치명적인 단점, 그리고 현실적인 대안인 Modular Monolith에 대해 알아보겠습니다.(공부하며 느낀 개인적인 견해의 글입니다..)1. MSA란 무엇인가?기존의 전통적인 웹 개발 방식은 Monolithic Architecture(모놀리식 아키텍처)라고 부릅니다. 하나의 거대한 프로젝트 안에 사용자 관리, 주문, 결제, 배송 등 모든 기능이 다 들어있는 형태죠. 반면 M..
[Spring Boot 멀티모듈] domain-common 빌드 실패 원인과 해결 과정 정리 - Lombok, JPA @Entity 인식 안됨, Gradle 의존성 삽질기
·
ServerDev/SpringBoot
Spring Boot + Gradle 기반의 멀티모듈 프로젝트를 구성하던 중,공통 엔티티와 Enum, 도메인 객체를 모아둔 domain-common 모듈을 분리하여 관리하고 있었습니다. 프로젝트 구조는 다음과 같았습니다.Wecam-project├── domain-common│ └── build.gradle├── wecam-backend│ └── build.gradle├── wecamadminbackend│ └── build.gradle├── build.gradle (root)└── settings.gradle 이 구조에서 domain-common은@Entity@Table@EnumeratedLombok 어노테이션 (@Getter, @Builder 등) 을 포함한 순수 도메인 모듈 역할을 하고 있..
[Spring Boot] 사용자/관리자 API 분리를 위한 멀티모듈 설계 실전 가이드 (Common, User, Admin)
·
ServerDev/SpringBoot
[Spring Boot] 사용자/관리자 API 분리를 위한 멀티모듈 설계 실전 가이드 (Common, User, Admin)백엔드 개발을 하다 보면, 일반 사용자용 API와 관리자용(Back-office) API를 분리해야 할 때가 옵니다. 트래픽 패턴도 다르고, 보안 요구사항도 다르며, 배포 주기도 다르기 때문입니다.하지만 무턱대고 프로젝트를 2개로 쪼개면 User, Product 같은 엔티티와 도메인 로직을 양쪽에서 복사/붙여넣기 해야 하는 문제가 발생합니다.오늘은 domain-common(공통), wecam-backend(사용자), wecam-admin-backend(관리자)로 구성된 멀티모듈 아키텍처를 설계하고, 실제 build.gradle 설정부터 설정하면서 했던 고민(Repository/Ser..
[SpringBoot & FormData] JSON + 파일 업로드: HttpMediaTypeNotSupported 에러 해결
·
ServerDev/SpringBoot
단순한 해결법 나열이 아니라, 왜 에러가 발생했는지(HTTP 프로토콜 관점), 프론트엔드와 백엔드가 각각 어떻게 데이터를 주고받아야 하는지 원리를 포함하여 기록하려 합니당. (해당 트러블 슈팅은 wecam 프로젝트에서 발생함..) 프론트엔드(Next.js)와 백엔드(Spring Boot)를 연동하다 보면 가장 까다로운 구간 중 하나가 바로 "파일 업로드와 일반 데이터를 동시에 보낼 때"입니다.저는 두가지 방법을 고민했습니다. 두 번 요청: JSON 데이터를 먼저 보내서 ID를 받고, 그 ID로 파일을 별도 업로드한다. (Transaction 관리가 귀찮음)한 번 요청: multipart/form-data로 묶어서 한 방에 보낸다. (깔끔하지만 구현이 까다로움) 당연히 2번이 UX나 아키텍처 관..
[Architecture 구축기 - AI 모델 서빙] 실무에서 마주칠 5가지 AI 서빙 아키텍처 고도화 전략
·
Architecture
최근 인턴 활동을 하며 회사 내의 폐쇄형 LLM 을 모델로 사용해, RAG 를 구축한 챗봇 서비스에 투입 되어 일을 맡고 있습니다. 어떤 아키텍처가 적합할지 고민을 하다가 제가 지금까지 어떤식으로 아키텍처를 설계해왔는지 AI 모델 서빙과 관련해 정리를 해볼까 합니다. (원래 하이브리드 서버 를 좋아하는 편이라 더 적합하지 않는 것일 수도 있어요 .. 하지만 정리는 좋은 거니까! ) 단순 AI 모델 서빙이라면 SpringBoot + FastAPI , 또는 Only FastAPI 로도, 이 구조만으로도 80%의 요구사항은 해결된다 생각하긴 합니다. 텍스트 감성 분석, 간단한 추천 시스템, 데이터 전처리 같은 작업은 HTTP 요청 한 번으로 충분하죠. 하지만 서비스가 성장하고 요구사항이 고도화되면, 우리는 '..
[Project : Ms-Serving] Istio 기반 AI 모델 서빙 및 관측 플랫폼 (feat.K8s)
·
Project/ms-serving
클라우드 네이티브 마이크로서비스 기반 AI 모델 서빙 플랫폼(Cloud-native Microservice-based AI Model Serving Platform) 본 프로젝트는 AI 모델을 클라우드 네이티브 환경에서 효율적으로 배포하고 서비스할 수 있는 플랫폼을 구축하는 것을 목표로 한다.Kubernetes 기반 인프라 위에 KServe, Knative, Istio 등을 활용하여 확장성과 유연성을 제공한다.일반 사용자Web UI를 통해 AI 모델 서빙 요청을 보내는 사용자관리자 (Platform Admin)전체 시스템 상태 확인, 모니터링 설정 및 관리개발자 (DevOps)새로운 모델 서빙 배포 및 라우팅 정책 설정 주요 구성 요소 - Stack Overview구성 요소 설명InfraDocker ..
[JPA] 동시성 제어 : LockModeType.PESSIMISTIC_WRITE
·
ServerDev/SpringBoot
Spring Data JPA를 사용하여 동시성 이슈를 해결하려 할 때, 가장 강력하면서도 확실한 방법인 LockModeType.PESSIMISTIC_WRITE(비관적 쓰기 락)에 대해 정리해 봅니다.1. PESSIMISTIC_WRITE란?LockModeType.PESSIMISTIC_WRITE는 데이터베이스의 배타적 락(Exclusive Lock) 기능을 사용하여 동시성을 제어하는 방식입니다.쉽게 비유하자면 다음과 같습니다."내가 이 데이터를 다 쓰고 나갈 때까지, 아무도 들어오지 마! (읽지도 말고 쓰지도 마!)"트랜잭션이 시작되고 데이터를 조회하는 순간부터 락을 걸어버리기 때문에, 데이터의 무결성이 깨질 확률을 '0'에 수렴하게 만드는 아주 강력한 옵션입니다. (대신 해당 lock 이 풀리기 전까진 다..
[SpringBoot&JPA] QR 코드 기반 게스트 계정 자동 생성 및 로그인 구현
·
ServerDev/SpringBoot
QR 코드 기반 게스트 계정 자동 생성 및 로그인 구현 (Spring Boot + JPA)QR 코드를 통해 서비스에 접근하는 게스트 사용자를 위해 인증 없이 계정을 자동 생성하고 바로 로그인시키고자 했습니다.기존 회원가입 로직은 이메일 인증과 key/code 검증이 필수라 게스트 흐름과 맞지 않았습니다.우선 자동 회원가입 -> 로그인 흐름을 맞추기 위해, 비밀번호 생성과 아이디 생성을 위한 Sequence Table 을 구현했습니다.해당 테이블로 유저가 동시 접속할 때 자동 +1 을 부여-- 시퀀스 생성CREATE SEQUENCE guest_seq START 1 INCREMENT 1 MINVALUE 1 NO MAXVALUE CACHE 1;-- 기존 guest_sequence_t..
[Spring Boot] 권한 검증 - 커스텀 AOP와 Redis로 해결하기 (@IsCouncil)
·
ServerDev/SpringBoot
권한 검증을 위한 커스텀 AOP 는 wecam 프로젝트를 진행하면서 만들게 되었습니다!! (프로젝트 기능 개발) 백엔드 개발을 하다 보면 컨트롤러 메서드마다 반복되는 검증 로직들이 있습니다."이 유저가 학생인가?", "헤더에 학생회 ID가 있는가?", "그 ID가 현재 로그인한 상태와 유효한가?" 이런 if 문들이 비즈니스 로직과 섞이면 코드가 지저분해지고 가독성이 떨어집니다. 오늘은 Spring AOP와 Redis를 활용해, 어노테이션 하나만 붙이면 이 모든 검증을 자동으로 수행하고 컨텍스트까지 주입해 주는 설계 패턴을 기록합니다, 1. 반복되는 검증 로직 학생회 관리 서비스를 만들었을 때, 특정 기능을 수행하려면 다음 과정이 필수적입니다.로그인한 유저인지 확인한다.유저의 Role이 STUDEN..
[SpringBoot - SSR] 파일 업로드 에러: "Failed to convert String to MultipartFile" 원인과 해결
·
ServerDev/SpringBoot
Spring Boot로 파일 업로드 기능을 구현하다 보면, 꽤 긴 에러 메시지와 함께 요청이 실패하는 경험을 하게 됩니다. 특히 폼(Form) 데이터를 통해 이미지를 전송할 때, 분명 파일을 선택했음에도 불구하고 서버 로그에는 타입 변환 실패(Type Mismatch) 오류가 찍히는 경우가 빈번합니다.오늘은 파일 업로드 구현 시 가장 흔하게 발생하는 MultipartFile typeMismatch 에러의 정확한 원인과, 이를 해결하기 위한 체크리스트를 정리해 보려 합니다. [SpringBoot - SSR] 파일 업로드 에러: "Failed to convert String to MultipartFile" 원인과 해결 Spring Boot에서 처음 파일 업로드 기능을 구현하다 보면,, 아래와 같은 에러 ..
[Spring Boot] 수정 기능 구현 시, 멀쩡한 데이터가 NULL 로 덮어씌워지는 문제
·
ServerDev/SpringBoot
[Spring Boot] 수정 기능 구현 시, 멀쩡한 데이터가 NULL로 덮어씌워지는 문제과거 멘토링 매칭 플랫폼 프로젝트 ( SSR로 구현 )를 진행하던 당시 겪었던 이슈를 기록으로 남기고자 합니다. 당시 회원 정보 수정 기능을 구현하고 테스트를 진행했는데, 분명 제목(Title)만 수정해서 저장했음에도 불구하고 카테고리나 인원수 같은 다른 필드들이 전부 NULL로 변해버리거나 데이터가 날아가는 현상이 있었습니다. 처음에는 단순한 쿼리 오류라고 생각했지만, 디버깅을 해보니 Spring MVC의 데이터 바인딩 원리와 JPA의 수정 방식을 제대로 이해하지 못해 발생한 구조적인 문제였습니다. 이번 글에서는 이 문제가 왜 발생했는지, 그리고 실무적으로 어떻게 해결하는 것이 가장 안전한지 정리해 보려고 합니다...
[ Web Stack] 스프링 부트 Web Stack 종류 - Server MVC & WebFlux
·
ServerDev/SpringBoot
Web Stack 종류java 언어로 구현하는 백엔드 서버의 프레임워크인 Spring Boot에서 스택을 나눌 수 있다는 것을 알게 되었습니다.스택을 나누고 구현을 한 적은 없는 것 같은데, 공부해보니 2가지 스택으로 나뉜다고 하더군요.항목Servlet 기반 (Spring MVC)WebFlux (Spring WebFlux)모델전통적인 동기/블로킹 I/O비동기/논블로킹 I/O스레드 모델요청 1개 = 스레드 1개요청 N개 ≠ 스레드 N개 (이벤트 루프 기반)리턴 타입String, ModelAndView, ResponseEntityMono, FluxServlet API 사용 여부사용 (예: HttpServletRequest)사용 안함공식 문서를 보았는데정확히 이해는 잘 되진 않지만, Model , Contro..
[SSE & Nginx] 실서비스 EventStream 유지 설정
·
DevOps/Nginx
[SpringBoot/Nginx] 운영 환경에서 SSE가 끊길 때 확인할 것들1. 문제 상황로컬 환경(SpringBoot + Front)에서는 SSE 스트림이 문제 없이 유지가 됐었습니다. 그러나 Dev(운영 유사) 환경에서는 SSE가 일정 시간 지나면 끊기는 것이 확인 됐습니다.로컬 환경 자체에서는 제대로 작동되었기에 "로컬과 다른 점: 운영 Nginx(Reverse Proxy) 뒤에 배포"Nginx 설정 파일에서 SSE 설정을 따로 해두는 부분이 있겠다라는 생각이 들었습니다.2. TL;DR원인: Nginx 기본 proxy 버퍼링/타임아웃/압축 등의 동작이 SSE(서버-센트 이벤트)의 지속 스트리밍을 방해실제 파일에서는 SSE 에 대한 기본 설정을 하지 않았었고,Nginx는 기본적으로 proxy_buf..