Spring Boot 集成 Redis 打造高效点赞系统
在当今社交网络、内容分享平台盛行的时代,点赞功能几乎无处不在。它不仅能增强用户与内容之间的互动性,还能为平台运营提供有价值的数据洞察。而利用 Spring Boot 集成 Redis 来构建点赞系统,凭借 Redis 的高性能、原子操作特性,可以快速、准确地处理大量点赞请求,确保点赞数据的实时更新与一致性。接下来,就让我们深入探讨如何一步步实现这个点赞系统。
一、Redis 简介及其在点赞系统中的优势
Redis 是一款开源的、基于内存的高性能 key-value 存储数据库,它支持多种数据结构,如字符串(String)、列表(List)、集合(Set)、有序集合(Sorted Set)等,这些特性使其在诸多应用场景中表现卓越。
在点赞系统里,Redis 的优势尽显:
- 高速读写:点赞操作往往伴随着频繁的数据读写,Redis 将数据存储在内存中,使得数据的访问速度极快,能够瞬间响应用户的点赞请求,几乎没有延迟感,极大提升了用户体验。
- 原子操作:对于点赞这种并发量极高的操作,Redis 提供的原子操作确保了数据的准确性。例如,多个用户同时对同一内容点赞,利用 Redis 的 INCR 命令(用于对存储在 key 中的数字值进行自增操作)可以原子地增加点赞数,避免了传统数据库加锁解锁带来的性能开销以及可能出现的并发错误。
- 数据结构灵活适配:点赞相关的数据可以巧妙地利用 Redis 的不同数据结构来存储。比如,使用集合(Set)来记录点赞用户,方便快速判断某个用户是否已经点过赞;用字符串(String)存储点赞数,便于直观地展示点赞总量。
二、Spring Boot 集成 Redis 前期准备
-
安装 Redis
- 下载安装:前往 Redis 官方网站(https://redis.io/)下载适合你操作系统的 Redis 版本。以常见的 Linux 系统为例,解压下载的文件后,进入解压目录,通过以下命令启动 Redis 服务器:
src/redis-server
若要让 Redis 在后台持续运行,可使用:
src/redis-server &
- 配置与测试:Redis 默认配置文件为
redis.conf
,可以根据需求对端口号(默认 6379)、密码保护等参数进行调整。启动后,通过redis-cli
命令进入 Redis 客户端,输入ping
,若返回PONG
,则表明 Redis 服务器启动成功且正常通信。
-
创建 Spring Boot 项目
- 使用熟悉的 IDE(如 Intellij IDEA 或 Eclipse)创建一个新的 Spring Boot 项目。在项目创建过程中,勾选
Spring Data Redis
依赖,这将自动引入与 Redis 交互所需的基础类库,同时勾选Web
依赖,方便后续搭建供前端调用的接口。
- 使用熟悉的 IDE(如 Intellij IDEA 或 Eclipse)创建一个新的 Spring Boot 项目。在项目创建过程中,勾选
三、Spring Boot 项目配置 Redis
在 Spring Boot 项目的 application.properties
(或 application.yml
)文件中,配置 Redis 相关参数:
# Redis 服务器地址
spring.redis.host=localhost
# Redis 端口号
spring.redis.port=6379
# Redis 数据库编号,默认 0
spring.redis.database=0
# 是否开启 SSL,一般情况关闭,如为 true,需配置证书等相关信息
spring.redis.ssl=false
# Redis 连接密码,若未设置密码则留空
spring.redis.password=
若采用 application.yml
格式,配置如下:
spring:
redis:
host: localhost
port: 6379
database: 0
ssl: false
password:
完成配置后,Spring Boot 会自动创建 RedisTemplate
和 StringRedisTemplate
,前者用于操作各种数据类型,后者专门针对字符串类型进行优化,方便后续在代码中与 Redis 进行交互。
四、点赞系统核心功能实现
- 点赞功能
创建一个LikeService
类来封装点赞相关逻辑:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
@Service
public class LikeService {
private final RedisTemplate<String, Object> redisTemplate;
@Autowired
public LikeService(RedisTemplate<String, Object> redisTemplate) {
this.redisTemplate = redisTemplate;
}
public void like(String targetId, String userId) {
// 使用集合记录点赞用户,防止重复点赞
redisTemplate.opsForSet().add(targetId + ":likes", userId);
// 点赞数自增,使用字符串存储点赞数,方便后续展示
redisTemplate.opsForValue().increment(targetId + ":likeCount", 1);
}
}
在上述代码中,like
方法接收目标内容的唯一标识 targetId
(如文章 ID、图片 ID 等)和点赞用户的 ID userId
作为参数。首先,利用集合 opsForSet()
方法将点赞用户添加到以 targetId + ":likes"
为 key 的集合中,确保同一用户对同一内容不会重复点赞;接着,通过 opsForValue()
的 increment
方法对 targetId + ":likeCount"
这个存储点赞数的字符串值进行自增操作,原子地更新点赞数量。
- 取消点赞功能
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
@Service
public class LikeService {
// 省略前面的构造注入代码
public void unlike(String targetId, String userId) {
redisTemplate.opsForSet().remove(targetId + ":likes", userId);
redisTemplate.opsForValue().decrement(targetId + ":likeCount", 1);
}
}
unlike
方法与 like
方法相对应,从点赞用户集合中移除当前用户,并将点赞数减 1,保证点赞数据的准确更新。
- 判断用户是否点赞
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
@Service
public class LikeService {
// 省略前面的构造注入代码
public boolean hasLiked(String targetId, String userId) {
return redisTemplate.opsForSet().isMember(targetId + ":likes", userId);
}
}
hasLiked
方法通过查询点赞用户集合,快速判断指定用户是否已经对给定目标内容点过赞,为前端展示个性化按钮状态(如已点赞显示 “取消点赞”,未点赞显示 “点赞”)提供依据。
- 获取点赞数
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
@Service
public class LikeService {
// 省略前面的构造注入代码
public long getLikeCount(String targetId) {
Long count = redisTemplate.opsForValue().get(targetId + ":likeCount");
return count == null? 0 : count;
}
}
getLikeCount
方法从 Redis 中获取存储点赞数的字符串值,并将其转换为长整型返回,若获取的值为 null
,则说明该内容还未收到点赞,默认返回 0。
五、搭建对外接口
创建 LikeController
类,作为与前端交互的接口层:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/like")
public class LikeController {
private final LikeService likeService;
@Autowired
public LikeController(LikeService likeService) {
this.likeService = likeService;
}
@PostMapping("/{targetId}")
public void like(@PathVariable("targetId") String targetId, @RequestHeader("userId") String userId) {
likeService.like(targetId, userId);
}
@DeleteMapping("/{targetId}")
public void unlike(@PathVariable("targetId") String targetId, @RequestHeader("userId") String userId) {
likeService.unlike(targetId, userId);
}
@GetMapping("/{targetId}/hasLiked")
public boolean hasLiked(@PathVariable("targetId") String targetId, @RequestHeader("userId") String userId) {
return likeService.hasLiked(targetId, userId);
}
@GetMapping("/{targetId}/count")
public long getLikeCount(@PathVariable("targetId") String targetId) {
return likeService.getLikeCount(targetId);
}
}
这个控制器类提供了四个接口:
/like/{targetId}
:接收 POST 请求,用于用户点赞,从请求头中获取用户 ID,调用like
服务方法实现点赞逻辑。/like/{targetId}
:接收 DELETE 请求,用于用户取消点赞,同样获取用户 ID 后调用unlike
服务方法。/like/{targetId}/hasLiked
:通过 GET 请求,判断用户是否已点赞,返回布尔值结果给前端。/like/{targetId}/count
:以 GET 请求获取点赞数,将点赞数返回给前端展示。
六、测试点赞系统
可以使用工具如 Postman 对搭建好的接口进行测试:
- 点赞测试:发送 POST 请求到
/like/1
(假设1
为某篇文章的 ID),在请求头中设置userId
为某个用户 ID,如user1
,请求成功后,查看 Redis 中对应的数据变化,点赞用户集合应增加user1
,点赞数应自增 1。 - 取消点赞测试:发送 DELETE 请求到
/like/1
,同样携带user1
的用户 ID,之后验证点赞用户集合移除user1
,点赞数减 1。 - 判断点赞状态测试:发送 GET 请求到
/like/1/hasLiked
,携带user1
的用户 ID,根据之前的操作结果,应正确返回true
或false
。 - 获取点赞数测试:发送 GET 请求到
/like/1/count
,应返回当前准确的点赞数量。
通过以上全面的测试,确保点赞系统的各个功能正常运行,能够稳定地处理大量点赞请求,为用户提供流畅的点赞体验。
七、总结
通过 Spring Boot 与 Redis 的紧密集成,我们成功构建了一个高效、准确的点赞系统。利用 Redis 的高性能、原子操作以及丰富的数据结构特性,配合 Spring Boot 的简洁开发模式,快速实现了点赞、取消点赞、判断点赞状态和获取点赞数等核心功能,并通过搭建对外接口,方便前端进行调用。在实际项目应用中,你可以根据平台的具体需求进一步优化和扩展这个点赞系统,比如结合用户行为分析、实现热门内容推荐等,充分挖掘点赞数据的价值,提升平台的用户活跃度与竞争力。