SpringBoot Redis集成测试:如何验证数据从Redis缓存而非MySQL读写?
嘿,我来分享几个在Spring Boot + Redis缓存场景下,验证数据是否从Redis读写而非MySQL的靠谱方法,都是日常开发里常用的:
直接查看Redis缓存内容
因为你用Docker Compose启动Redis,直接进入容器的Redis客户端就行:docker-compose exec redis redis-cli进入后可以用
KEYS *列出所有缓存键(注意生产环境别随便用这个,会阻塞Redis,测试环境没问题),或者用GET 你的缓存键名(比如你的缓存键是user::1,就执行GET user::1)。如果能拿到对应的数据,说明缓存已经存储成功。之后再调用查询接口,同时观察MySQL是否有新的查询请求——如果没有,就说明这次请求走了Redis缓存。监控MySQL的查询日志
开启MySQL的通用查询日志,就能清楚看到哪些SQL被执行了:- 进入MySQL容器:
docker-compose exec mysql bash - 修改MySQL配置(或者在Docker Compose的mysql服务里提前配置),开启
general_log:[mysqld] general_log = 1 general_log_file = /var/log/mysql/general.log - 重启MySQL服务(或者在Compose里重启),然后查看日志:
tail -f /var/log/mysql/general.log
当你第一次调用查询接口时,日志里会出现对应的SELECT语句;第二次及以后调用,如果日志里没有新的SELECT,就证明请求走了Redis缓存。如果是更新操作,日志里会有UPDATE语句,同时Redis里对应的缓存键应该被删除或更新(对应@CacheEvict或@CachePut注解的作用)。
- 进入MySQL容器:
在代码中添加日志标记
在你的DAO层(比如MyBatis的Mapper接口方法、JPA的Repository方法)里添加日志,比如:@Mapper public interface UserMapper { @Select("SELECT * FROM user WHERE id = #{id}") void logQuery(Long id) { System.out.println("从MySQL查询用户数据,ID: " + id); } User getUserById(Long id); }然后在Service层加了@Cacheable的方法里也加日志:
@Service public class UserService { @Cacheable(value = "user", key = "#id") public User getUserById(Long id) { System.out.println("从Redis缓存获取用户数据,ID: " + id); return userMapper.getUserById(id); } }调用接口时看日志输出,如果第一次出现MySQL的日志,第二次出现Redis的日志,就说明缓存生效了。
临时停止Redis服务做对比测试
在测试环境下,执行docker-compose stop redis停掉Redis服务,然后调用查询接口:- 如果是第一次查询,会走MySQL(日志里能看到);
- 如果之前已经缓存过数据,停掉Redis后再调用,要么会报错(如果没配置fallback),要么会再次走MySQL查询。
恢复Redis服务后,再次调用,就能看到请求回到Redis缓存,以此验证缓存的作用。
另外还要注意检查你的Spring Cache注解是否配置正确:比如@Cacheable的value和key是否符合预期,@CacheEvict是否在更新/删除方法上正确配置,这些都会直接影响缓存是否生效。
内容的提问来源于stack exchange,提问作者Imran

