项目描述:Redis实现的实时排行榜系统
本项目是一个基于 Spring Boot 和 Redis 的实时排行榜系统,利用 Redis 的有序集合(ZSet)数据结构高效地管理用户分数和排名。 用于Redis中Zset数据结构学习
Service
java
package org.example.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import java.util.Set;
@Service
public class LeaderboardService {
private static final String LEADERBOARD_KEY = "game:leaderboard";
@Autowired
private StringRedisTemplate redisTemplate;
// 增加或更新用户分数
public void addOrUpdateScore(String userId, double score) {
redisTemplate.opsForZSet().addIfAbsent(LEADERBOARD_KEY,userId,score);
}
// 获取用户排名(Redis 排名从 0 开始)
public Long getUserRank(String userId) {
Long l = redisTemplate.opsForZSet().reverseRank(LEADERBOARD_KEY, userId);
if(l==null)return null;
return l+1;
}
// 获取用户分数
public Double getUserScore(String userId) {
Double score = redisTemplate.opsForZSet().score(LEADERBOARD_KEY, userId);
if(score==0)
return null;
return score;
}
// 获取排行榜前 N 名
public Set<String> getTopUsers(int topN) {
return redisTemplate.opsForZSet().reverseRange(LEADERBOARD_KEY, 0, topN - 1);
}
}
下面是control
java
package org.example.control;
import org.example.service.LeaderboardService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
@RestController
@RequestMapping("/leaderboard")
public class LeaderboardController {
@Autowired
private LeaderboardService leaderboardService;
// 增加或更新用户分数
@PostMapping("/add")
public String addScore(@RequestParam String userId, @RequestParam double score) {
leaderboardService.addOrUpdateScore(userId, score);
return "Score added/updated successfully!";
}
@PostMapping("/addBatch")
public String addScoresBatch(@RequestBody List<Map<String, Object>> users) {
for (Map<String, Object> user : users) {
String userId = (String) user.get("userId");
double score = Double.parseDouble(user.get("score").toString());
leaderboardService.addOrUpdateScore(userId, score);
}
return "Batch scores added/updated successfully!";
}
// 获取用户排名和分数
@GetMapping("/rank/{userId}")
public Map<String, Object> getUserRank(@PathVariable String userId) {
Long rank = leaderboardService.getUserRank(userId);
Double score = leaderboardService.getUserScore(userId);
return Map.of(
"userId", userId,
"rank", rank,
"score", score
);
}
// 获取排行榜前 N 名
@GetMapping("/top/{topN}")
public Map<String, Object> getTopUsers(@PathVariable int topN) {
Set<String> topUsers = leaderboardService.getTopUsers(topN);
// 获取每个用户的分数
Map<String, Object> leaderboard = topUsers.stream()
.collect(Collectors.toMap(
userId -> userId,
userId -> leaderboardService.getUserScore(userId)
));
return Map.of("leaderboard", leaderboard);
}
}