본문 바로가기

반응형

분류 전체보기

(27)
Spring + ELK로 로그 시스템 구축하기 개요Ticketing 프로젝트 진행 중에 로그를 시각화하기 위해서 ELK 스택을 도입하기로 결정하였습니다. 원래는 모니터링 서버(Grafana)에 Loki와 연동하였으나, 모니터링 서버의 성능이 상대적으로 떨어져 정상적으로 로그를 처리하지 못했고, ElasticSearch도 사용하게 된 김에 이를 해결하기 위해 ELK를 도입하기로 결정했습니다. 1. Spring 로그 설정먼저 ELK로 로그를 보내기 위해선, 스프링에서 찍은 로그를 파일로 저장해야합니다. 로그는 LogstashEncoder를 사용하여 JSON 형태로 로그가 저장되도록 설정하였습니다. ${LOG_PATH}/${LOG_FILE}_${TODAY}.log ${LOG_PATH}/${LOG..
공연 조회 API에 캐싱 적용하기 개요이전글에서 공연 조회 API에 대해 병목지점을 파악하고, 성능 테스트를 해보았습니다. 이번글에서는 공연 정보 조회 API에 캐시를 적용하여 조회 성능을 더욱 올려보도록 하겠습니다. 캐시를 적용한 이유현재 공연 조회 API는 별도의 검색 기능을 제공하지 않고, 오로지 페이지 네이션 기능만을 제공합니다. 이렇게 사용자에게 보여지는 데이터가 일정하고 변경이 많지 않기 때문에 캐시를 적용하는 것이 적절하다고 판단하였습니다.  구조 설계캐시는 Local Cache, Global Cache(Redis)를 모두 사용할 것인데요, 이렇게 두가지의 캐시를 아래의 전략으로 사용할 예정입니다.Local Cache는 TTL을 짧게 주어 데이터가 자주 변경되게 함.Global Cache는 TTL을 길게 주어 데이터가 오래 ..
공연 예매 시 Proxy를 사용해 DB 부하 줄이기 개요현재 공연 좌석을 예매할 시 락의 적용 없이 DB에 바로 저장시도 하도록 되어있습니다.공연 좌석 예매는 공연 날짜, 좌석에 따라 결정되며, 이 두가지 조건에 대해 Unique Constraint가 걸려있어 중복 예매를 방지하지만, 바로 Database에 많은 INSERT Query를 날리는 것은 많은 부하를 줄 수 있다고 판단했습니다.@Entity@Table( name = "carts", uniqueConstraints = [UniqueConstraint( name = "ux_seat_uid_date_uid", columnNames = ["seat_id", "performance_datetime_id"] )])class Cart( //...}따라서 Redis로..
내가 만든 Docker Image가 ARM 아키텍쳐에서 실행되지 않을 때 개요Ticketing 프로젝트 진행 중, 서버의 업스케일링을 위해서 AMD/linux기반의 아키텍쳐에서 ARM/linux 기반의 아키텍쳐로 마이그레이션 할 일이 생겼습니다. 그런데 Docker Image로 빌드해놓은 Ticketing 어플리케이션이 ARM 아키텍쳐에서 실행되지 않는다는 오류를 발견했습니다.no matching manifest for linux/arm64/v8 in the manifest list entries 현재 상황현재 Ticketing Application이 배포되는 과정은 다음과 같습니다.개발자가 Github main Branch에 PushGithub Actions Script가 실행되어 Spring Build → Docker Image 생성생성된 Image를 Docker hub에..
공연 정보 조회 API 쿼리 분석하고 개선하기 개요티케팅 어플리케이션의 개발 및 배포가 완료되어서, 이제 성능 측정을 해보려 합니다.이번에 성능 개선을 할 API는 공연 정보 API 입니다.지금 아래와 같이 Performance가 검색 조차 되지 않는데, 쿼리 분석을 하고 정상적으로 검색이 되도록 수정해보고자 합니다.[LdrxyZMp]|||-> PerformanceReader.searchPerformanceSummaryDto [LdrxyZMp]||| PerformanceReader.searchPerformanceSummaryDto [Sldi1Gc3]||| PerformanceReader.searchPerformanceSummaryDto [NztCOAr_]||| PerformanceReader.searchPerformanceSummaryDto [wnv..
Spring + Grafana, Loki, Prometheus로 모니터링 시스템 구축하기 개요Spring + ELK Stack으로 로그 모니터링 시스템을 구축하려 했지만, ElasticSearch가 서버에 너무 무거워서 정상적으로 동작하지 않았습니다. 이에 대한 대안으로 ELK 대신 Loki와 Grafana로 로그 시각화 툴을 구축하고, 추가적으로 Prometheus를 도입해 메트릭또한 수집해 보고자 합니다.먼저 Grafana, Loki, Promtail을 필요로 하는데, 각 서비스의 역할은 다음과 같습니다.Grafana: 로그 시각화Loki: 로그 데이터 저장 및 인덱싱Prometheus : Spring, MySQL, Nginx등의 매트릭 수집Grafana와 Loki는 별도의 모니터링 서버에 구축하고, Promtail은 Application 서버에 구축하려 합니다.Grafana + Loki..
비동기 환경에서 Request를 유지하려면 어떻게 해야할까? 개요Spring Web MVC 환경에서 request 마다 유지되는 값이 존재할 때, 고민해야할 점이 하나 생겼습니다. 바로 비동기 환경에서 request 마다 유지되는 값을 전달해 줄 수 있을까? 만약 잘 동작하지 않는다면 어떻게 해야할까? 에 대한 고민입니다. 상황 설명상황은 아래와 같습니다. 아래와 같이 Logging을 찍는 AOP 코드가 있다고 가정해보겠습니다.@Component@Scope(scopeName = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)class RequestId( val id :String = createId()){ companion object{ fun createId() : String{ ..
Database Unique Constraint를 활용한 중복 예약 방지 로직 구현하기 개요공연 티케팅 예매 프로젝트 진행 중, 공연의 좌석에 대해 중복된 예약을 제한해야하는 요구사항이 존재했습니다. 이를 Database의 Unique Constraint를 사용하여 구현하였는데, 어떻게 구현하였는지 공유하고자 합니다.요구사항, Entity 설명먼저 요구사항은 아래와 같습니다.로그인된 사용자는 공연의 자리를 선택하여 장바구니에 추가할 수 있습니다. 이 때, 다른 사람이 이미 예약한 좌석은 예매할 수 없습니다.다음으로 엔티티를 보겠습니다. 엔티티는 아래와 같습니다.class Cart( @Column(unique = true, updatable = false) val uid: String, @ManyToOne @JoinColumn(name = "seat_id") val..

반응형