Latest Posts · Page 2 of 5
플랫폼 백엔드 개발 가이드

Java 21 Virtual Thread + Spring Boot 3.5 + Spring Cloud 기반의 마이크로서비스 아키텍처로, 4개 독립 서비스 모듈과 공통 라이브러리로 구성된 백엔드 개발 가이드이다. @ParsedAuthToken + @ValidateUser 커스텀 애노테이션과 AOP를 조합해 JWT 파싱 및 사용자 검증 로직을 컨트롤러에서 완전히 분리한 것이 인증 설계의 핵심이다. 레이어별 메서드 명명 규칙(Controller → get*/save*, Service → find*/save*, Repository → find*/insert* 등)과 FeignClient를 Virtual Thread로 래핑하는 패턴을 팀 표준으로 정의한 실전 설계 가이드이다.

Read
Jasypt를 이용한 Spring Boot 프로퍼티 암호화

Jasypt를 사용하면 application.yml에 민감한 값을 ENC() 형태로 암호화 저장하고, 런타임에 자동 복호화하여 안전하게 사용할 수 있다. 암호화 키(jasypt.encryptor.password)는 코드에 두지 않고 반드시 환경변수나 VM 옵션으로 외부 주입해야 한다. 간단히 적용 가능하지만 키 관리, 알고리즘 변경, 복호화 범위(spring 하위 프로퍼티 제한) 등의 운영상 주의가 필요하다.

Read
Kotlin, SpringBoot 3, GraalVM 환경에서 Native Image로 컴파일하여 애플리케이션 실행

Spring Boot 3 + GraalVM Native Image를 사용하면 JVM 없이 실행되는 바이너리를 생성할 수 있으며, 기동 속도가 약 93.5% 향상된다 (4.7초 → 0.3초). 설정은 build.gradle.kts에 native 플러그인 추가, application.yaml에 AOT 활성화, GRAALVM_HOME 환경변수 설정 후 ./gradlew nativeCompile로 빌드. 다만 컴파일 시간 12~13분, 환경 의존성, 미지원 라이브러리 존재, 운영 레퍼런스 부족 등의 이유로 실제 운영 도입에는 추가 검토가 필요하다.

Read
AOP와 Redis를 활용한 접속 제한 설정 기능 구현

Embedded Redis를 Local/DEV 환경에 내장하여 구동하고, STAGE/PROD에서는 ElastiCache를 사용하도록 @Profile로 환경별 RedisConnectionFactory Bean을 분리 구성한다. @AccessLimiter 커스텀 Annotation을 정의하여 IP/Session 기준, 최대 허용 횟수, TTL 등의 옵션을 선언적으로 설정할 수 있게 하고, Redis에 접속 횟수를 key-value로 저장해 카운팅한다. @Around AOP로 메서드 실행 전에 접속 횟수를 확인해 초과 시 ExceededRestrictException을 throw하고, 실행 후에는 비동기(CompletableFuture)로 카운트를 증가시켜 비즈니스 로직과 완전히 분리한다.

Read
Java Application Deploy Command

Java 21(OpenJDK) 기반으로 Z GC (-XX:+UseZGC, -XX:+ZGenerational) 를 사용하며 Generational ZGC를 적용한다. Heap은 -Xms2048m / -Xmx3072m / -XX:SoftMaxHeapSize=2560m, MetaSpace는 -XX:MetaspaceSize=512m / -XX:MaxMetaspaceSize=768m으로 설정한다. GC 로그는 파일로 저장(filecount=3, filesize=100m), OOM 발생 시 Heap Dump를 자동 생성하도록 설정한다.

Read
Message Queue 비교 분석

Apache Kafka는 분산처리 성능, 가용성, 에코시스템 면에서 가장 우수하여 대용량/고가용성이 요구될 때 최적이고, AWS SQS는 운영 부담이 낮고 유지보수성이 뛰어나 소규모/단순 구조에 적합하다. Kafka는 Consumer Group 단위로 동일 메시지를 여러 도메인 시스템이 독립적으로 수신할 수 있어 분산 처리에 구조적 강점이 있고, SQS는 Queue당 메시지 1회 소비 삭제 방식으로 중복 처리 부담이 적다. MQTT(Mosquitto)는 IoT/모바일 Device 간 인터페이스에 적합하며, 서버 애플리케이션 간 인터페이스에는 적합하지 않다는 결론 → 서버 간은 Kafka 또는 SQS, 모바일 대상은 AWS IoT 도입을 제안.

Read
Docker-compose로 Cassandra 클러스터 구성

docker-compose로 Cassandra 4.0 노드 3개짜리 클러스터를 로컬에 구성하며, node2·node3은 CASSANDRA_SEEDS=cassandra-db-node1으로 시드 노드를 지정해 클러스터에 참여시킨다. Cassandra의 기본 heap 메모리가 2GB이므로 mem_limit은 반드시 2g 초과로 설정해야 안정적으로 구동된다. 구동 후 cqlsh로 노드 1에서 데이터를 insert하고, 노드 2에서 조회하여 데이터가 클러스터 전체에 샤딩되었음을 확인한다.

Read
AWS Secrets Manager SDK를 사용한 DB Connection 정보 보안 적용

aws-secretsmanager-jdbc 방식은 설정이 단순하나 Driver 고정 및 Credentials Provider Chain 오동작 위험이 있어, Spring Cloud AWS + DataSource Java Bean 방식을 권장한다. 환경별로 @Profile을 통해 로컬은 JVM 옵션의 Access Key로, 서버 환경은 EC2 IAM Role로 AWS 인증을 분리 구성한다. GetSecretValueResult에서 가져온 JSON 문자열을 DataSourceSecrets 모델에 Jackson으로 매핑하여 DB 접속 정보를 동적으로 주입한다.

Read
SpringBoot 버전 2.7 이상에서 MariaDB(RDS)의 Aurora 옵션 미지원

Spring Boot 2.7 환경에서 MariaDB Connector와 AWS Aurora(RDS) 조합 사용 시 드라이버 호환성 이슈가 발생할 수 있다. 특히 최신 MariaDB 드라이버(3.x)는 Aurora 전용 모드(aurora)를 지원하지 않아 기존 기능(읽기/쓰기 분산 등)이 제대로 동작하지 않을 수 있다. 따라서 상황에 따라 MariaDB Connector 2.x 유지 또는 AWS 전용 JDBC 드라이버로 변경하는 등의 대응이 필요하다.

Read
SQS DLQ의 메시지를 처리

SQS의 DLQ(Dead Letter Queue)는 여러 번 처리에 실패한 메시지를 별도 큐로 분리 저장하는 구조다. 메시지는 설정한 재시도 횟수(maxReceiveCount)를 초과하면 자동으로 DLQ로 이동되어 메인 큐의 처리 흐름을 방해하지 않는다. 이를 통해 실패 메시지를 분석·재처리하고, 전체 시스템의 안정성과 장애 대응력을 높일 수 있다.

Read
블로그에 새로운 글이 발행되었습니다.