ElasticSearch 클러스터는 하나 이상의 노드를 이용해서 클러스터를 구성하며, 사용자의 요청을 클러스터 단위로 처리합니다. 클러스터ElasticSearch 클러스터는 고유의 클러스터 이름과 UUID를 가집니다.이 두 가지 값으로 ElasticSearch는 어떤 노드들이 동일한 클러스터에 속해 있는지 인식하며 클러스터링을 수행합니다.클러스터 이름클러스터에 속한 모든 노드는 동일한 클러스터 이름을 사용해야 합니다.이름이 다른 노드가 클러스터에 합류하려고 하면 에러가 발생합니다.클러스터 UUID클러스터가 최초 생성될 때 자동으로 생성되며, 사용자가 직접 지정할 수 없습니다.클러스터에 속한 모든 노드는 동일한 UUID를 공유합니다. 노드노드는 클러스터를 구성하는 ElasticSearch 프로세스 하나를 ..
Category
개요DMforU는 공지사항의 알림을 받고, 홈페이지에 올라온 공지사항을 간단하게 보거나 검색하기 위한 애플리케이션입니다.위와 같은 애플리케이션 특성으로 MySQL 테이블은 2개 밖에 존재하지 않습니다.공지사항알림 구독코드의 리팩토링은 꾸준히 진행되어 왔지만, 쿼리 응답 시간에 대해서는 생각해본적이 없었습니다.따라서, 각 테이블에서 사용되는 쿼리를 알아보고 MySQL의 성능을 최적화 해보려고 합니다.우선 공지사항 테이블부터 진행하고자 합니다.본론공지사항 테이블의 문제테이블공지사항 테이블은 다음과 같습니다. 쿼리공지사항 테이블에서 주로 사용되는 쿼리는 다음과 같습니다. (save()인 insert 구문은 제외하였습니다.)# 타입에 해당하는 공지사항의 가장 최신 공지번호SELECT MAX(number) FRO..
개요org.springframework.context.ApplicationContextException: Failed to start bean 'eurekaAutoServiceRegistration' at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:288) ~[spring-context-6.1.13.jar:6.1.13] at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:472) ~[spring-context-6...
개요DMforU 프로젝트 대규모 리팩토링을 진행할 것이라고 포스팅을 작성하고, 어느덧 한 달 반이라는 시간이 흘러 운영 서버에 재배포를 하게 되었습니다. 리팩토링된 자세한 사항은 다음과 같습니다.Kotlin + Spring / Multi Module 구조 적용Redis에서 MongoDB로 전환Junit5, Mocktito를 사용한 단위 / 통합 테스트 작성JaCoCo를 사용한 테스트 커버리지 관리 및 테스트 자동화Jenkins를 사용한 CI / CD 구축Prometheus, Grafana를 사용한 모니터링 시스템 구축SQS, Lambda를 사용한 FCM 푸시 알림 로직 분리 본론계획에서 제거된 부분Spring BatchSpring Batch를 사용할 것이라고 작성했었는데, 사용하지 않은 이유는 다음과 같..
개요이전에 작성한 FCM 포스팅에서 언급한 것처럼, 한 번에 전송할 수 있는 메시지 수에는 500개라는 제한이 있습니다. 게다가, 현재 동기 방식으로 작성된 FCM 모듈에서 문제가 발생할 경우, Admin 전체 서비스에 영향을 미칠 위험이 있습니다. 이를 개선하기 위해, SQS와 Lambda를 사용하여 메시지 전송의 제한을 없애고, SQS에 비동기로 메시지를 전달하는 방식으로 리팩토링을 진행하였습니다. 본론AWS IAM, SQS, LambdaSQS과 Lambda 함수를 만들기 이전, 외부 애플리케이션에서 접근해야 하기 때문에 IAM을 생성하였습니다. SQS에 메시지를 보내야 하기 때문에, IAM 사용자를 생성하면서 AmazonSQSFullAccess 권한을 부여하였습니다. SQS 대기열을 생성한 후, ..
개요현재 DMforU 운영 서버는 단순히 로그만 남기는 방식으로 관리되고 있습니다.그러나 이 방식만으로는 서버가 안정적으로 운영되는지 확인하기 어렵다고 생각했습니다.이에 따라, 서버의 상태를 실시간으로 모니터링할 수 있는 시스템을 구축하게 되었습니다.본론현재 DMforU 서버는 Spring Boot 프레임워크로 구현되어 있어, 모니터링을 간편하게 적용할 수 있는 Spring Boot Actuator 라이브러리를 활용했습니다.Actuator를 통해 수집한 메트릭은 Prometheus로 전송되며, Grafana를 통해 시각적으로 모니터링할 수 있도록 구성하였습니다. Actuator Actuator는 여러 모듈에 동일한 설정을 적용할 수 있기 때문에 support 패키지에 모듈로 만들었습니다.그리고, API ..
개요DMforU의 실제 운영 서버는 수동 배포 환경에서 동작하고 있습니다.현재 애플리케이션은 API 서버와 Admin 서버로 분리되어 있는 상태인데, 이로 인해 다음과 같은 문제가 발생하고 있습니다.애플리케이션 빌드, 빌드 결과물 전송, jar 파일 실행을 두 번 반복해야 하는 비효율무중단 배포를 고려한 자동 배포 환경이 마련되지 않은 상황이에 따라, Jenkins 서버를 활용하여 Dev 환경에 자동 배포하는 시스템을 구축했습니다. 추후, Dev 환경에서 새롭게 변경된 서버들이 문제 없이 작동하는 것을 확인한 후, Prod 환경에도 파이프라인을 추가할 계획입니다. 본론Jenkins 서버 구축현재 AWS 프리티어를 사용 중이므로, 새로운 계정을 생성한 뒤 EC2 인스턴스를 만들어 Docker를 활용하여 J..
개요이전 포스팅에서는 전반적인 테스트 코드를 작성했지만, 아직 놓친 부분이 없는지에 대한 확신이 부족한 상태입니다.또한, 테스트를 주기적으로 실행하고, 그 결과를 확인하면서 개발하는 것이 중요하지만, 현실적으로 이를 지속하는 것은 쉽지 않습니다.이에 따라 CI 환경을 구축해 테스트를 자동으로 실행하고, 테스트 완료 후에는 커버리지도 자동으로 확인할 수 있도록 하려 합니다. 본론JaCoCo테스트 커버리지 측정은 Gradle의 JaCoCo 플러그인을 사용했습니다.멀티 모듈구조 이기 때문에 다음과 같은 build.gradle.kts을 작성할 수 있습니다.subprojects { ... apply(plugin = "jacoco") tasks.withType { useJUnit..
개요DMforU 초기 개발 당시에는 테스트 코드의 중요성을 크게 느끼지 못했고, 수동으로 API 테스트해보고 문제없다 싶으면 배포를 하고는 했습니다.하지만, 최근 1달 동안 인프런 클린 코드 / 테스트 코드 스터디를 진행하고 테스트 코드의 중요성을 많이 느끼게 되었습니다. 앞으로의 리팩토링과 유지보수에서 만날 문제를 줄이기 위해 테스트 코드를 작성하기로 결정하였습니다.본론테스트 작성은 Junit과 Mocktito을 사용했습니다.(Kotlin으로 개발했기 때문에 Kotest, Mockk 등 선택지가 다양했는데, 해당 사실은 테스트 코드를 거의 다 작성했을 무렵 알게 되었습니다..)현재 프로젝트는 멀티 모듈을 적용하였고, 모듈별 의존성을 최소한으로 가져가는 방향으로 개발하였습니다.각 모듈별 단위테스트 위주로..
개요DMforU 서비스 환경에는 Redis가 포함되어 있었으며, 원래 사용자 토큰의 신선도를 관리하는 용도였습니다. 그러나 해당 기능을 사용하지 않게 되면서, 학사 일정과 식단표의 저장소로 Redis를 활용하게 되었습니다.(기존 학시 일정과 식단표 API는 요청 마다, 학교 홈페이지 정보를 불러오는 형태였습니다. ) 이후 Redis가 적합하지 않다고 판단되어, MongoDB로 저장소를 전환을 시도하게 되었습니다. 본론학사 일정과 식단표학사 일정과 식단표 Domain 코드더보기class Schedule private constructor( val dates: List, val content: String,) { companion object { fun of(dateArray: ..