网站优化主要来说就是加缓存来用空间换时间,方案有以下三种
-
本地缓存
- 将数据库缓存在应用服务器上,性能最好
- 常用缓存工具:Ehcache、Guava、Caffeine等。
-
分布式缓存
- 将数据缓存在NoSQL数据库上,跨服务器
- 常用缓存工具:MemCache、Redis等
-
多级缓存
- 一级缓存(本地缓存)>二级缓存(分布式缓存)>DB
- 避免缓存雪崩(缓存失效,大量请求直达DB),提高系统的可用性。
本地缓存配置
#caffeine
caffeine.posts.max-size = 15
caffeine.posts.expire-seconds=180
在本项目中主要用于优化文章缓存,缓存前15页的数据,以及文章的数量
编写业务代码
@Service
public class DiscussPostSerivce {
private static final Logger logger = LoggerFactory.getLogger(DiscussPostSerivce.class);
@Autowired
private DiscussPostMapper discussPostMapper;
@Autowired
private SensitiveFilter sensitiveFilter;
@Value("${caffeine.posts.max-size}")
private int maxSize;
@Value("${caffeine.posts.expire-seconds}")
private int expireSeconds;
//caffeine的核心接口Cache,LoadingCache,AsyncLoadingCache
//帖子列表的缓存
private LoadingCache<String,List<DiscussPost>> postListCache;
//缓存帖子总数
private LoadingCache<Integer,Integer> postRowsCache;
@PostConstruct
public void init(){
//初始化帖子列表缓存
postListCache = Caffeine.newBuilder()
.maximumSize(maxSize)
.expireAfterWrite(expireSeconds, TimeUnit.SECONDS)
.build(key -> {
if (key == null || key.length() ==0){
throw new IllegalArgumentException("缓存参数错误");
}
String[] params = key.split(":");
if (params == null || params.length !=2){
throw new IllegalArgumentException("缓存参数错误");
}
int offset = Integer.valueOf(params[0]);
int limit =Integer.valueOf(params[1]);
//二级缓存位置 Redis >mysql
logger.debug("load post list from DB");
return discussPostMapper.selectDiscussPosts(0,offset,limit,1);
});
//初始化帖子总数缓存
postRowsCache = Caffeine.newBuilder()
.maximumSize(maxSize)
.expireAfterWrite(expireSeconds,TimeUnit.SECONDS)
.build(key->{
logger.debug("load post list from DB");
return discussPostMapper.selectDiscussPostRows(key);
});
}
public List<DiscussPost> findDiscussPosts(int userId,int offset,int limit,int ordermode){
if (userId == 0 && ordermode == 1){
return postListCache.get(offset + ":" + limit);
}
logger.debug("load post list from DB");
return discussPostMapper.selectDiscussPosts(userId, offset, limit,ordermode);
}
public int findDiscussPostRows(int userId){
if (userId == 0){
return postRowsCache.get(userId);
}
logger.debug("load post rows from DB");
return discussPostMapper.selectDiscussPostRows(userId);
}
}
在数据库插入一万条数据进行压力测试
未加缓存前
优化后
吞吐量大概提升40%~50%