Skip to content

Commit 3870cc5

Browse files
committed
Refactor: KEYS 대신 Redis 카운터를 사용하여 온라인 유저 수 조회 성능 개선
1 parent 71234e9 commit 3870cc5

File tree

3 files changed

+39
-3
lines changed

3 files changed

+39
-3
lines changed

src/main/java/com/back/global/websocket/config/WebSocketConstants.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,13 @@ private WebSocketConstants() {
4646
public static final String ROOM_USERS_KEY_PREFIX = "ws:room:";
4747
public static final String ROOM_USERS_KEY_SUFFIX = ":users";
4848

49+
/**
50+
* 전체 온라인 사용자 수 저장 Key
51+
* - 패턴: ws:online_users:count
52+
* - 값: Long (카운트)
53+
*/
54+
public static final String ONLINE_USER_COUNT_KEY = "ws:online_users:count";
55+
4956
// ===== Key 빌더 헬퍼 메서드 =====
5057

5158
public static String buildUserSessionKey(Long userId) {

src/main/java/com/back/global/websocket/service/UserSessionService.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ public void registerSession(Long userId, String sessionId) {
3434
redisSessionStore.saveUserSession(userId, newSession);
3535
redisSessionStore.saveSessionUserMapping(sessionId, userId);
3636

37+
redisSessionStore.incrementOnlineUserCount();
38+
3739
log.info("WebSocket 세션 등록 완료 - 사용자: {}, 세션: {}", userId, sessionId);
3840
}
3941

@@ -44,6 +46,9 @@ public void terminateSession(String sessionId) {
4446
if (userId != null) {
4547
redisSessionStore.deleteUserSession(userId);
4648
redisSessionStore.deleteSessionUserMapping(sessionId);
49+
50+
redisSessionStore.decrementOnlineUserCount();
51+
4752
log.info("WebSocket 세션 종료 완료 - 세션: {}, 사용자: {}", sessionId, userId);
4853
} else {
4954
log.warn("종료할 세션을 찾을 수 없음 - 세션: {}", sessionId);

src/main/java/com/back/global/websocket/store/RedisSessionStore.java

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -182,11 +182,35 @@ public long getRoomUserCount(Long roomId) {
182182

183183
public long getTotalOnlineUserCount() {
184184
try {
185-
Set<String> userKeys = redisTemplate.keys(WebSocketConstants.buildUserSessionKeyPattern());
186-
return userKeys != null ? userKeys.size() : 0;
185+
// 카운터 키에서 직접 값을 가져옴
186+
Object count = redisTemplate.opsForValue().get(WebSocketConstants.ONLINE_USER_COUNT_KEY);
187+
if (count instanceof Number) {
188+
return ((Number) count).longValue();
189+
}
190+
return 0L;
187191
} catch (Exception e) {
188192
log.error("전체 온라인 사용자 수 조회 실패", e);
189-
return 0;
193+
return 0; // 에러 발생 시 0 반환
194+
}
195+
}
196+
197+
public void incrementOnlineUserCount() {
198+
try {
199+
redisTemplate.opsForValue().increment(WebSocketConstants.ONLINE_USER_COUNT_KEY);
200+
} catch (Exception e) {
201+
log.error("온라인 사용자 수 증가 실패", e);
202+
}
203+
}
204+
205+
public void decrementOnlineUserCount() {
206+
try {
207+
// 카운터가 0보다 작아지지 않도록 방지
208+
Long currentValue = redisTemplate.opsForValue().decrement(WebSocketConstants.ONLINE_USER_COUNT_KEY);
209+
if (currentValue != null && currentValue < 0) {
210+
redisTemplate.opsForValue().set(WebSocketConstants.ONLINE_USER_COUNT_KEY, 0L);
211+
}
212+
} catch (Exception e) {
213+
log.error("온라인 사용자 수 감소 실패", e);
190214
}
191215
}
192216

0 commit comments

Comments
 (0)