网站加载性能优化

网站优化主要来说就是加缓存来用空间换时间,方案有以下三种

  • 本地缓存

    • 将数据库缓存在应用服务器上,性能最好
    • 常用缓存工具: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> postListCache;

    //缓存帖子总数
    private LoadingCache 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 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);
    }
}

在数据库插入一万条数据进行压力测试

未加缓存前

image.png

优化后

image.png

吞吐量大概提升40%~50%

你可能感兴趣的:(java,中间件,java,redis,缓存)