[TroubleShooting] CloudFront 캐시 무효화
·
TroubleShooting
우아한테크코스 레벨 3 팀 프로젝트 Festabook에서 학습한 내용을 정리한 글입니다. 👀 현재 상황 및 배경 설명기존에는 Nginx로 정적 프론트 화면을 배포했는데, Dev/Prod 환경을 분리하면서 Prod 환경은 CloudFront를 통해 프론트를 보여주도록 아키텍처를 구성했다. 🚨 문제 상황S3와 CloudFront, 도메인을 연결하고 프론트를 배포했다. 그런데 S3 정적 리소스는 업데이트된 버전을 정상적으로 확인할 수 있는데, 실제 도메인으로 접속하면 "권한이 없다"는 화면이 떴다. 초기 구성 중에서의 배포라 CloudFront 설정을 잘못했다고 생각하고 여러 작업을 해봤지만 문제가 해결되지 않았다. ✏️ 원인 분석CloudFront는 S3의 정적 파일을 엣지 로케이션(전 세계에 분산된..
[TroubleShooting] 왜 우리는 WebFlux를 선택할 수밖에 없었나
·
TroubleShooting
👀 현재 상황 및 배경 설명우리는 MSA 환경에서 각 서버에서 활용할 수 있는 공통 모듈을 도입하려 했다.각 서버는 공통 모듈(common-module)을 통해 공통 로직을 공유하고 있으며,클라이언트의 요청은 Spring Cloud Gateway를 통해 내부 서비스로 라우팅된다. 🚨 문제 상황초기 개발 당시, 우리는 익숙한 Spring MVC 기반으로 서비스를 구성하고 있었다. 그러나 Spring Cloud Gateway에 인증 필터를 적용하는 과정에서 문제가 발생했다. 가장 핵심적인 인증 필터가 제대로 동작하지 않았던 것이다.특정 토큰을 통해 사용자 정보를 추출해 다른 서버로 전파하려 했지만, 사용자 정보가 null인 상태로도 필터가 그대로 통과되는 현상이 나타났다. 이를 통해 필터 로직 자체가 ..
[TroubleShooting] Jackson이 싫어하는 단일 필드
·
TroubleShooting
👀 현재 상황 및 배경 설명🔽 DTO 흐름코드의 가독성과 흐름을 깔끔하게 유지하기 위해 클래스 간 정보를 전달할 때 DTO 클래스를 활용하고 있다. Swagger를 사용하고 있으므로, DTO 클래스의 명명 규칙을 백엔드 내부적으로 통일하였다.입력을 전달하는 DTO: ~Request출력을 전달하는 DTO: ~Response내부적으로 정보를 전달하는 DTO: ~Dto ▶ 구현 코드🔽 MemberRegisterRequest DTO@Getter@Builder@RequiredArgsConstructorpublic class MemberRegisterRequest { @Schema(description = "회원의 이름", example = "이소은", required = true) private ..
[TroubleShooting] 주니어 개발자들을 울게 만드는 CORS 에러
·
TroubleShooting
👀 현재 상황 및 배경 설명🔽 SecurityConfig API 요청 흐름현재 API 요청은 공개 접근 필터 체인과 인증이 필요한 필터 체인, 어드민 권한 필터 체인을 순차적으로 거치게 되어있다.공개 접근 필터 체인: 로그인 없이도 접근 가능한 엔드포인트를 처리한다.인증이 필요한 필터 체인: 로그인이 반드시 요구되는 엔드포인트를 처리한다.어드민 권한 필터 체인: 어드민만 접근할 수 있는 엔드포인트를 처리한다.🔽 CORS 설정Spring Security에서 CORS를 설정하는 방법은 크게 두 가지가 있다.CorsFilter Bean 등록CorsConfigurationSource Bean 등록현재 프로젝트에서는 CorsConfigurationSource를 사용하여 CORS를 설정했다. ▶ 구현 코드🔽..
[TroubleShooting] Spring MVC에서 정적 경로가 동적 경로로 인식되어 엔드포인트가 동작하지 않을 때
·
TroubleShooting
👀 현재 상황 및 배경 설명🔽 SecurityConfig API 요청 흐름API 요청은 공개 접근 필터 체인과 인증이 필요한 필터 체인을 순차적으로 거친다.공개 접근 필터 체인: 로그인 없이도 접근 가능한 엔드포인트를 처리한다.인증이 필요한 필터 체인: 로그인이 반드시 요구되는 엔드포인트를 처리한다.🔽 회원 정보 조회 엔드포인트현재 프로젝트에서는 회원 정보 조회를 위한 두 가지 API를 제공한다.동적 경로 API: 특정 회원 정보를 조회하는 API로, @PathVariable을 사용하여 memberId 값을 동적으로 전달받는다.정적 경로 API: 자신의 정보를 조회하는 API로, 문자열 "self"를 정적으로 경로에 사용한다.위 두 경로는 서로 다른 역할을 수행하지만, Spring MVC의 URL ..
[TroubleShooting] Cascade 옵션은 부모에게만
·
TroubleShooting
👀 현재 상황 및 배경 설명현재 프로젝트에서는 N:M 관계(다대다 관계)가 적용된 Member와 Organization 엔티티 간의 연관관계를 설정하고 있다. 중간 테이블인 OrganizationMember 테이블이 두 엔티티를 연결해주며, 이를 통해 양방향 관계가 관리된다. 중간 테이블을 통해 Member는 여러 Organization에 속할 수 있으며, 반대로 각 Organization도 여러 Member와 연관될 수 있다. 현재는 Organization 엔티티에서만 양방향 관계를 설정하여 컬렉션 필드를 관리하고 있다.또한, CascadeType 옵션을 통해 부모 엔티티 삭제 시 자식 엔티티도 자동으로 삭제되도록 구현했다. 그러나 중간 테이블인 OrganizationMember를 통해 양방향 관계를..
[TroubleShooting] 컬렉션 필드 초기화가 되지 않는 Builder 패턴
·
TroubleShooting
👀 현재 상황 및 배경 설명현재 프로젝트에서 Builder 패턴을 사용하여 엔티티 객체를 생성하고 있으며, 특히 양방향 연관관계를 설정한 Organization 엔티티에서 리스트 형태의 컬렉션 필드를 사용하고 있다. ▶ 구현 코드@Entity@Getter@Builder@NoArgsConstructor(access = AccessLevel.PROTECTED)@AllArgsConstructorpublic class Organization { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; ... // 양방향 연관관계 @OneToMany(mappedBy = "organization", cascade ..
[TroubleShooting] DB 쿼리 비용
·
TroubleShooting
👀 현재 상황 및 배경 설명현재 가게 사진을 업데이트하는 로직은 모든 기존 사진을 삭제한 후 새로운 사진을 덮어쓰는 방식으로 작동하고 있다.기존 사진 URL을 데이터베이스에서 모두 조회기존 사진 URL을 DB에서 모두 삭제새로운 사진 URL을 DB에 모두 저장 ▶ 구현 코드/** * 가게 사진을 업데이트합니다. */@Transactionalprotected void updateMarketImages(Market market, List imageUrls) { // 기존 사진 조회 List marketImageList = marketImageRepository.findAllByMarketId(market.getId()); // DB에서 기존 사진 URL 모두 삭제 marketImage..
soeun2537
'TroubleShooting' 태그의 글 목록