Spring Event를 통한 사용자 랭킹 서비스 개선

Zoonmy·2025년 4월 2일
post-thumbnail

1️⃣ 배경

사용자 랭킹 서비스에서 점수, 티어, 뱃지 시스템을 구현하려고 했습니다. 하지만 이 과정에서 서비스 간 결합도가 급격히 증가하는 문제가 발생했습니다.

🔥 문제 상황

  1. 점수 변경 → 티어 변경
    • 사용자의 점수가 변경될 때마다 티어를 다시 계산해야 함
  2. 티어 변경 → 뱃지 획득
    • 특정 티어에 도달하면 새로운 뱃지를 부여해야 함
  3. 점수 변경 → 뱃지 획득
    • 점수가 특정 조건을 만족하면 새로운 뱃지를 부여해야 함

🚨 문제점: 서비스 간 직접 호출이 많아지면서 높은 결합도(coupling) 가 발생했고, 이는 유지보수성과 성능 저하로 이어졌습니다.


2️⃣ 해결 방안 모색

이 문제를 해결하기 위해 Spring Event를 도입하여 서비스 간 결합도를 낮추고, 비동기 이벤트 기반 처리를 활용하여 성능을 최적화하고자 했습니다.

✅ Spring Event 도입 이유

  • 서비스 간 결합도 감소 → 이벤트 발행(Publisher)과 구독(Listener) 구조로 변경
  • 비동기 처리로 성능 최적화 → 이벤트가 발생하면 비동기적으로 처리하여 응답 속도 향상
  • 유연한 확장 가능 → 새로운 뱃지 조건이나 티어 규칙이 추가되더라도 기존 코드 수정 최소화

3️⃣ 해결 방법

🚀 Spring Event 적용 방식

  1. 점수 변경 시 이벤트 발행

    @Component
    public class ScoreService {
        private final ApplicationEventPublisher eventPublisher;
    
        public void updateScore(User user, int score) {
            user.setScore(score);
            eventPublisher.publishEvent(new ScoreUpdatedEvent(user));
        }
    }
  2. 티어 변경 로직을 이벤트 리스너로 처리

    @Component
    public class TierEventListener {
        @EventListener
        public void handleScoreUpdated(ScoreUpdatedEvent event) {
            User user = event.getUser();
            user.updateTier();
            eventPublisher.publishEvent(new TierUpdatedEvent(user));
        }
    }
  3. 뱃지 부여 로직도 이벤트 리스너로 처리

    @Component
    public class BadgeEventListener {
        @EventListener
        public void handleTierUpdated(TierUpdatedEvent event) {
            User user = event.getUser();
            user.checkAndGrantBadges();
        }
    }

결과: 점수 → 티어 → 뱃지의 흐름을 이벤트 기반으로 변경하여 서비스 간 결합도를 낮추고 성능 최적화


4️⃣ 성능 분석

Spring MVC 방식과 Spring Event 방식의 성능 차이를 비교하였습니다.

테스팅은 Jmeter를 사용해 진행하였으며, '사용자가 리뷰를 작성' 할 때 점수를 얻는 조건으로 두어 테스트하였습니다.

📈 1) 처리량 비교 (Requests/sec)

요청 수🔴 순수 Spring MVC🟢 Spring MVC + Event🔼 차이
10,000642.8720.7🔺 12.1% ↑
20,000783.61,029.7🔺 31.4% ↑
30,000594.2647.1🔺 8.9% ↑
40,000583.5649.8🔺 11.4% ↑

📉 2) 평균 응답 시간 비교 (ms)

요청 수🔴 순수 Spring MVC🟢 Spring MVC + Event🔽 차이
10,000149 ms127 ms🔽 14.8% ↓
20,000122 ms93 ms🔽 23.8% ↓
30,000493 ms452 ms🔽 8.3% ↓
40,000668 ms601 ms🔽 10% ↓

📊 3) 안정성 비교 (응답 시간 표준 편차)

요청 수🔴 순수 Spring MVC🟢 Spring MVC + Event🔽 차이
10,00055.0446.48🔽 15.6% ↓
20,00032.7217.75🔽 45.8% ↓
30,00069.1265.49🔽 5.3% ↓
40,00096.8574.86🔽 22.7% ↓

결과 요약

  • Spring Event 적용 후 처리량이 증가하여 기존 대비 최대 24% 응답 속도 개선
  • 응답 시간이 평균 10~25% 감소, 특히 고부하 상황에서 더 큰 차이 발생
  • 응답 시간의 표준 편차 감소 → 시스템 안정성 증가

추가적으로 Kafka나 Rabbit MQ를 사용해서 이벤트 스트림을 통한 이벤트 처리를 하는 방법으로 개선하는 것도 좋을 것 같다고 생각했습니다.

현재 방안으로는, Event가 소실되게 된다면 해당 서비스는 제대로 동작하지 않을 수도 있기 때문입니다.

profile
열시미 해야쥐

0개의 댓글