SpringBoot 는 Redis 의 zset 를 사용 하여 온라인 사용자 정 보 를 통계 합 니 다.
7430 단어 SpringBootRediszset
현재 의 응용 프로그램 은 모두 심장 박동 패 키 지 를 사용 하여 사용자 가 온라인 인지 아 닌 지 를 표시 하 는 경향 이 있다.사용자 가 로그 인 한 후 일정 시간 마다 서버 에 메 시 지 를 보 내 현재 사용자 가 온라인 임 을 표시 합 니 다.서버 는 클 라 이언 트 의 심장 박동 메 시 지 를 5 분 안에 받 아 온라인 사용자 로 볼 수 있 는 시간 차 를 정의 할 수 있 습 니 다.
온라인 사용자 통계 의 실현
데이터베이스 기반 구현
가장 쉬 운 방법 은 사용자 표 에 마지막 심장 박동 가방 을 추가 하 는 날짜 시간 필드 lastactive。서버 가 심장 박동 을 받 은 후,매번 이 필드 를 현재 의 최신 시간 으로 업데이트 합 니 다.
최근 5 분 동안 활성 화 된 사용자 수 를 조회 하려 면 SQL 한 마디 로 간단하게 완성 할 수 있다.
SELECT COUNT(1) AS `online_user_count` FROM `user` WHERE `last_active` BETWEEN '2020-12-22 13:00:00' AND '020-12-22 13:05:00';
단점 도 분명 하 다.검색 효율 을 높이 기 위해 lastactive 필드 에 색인 을 추가 합 니 다.심장 박동 의 업데이트 로 인해 색인 트 리 를 자주 유지 하고 효율 이 매우 낮 습 니 다.Redis 기반 실현
이것 은 비교적 이상 적 인 실현 방식 이다.Redis 는 메모 리 를 바탕 으로 읽 기와 쓰 기 를 하 는데 관계 형 데이터베이스 보다 성능 이 훨씬 좋 고 Zset 가 제공 하 는 온라인 사용자 의 통계 서 비 스 를 편리 하 게 구축 할 수 있다.
Redis 의 Zset
여 기 는 redis 와 관련 된 것 이 많 지 않 습 니 다.아래 zset 를 간단하게 설명 하 겠 습 니 다.그것 은 질서 있 는 set 집합 으로 집합 중의 모든 요 소 는 2 개의 물건 으로 구성 된다.
4.567917.member 가 집합 인 이상 집합 중의 요소 이 고 중복 할 수 없다.
요소 추가
ZADD key score member [score member ...]
집합 에 하나 이상 의 요 소 를 한꺼번에 추가 합 니 다.member 가 존재 하면 현재 score 를 사용 하여 덮어 씁 니 다.모든 원소 의 수량 을 통계 하 다
ZCARD key
score 값 이 min 과 max 사이 의 요소 수량 을 통계 합 니 다.
ZCOUNT key min max
score 값 이 min 과 max 사이 에 있 는 요 소 를 삭제 합 니 다.
ZREMRANGEBYSCORE key min max
하나의 예시내 마음속 프로 그래 밍 언어의 평 점 순 위 를 zset 로 저장 하려 고 합 니 다.이 키 는 lang 이 라 고 합 니 다.
정 보 를 추가 하고 새로 추 가 된 요소 개 수 를 되 돌려 줍 니 다.
> zadd lang 999 php 10 java 9 go 8 python 7 javascript
"5"
추 가 된 수량 보기
> zcard lang
"5"
평 점 8-10 사이 의 요소 개 수 를 보면 3 개가 있 습 니 다.
> zcount lang 8 10
"3"
평 점 이 8-1000 인 요 소 를 삭제 하고 삭 제 된 개 수 를 되 돌려 줍 니 다.
> ZREMRANGEBYSCORE lang 8 1000
"4"
온라인 사용자 서비스의 실현zset 를 알 게 되면 온라인 사용자 의 통계 서 비 스 를 실현 할 수 있 습 니 다.
사고의 방향 을 실현 하 다.
클 라 이언 트 는 5 분 마다 서버 에 심장 박동 을 보 냅 니 다.서버 는 세 션 에 따라 사용자 의 ID 를 가 져 옵 니 다.zset 의 member 입 니 다.
zset 에 저장 하면 score 는 현재 심장 박동 을 받 은 시간 스탬프 입 니 다.같은 사용자 가 두 번 째 로 심장 박동 을 보 낼 때 해당 하 는 score 값 을 업데이트 합 니 다.업데이트 가 메모리 에 있 기 때문에 이 속 도 는 상당히 빠 릅 니 다.
zadd users 1608616915109 10000
온라인 사용자 의 수 를 집계 해 야 한다.본질 적 으로 통계 해 야 한다.최근 5 분 동안 심장 박동 을 보 내 는 사용자 가 있 으 며,zcount 를 통 해 쉽게 집계 할 수 있다.프로그램 을 통 해 현재 시간 스탬프 를 가 져 옵 니 다.max Score 로 시간 스탬프 를 5 분 빼 면 minScore 로 합 니 다.
zcount users 1608616615109 1608616915109
일부 사용자 들 은 오랫동안 로그 인 을 하지 않 았 을 수도 있 기 때문에 ZREMRANGEBYSCORE 를 통 해 청 소 를 할 수 있 습 니 다.프로그램 을 통 해 현재 시간 스탬프 를 가 져 옵 니 다.5 분 을 뺀 후 maxScore 로 0 을 사용 합 니 다.minScore 로 서 5 분 이 넘 도록 심장 박동 패 키 지 를 보 내지 않 은 모든 사용 자 를 청소 하 는 것 을 의미 합 니 다.
ZREMRANGEBYSCORE users 0 1608616615109
구현 코드
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import javax.annotation.Resource;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
/**
*
*
*
*
* @author Administrator
*
*/
@Component
public class OnlineUserStatsService {
private static final String ONLINE_USERS = "onlie_users";
@Resource
private StringRedisTemplate stringRedisTemplate;
/**
*
* @param userId
* @return
*/
public Boolean online(Integer userId) {
return this.stringRedisTemplate.opsForZSet().add(ONLINE_USERS, userId.toString(), Instant.now().toEpochMilli());
}
/**
* ,
* @param duration
* @return
*/
public Long count(Duration duration) {
LocalDateTime now = LocalDateTime.now();
return this.stringRedisTemplate.opsForZSet().count(ONLINE_USERS,
now.minus(duration).atZone(ZoneId.systemDefault()).toInstant().toEpochMilli(),
now.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
}
/**
* ,
* @return
*/
public Long count() {
return this.stringRedisTemplate.opsForZSet().zCard(ONLINE_USERS);
}
/**
*
* @param duration
* @return
*/
public Long clear(Duration duration) {
return this.stringRedisTemplate.opsForZSet().removeRangeByScore(ONLINE_USERS, 0,
LocalDateTime.now().minus(duration).atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
}
}
사용 예시
@Resource
private OnlineUserStatsService onlineUserStatsService;
@Test
public void test() {
// ID 1
boolean result = this.onlineUserStatsService.online(1);
System.out.println("online=" + result);
// 5 , ,
Long count = this.onlineUserStatsService.count(Duration.ofMinutes(5));
System.out.println("oneline count=" + count);
//
count = this.onlineUserStatsService.count();
System.out.println("all count=" + count);
// 1
Long clear = this.onlineUserStatsService.clear(Duration.ofDays(1));
System.out.println("clear=" + clear);
}
메모리 소모 분석예산 레 디 스 메모리 소모
저 는 Redis 의 메모리 배분 에 익숙 하지 않 습 니 다.제 생각 대로 데 이 터 를 작 성 했 을 뿐 입 니 다.그래서 제 가 여기 서 이해 하 는 것 은 잘못된 것 일 수도 있 습 니 다.하지만 증명 에 지장 이 없 을 것 같 습 니 다.-이런 장면 에서 Zset 를 사용 하면 메모리 소모 가 매우 적다 는 사실.
구상 onlieusers 는 1 억 명의 사용자 의 상태 정 보 를 저장 해 야 합 니 다.각 요소 score 와 member 는 10 개의 바이트 로 저장 해 야 합 니 다.그러면 모두 20G 메모리 가 필요 합 니 다.20G 의 메모 리 는 현재 서버 로 서 는 큰 문제 가 아니다.
마지막.
String userId = "10010";
System.out.println(userId.getBytes().length); // => 5
byte[] bin = ByteBuffer.allocate(4).putInt(Integer.valueOf(userId)).array();
System.out.println(bin.length); // => 4
System.out.println(ByteBuffer.wrap(bin).getInt()); // ID => 10010
이상 은 SpringBoot 가 Redis 의 zset 를 사용 하여 온라인 사용자 정 보 를 통계 하 는 상세 한 내용 입 니 다.SpringBoot 가 온라인 사용자 정 보 를 통계 하 는 데 관 한 자 료 는 저희 의 다른 관련 글 을 주목 하 시기 바 랍 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
【Java・SpringBoot・Thymeleaf】 에러 메세지를 구현(SpringBoot 어플리케이션 실천편 3)로그인하여 사용자 목록을 표시하는 응용 프로그램을 만들고, Spring에서의 개발에 대해 공부하겠습니다 🌟 마지막 데이터 바인딩에 계속 바인딩 실패 시 오류 메시지를 구현합니다. 마지막 기사🌟 src/main/res...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.