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

🚨 문제점: 서비스 간 직접 호출이 많아지면서 높은 결합도(coupling) 가 발생했고, 이는 유지보수성과 성능 저하로 이어졌습니다.
이 문제를 해결하기 위해 Spring Event를 도입하여 서비스 간 결합도를 낮추고, 비동기 이벤트 기반 처리를 활용하여 성능을 최적화하고자 했습니다.

점수 변경 시 이벤트 발행
@Component
public class ScoreService {
private final ApplicationEventPublisher eventPublisher;
public void updateScore(User user, int score) {
user.setScore(score);
eventPublisher.publishEvent(new ScoreUpdatedEvent(user));
}
}
티어 변경 로직을 이벤트 리스너로 처리
@Component
public class TierEventListener {
@EventListener
public void handleScoreUpdated(ScoreUpdatedEvent event) {
User user = event.getUser();
user.updateTier();
eventPublisher.publishEvent(new TierUpdatedEvent(user));
}
}
뱃지 부여 로직도 이벤트 리스너로 처리
@Component
public class BadgeEventListener {
@EventListener
public void handleTierUpdated(TierUpdatedEvent event) {
User user = event.getUser();
user.checkAndGrantBadges();
}
}
✅ 결과: 점수 → 티어 → 뱃지의 흐름을 이벤트 기반으로 변경하여 서비스 간 결합도를 낮추고 성능 최적화
Spring MVC 방식과 Spring Event 방식의 성능 차이를 비교하였습니다.
테스팅은
Jmeter를 사용해 진행하였으며, '사용자가 리뷰를 작성' 할 때 점수를 얻는 조건으로 두어 테스트하였습니다.
| 요청 수 | 🔴 순수 Spring MVC | 🟢 Spring MVC + Event | 🔼 차이 |
|---|---|---|---|
| 10,000 | 642.8 | 720.7 | 🔺 12.1% ↑ |
| 20,000 | 783.6 | 1,029.7 | 🔺 31.4% ↑ |
| 30,000 | 594.2 | 647.1 | 🔺 8.9% ↑ |
| 40,000 | 583.5 | 649.8 | 🔺 11.4% ↑ |
| 요청 수 | 🔴 순수 Spring MVC | 🟢 Spring MVC + Event | 🔽 차이 |
|---|---|---|---|
| 10,000 | 149 ms | 127 ms | 🔽 14.8% ↓ |
| 20,000 | 122 ms | 93 ms | 🔽 23.8% ↓ |
| 30,000 | 493 ms | 452 ms | 🔽 8.3% ↓ |
| 40,000 | 668 ms | 601 ms | 🔽 10% ↓ |
| 요청 수 | 🔴 순수 Spring MVC | 🟢 Spring MVC + Event | 🔽 차이 |
|---|---|---|---|
| 10,000 | 55.04 | 46.48 | 🔽 15.6% ↓ |
| 20,000 | 32.72 | 17.75 | 🔽 45.8% ↓ |
| 30,000 | 69.12 | 65.49 | 🔽 5.3% ↓ |
| 40,000 | 96.85 | 74.86 | 🔽 22.7% ↓ |
추가적으로 Kafka나 Rabbit MQ를 사용해서 이벤트 스트림을 통한 이벤트 처리를 하는 방법으로 개선하는 것도 좋을 것 같다고 생각했습니다.
현재 방안으로는, Event가 소실되게 된다면 해당 서비스는 제대로 동작하지 않을 수도 있기 때문입니다.