전체 224

AWS ECS 배포 실패

ECS 배포ECS를 Fargate로 서버리스로 배포를 진행했다.ECS만 배포하는 것은 성공했지만 오토스케일링을 염두해두고 있어 로드밸런서를 적용하여 배포해야 했다.로드밸런서를 붙여서 배포하니 배포 실패가 나온다.해결법이미지를 보면 상태검사를 했을 때 Unhealthy가 나와서 실패를 하는 것 같다.Request timed out.이 나오는데 서버가 완전히 실행되기 전에 상태검사를 시작하고 Unhealthy가 나오면서 배포를 실패하는 것으로 인지했다. 상태검사를 할 때, 기본 설정으로 위와 같이 되어 있다. 비정상 임계값을 5로 늘려주고 간격을 100초로 두면서 상태검사하는 시간을 조정해주었다.그렇게 하니 배포가 제대로 되었다.

[동시성 제어] 티켓 예매 중복 예매 문제 해결

동시성 문제콘서트 티켓 예매 서비스 프로젝트를 진행하는 중 여러 사용자가 한 좌석에 대해 거의 동시에 예매 요청을 보내게 되면 여러 개의 같은 예매가 생성되는 문제를 확인했다.좌석 예매 서비스라면 많이 본 `이미 선택된 좌석입니다`처럼 동시성을 제어하기 위해 낙관적 락, 비관적 락 등 다양한 방식을 적용해 보며 문제를 해결해 나갔다.예매 코드와 테스트 코드예매 코드public void createReservation(Long userId, Long concertId, ReservationRequestDto requestDto) { Seat seat = seatRepository.findSeatForReservation(concertId, requestDto.getHo..

[CI 빌드 에러] 빌드 시 발생했던 에러들 해결

1. Redis가 없어 발생하는 에러Github Actions를 통해 CI를 구축하고 테스트 코드가 실패가 됐었다.로컬에서 테스트 코드가 성공인 것을 확인했고 PR를 날렸는데 빌드 과정에서 테스트가 실패한다고 발생한다.알아보니 해당 테스트 코드는 Redis를 사용하는데 github workflow에서 redis가 실행되지 않아 발생하는 문제였다.그래서 CI 스크립트에 Redis를 실행할 수 있도록 해줬다.jobs: build: name: CI if: github.event_name == 'pull_request' runs-on: ubuntu-latest environment: development services: redis: image: redis ..

[CI/CD] ECS에 Spring boot 서버 배포하기

ECS와 EC2현재 진행하고 있는 팀 프로젝트를 배포를 해야했다.배포하는 방법에는 EC2와 ECS를 선택지를 두고 있었고, ECS를 선택하게 되었다.EC2는 docker나 jdk와 같은 따로 설정을 해줘야 하는 번거러움이 있었고ECS는 컨테이너 서비스이기 떄문에 도커 이미지를 올리고 미리 정의된 Task를 사용하기 때문에 따로 설정이 필요없고 간편하는 점에서 사용하게 되었다.RDS와 ElastiCacheECS로 배포를 하면서 auto scaling을 적용해볼 계획을 가지고 있었다.기존에 localhost로 사용하는 방식으로 한다면 database와 cache가 각 서버에 생기기 때문에 데이터가 공유되지 않는다.그래서 RDS와 ElastiCache를 사용해 서버가 늘어나도 데이터가 공유될 수 있도록 하였다..

[Redis 캐싱 처리] Could not write JSON: Java 8 date/time type `java.time.LocalDateTime` not supported by default

문제점 Redis를 이용하여 캐싱 처리를 하려고 하니 Could not write JSON: Java 8 date/time type `java.time.LocalDateTime` not supported by default와 같은 에러가 발생하였다. @Bean public CacheManager cacheManager() { RedisCacheManager.RedisCacheManagerBuilder builder = RedisCacheManager.RedisCacheManagerBuilder.fromConnectionFactory(redisConnectionFactory()); RedisCacheConfiguration configuration = RedisCacheConfiguration.defaul..

기타/개발일기 2024.03.24

[Spring Boot] Redis로 캐싱 처리 적용하기

Redis 정의 이전에 Spring Boot에서 Redis를 사용하는 방법에 대해서 간단하게 포스팅했다. Key, Value 구조의 비정형 데이터를 저장하고 관리하기 위한 오픈 소스 기반의 비관계형 데이터 베이스 관리 시스템 (DBMS)이다. 데이터베이스, 캐시, 메세지 브로커로 사용되며 인메모리 데이터 구조를 가진 저장소이다. Redis 장점 높은 성능 Redis는 인메모리 데이터 저장소로 작동하므로 빠른 속도로 데이터를 처리할 수 있다. 비동기 방식으로 데이터를 처리하므로 성능이 향상된다. 데이터 구조 다양성 Redis는 다양한 데이터 구조를 지원하므로, String, List, Hash, Set 등을 통해 데이터를 쉽게 처리할 수 있다. 데이터 복제 및 분산 Redis는 데이터 복제를 지원한다. 클..

기타/개발일기 2024.03.24

[Spring Security] JWT 특성을 이용한 인증 처리 리팩토링

JWT의 특성 JWT의 특성은 stateless, 즉 무상태성이다. JWT는 HTTP 통신을 통해 주고받기 때문에 기본적으로 HTTP의 특성을 가지게 된다. 무상태성은 서버가 클라이언트의 상태를 가지고 있지 않는 것을 말한다. 인증 처리 리팩토링 리팩토링을 하게 된 계기는, 로그인한 유저가 로그인 인증 처리를 할 때, Database를 걸쳐 나오는 것 때문에, 이를 수정하고자 했다. // 인증 처리 public void setAuthentication(String username) { SecurityContext context = SecurityContextHolder.createEmptyContext(); Authentication authentication = createAuthentication(u..

기타/개발일기 2024.03.21

Spring Boot에서 Redis 사용하기

Redis를 공부하게 된 계기는 프로젝트를 진행하면서 Refresh Token을 처리를 해줘야 하는데 이를 보통 Redis로 사용을 많이 한다고 한다. 하지만 Redis를 따로 사용해 본 적이 없어서 Database를 사용하여 Refresh Token을 관리해줬다. Redis를 공부해놔야 할 것 같아 리팩토링을 통해 Redis를 사용하게 되었다. Redis 레디스는 Mysql와 같은 RDS도 아니고, MongoDB와 같은 NoSQL도 아니다. 인메모리 형식의 키-값 구조를 가진 데이터 저장소이다. 주요 Redis 사용 사례로는 캐싱, 세션 관리, pub/sub 및 순위표라고 한다. Spring Boot Redis 스프링 부트에서 공식적으로 레디스 기능을 제공해준다. Spring Boot Redis에는 J..

기타/개발일기 2024.03.15

queryDSL 사용방법

Config 설정 queryDSL을 사용하기 위해서 Dependency를 추가해줘야 한다. implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta' annotationProcessor "com.querydsl:querydsl-apt:5.0.0:jakarta" annotationProcessor "jakarta.annotation:jakarta.annotation-api" annotationProcessor "jakarta.persistence:jakarta.persistence-api" build.gradle에 해당 스크립트를 추가해준다. 그리고 queryDSL은 JPAQueryFactory를 통해서 사용해야 하기 때문에 빈 등록을 해줘야 한다. Config ..

Language/Java 2024.03.14

Spring Boot S3에 이미지 업로드

Spring Boot 이미지 업로드 처음에 이미지 업로드는 서버에 임의로 지정해놓은 디렉터리에 저장되도록 구현했다. private PostImage getPostImage(MultipartFile file, Post post) throws IOException { if (file != null) { String originalFilename = file.getOriginalFilename(); String saveFileName = createSaveFileName(originalFilename); file.transferTo(new File(getFullPath(saveFileName))); // 여기서 임의의 위치로 이미지 저장 String filePath = uploadPath + saveFileN..

기타/개발일기 2024.03.13