[ADVANCED #10] Spring 기반의 Kafka 사용 및 운용
·
Kafka/Core
0. 들어가며지금까지 우리는 Kafka의 핵심 개념부터 고급 기능까지 순수 Java 기반의 클라이언트를 사용하여 학습했다. 이는 Kafka 자체의 동작 원리를 이해하는 데 매우 효과적인 방법이었다. 하지만 실제 백엔드 개발 현장에서는 대부분 Spring Framework와 Spring Kafka 모듈을 사용하여 Kafka를 활용한다. 이번 글에서는 지금까지 배운 순수 Java 코드가 Spring Kafka에서는 어떻게 간결하고 선언적으로 바뀌는지, 그리고 Spring 환경에서 Kafka를 효과적으로 사용하고 운영하는 방법에 대해 자세히 알아보겠다.1. Spring Kafka 개요1.1. Spring Kafka란?Spring Kafka는 Spring Framework 기반의 애플리케이션에서 Apache K..
[ADVANED #1] GitHub Actions에서 Docker 고급 빌드 전략 (Buildx, 캐싱, 보안)
·
CI&CD/GitHub Actions
0. 들어가며[BASIC #5]에서는 Spring Boot 애플리케이션의 CI/CD 파이프라인을 구축하면서 Docker를 사용했다. 이번 포스팅에서는 GitHub Actions와 Docker의 연동을 더 깊이 있게 다루겠다.다룰 내용:Docker Buildx를 활용한 멀티 플랫폼 빌드레이어 캐싱 전략으로 빌드 속도 최적화Docker Hub 외 다른 레지스트리 사용 (GHCR, AWS ECR)Docker 이미지 보안 스캔고급 Dockerfile 최적화 전략1. Docker Buildx로 멀티 플랫폼 이미지 빌드1.1. 멀티 플랫폼 빌드의 필요성Apple Silicon(M1/M2) 맥북에서 만든 이미지를 Intel Linux 서버에서 실행하면 다음과 같은 에러가 발생한다.exec /usr/local/bin/..
[BASIC #5] 실전 프로젝트: Spring Boot 앱 CI/CD 파이프라인 구축하기
·
CI&CD/GitHub Actions
0. 들어가며지금까지 GitHub Actions의 이론, 기본 문법, 변수와 컨텍스트까지 모두 배웠다. 이번 포스팅에서는 배운 내용을 종합하여 실제 Spring Boot 애플리케이션의 CI/CD 파이프라인을 구축해보겠다.코드 push 시 자동 빌드 및 테스트테스트 통과 시 Docker 이미지 빌드Docker Hub에 이미지 push배포 서버에 자동 배포1. 프로젝트 준비1.1. Spring Boot 애플리케이션간단한 Spring Boot 애플리케이션을 준비한다.프로젝트 구조:spring-boot-ci-cd/├── .github/│ └── workflows/│ └── ci-cd-pipeline.yml├── src/│ ├── main/│ │ ├── java/│ │ │ └─..
[BASIC #4] GitHub Actions 변수와 컨텍스트 마스터하기
·
CI&CD/GitHub Actions
0. 들어가며[BASIC #3]에서는 GitHub Actions의 기본 문법을 알아보았다. 이번 포스팅에서는 변수와 컨텍스트를 더 깊이 다루겠다.특히 민감한 정보를 안전하게 관리하는 방법(secrets), Job 간 의존성 설정(needs), Action에 파라미터 전달하기(with) 등 실무에서 자주 사용되는 패턴에 초점을 맞출 것이다.1. 환경 변수 (env)1.1. 환경 변수 정의 방법환경 변수는 네 가지 레벨로 정의할 수 있다.# 워크플로우 레벨 (모든 Job에서 사용 가능)env: WORKFLOW_VAR: "workflow-value"name: Environment Variables Exampleon: [push]jobs: job1: # Job 레벨 (이 Job 내에서만 사용 가능) ..
[MVC-6] CSR 환경에서 @RequestBody만 쓸까? (feat. 파일 업로드와 @ModelAttribute)
·
Spring/MVC
0. 궁금증지난 [MVC-5] 포스팅에서는 스프링 MVC의 기본 기능과 애노테이션 기반 컨트롤러에 대해 알아보았다. 요즘은 React나 Vue.js 같은 프레임워크를 사용하는 CSR(Client-Side Rendering) 환경이 대세다. 이런 환경에서는 프론트엔드와 백엔드가 JSON 데이터로 통신하는 것이 표준(Standard)처럼 자리 잡았다.JSON 데이터 전송 → @RequestBody 사용그렇다면, 과거 JSP나 타임리프 시절에 폼(Form) 데이터를 받던 @ModelAttribute는 이제 CSR 환경에서 쓸모가 없을까? 결론부터 말하면 "아니오"다. JSON만으로는 해결하기 어려운 상황들이 분명 존재하기 때문이다. 이번 글에서는 CSR 환경에서도 @ModelAttribute가 필수적인 상황(..
[7] 성능 최적화 - Redis(캐싱)
·
Project/Secondhand Market
1. Redis 캐싱 적용 전 (Before)시스템의 병목 지점을 파악하기 위해, 트래픽이 집중되는 '메인 페이지 상품 목록 조회' API에 대해 부하 테스트를 진행하였다.1.1. 부하 테스트 스크립트 (k6/load-test.js)k6를 사용하여 점진적으로 부하를 높이는(Ramp-up) 시나리오를 구성하였다. 동시 접속자(VUs) 100명이 지속적으로 요청을 보내는 Thundering Herd 상황을 시뮬레이션하였다.import http from 'k6/http';import { check, sleep } from 'k6';export const options = { // [부하 시나리오 설정] // 1. Ramp-up: 10초 동안 사용자(VU)를 0명에서 10명까지 늘림 // 2. ..
[6] 성능 최적화(4): Async 적용
·
Project/Secondhand Market
이번 포스팅에서는 외부 API 호출(SMS 발송)과 대용량 파일 처리(이미지 업로드) 시 발생하는 성능 병목을 비동기 처리(Async & CompletableFuture)를 통해 획기적으로 개선한 과정을 정리한다.1. 인증 코드 전송 (SMS)회원가입 시 휴대폰 인증 코드를 발송하는 기능이다. 기존에는 SMS 발송이 완료될 때까지 사용자가 계속 대기해야 하는 문제가 있었다.1.1. 동기 방식 (기존) 기존 코드는 AuthService에서 SMS 발송 메서드를 호출하면, 발송이 끝날 때까지 다음 줄로 넘어가지 않는 블로킹(Blocking) 방식이었다. 외부 SMS 서비스가 느려지거나 장애가 발생하면, 우리 서버의 회원가입 요청도 같이 느려지거나 타임아웃이 발생하는 위험이 존재했다. 변경 전 코드 (동기 처..
[5] 성능 최적화(3): N+1
·
Project/Secondhand Market
1. 상품 목록 조회 API (GET /items) 최적화 상품 목록 조회 API는 한 페이지당 20개의 상품 데이터를 반환하도록 구현되어 있다. API 호출 시 그라파나(Grafana)를 통해 쿼리 실행 내역을 모니터링한 결과, 단 한 번의 요청에 무려 21개의 쿼리가 발생하는 것을 확인했다.1.1. 원인 분석이러한 현상이 발생하는 원인은 ItemService의 getItemList() 메서드 로직에 있다.ItemRepository.searchItems(...)가 호출되면서 Item 엔티티 목록을 조회하는 쿼리 1회가 실행된다.조회된 엔티티들을 DTO로 변환하기 위해 .map(item -> ItemListResponse.fromEntity(...))가 실행된다.문제는 ItemListResponse.fr..