个人网站性能优化经历(1)Redis优化过程

自己搭建了一个基于SpringBoot+Spring Security+MyBatis+MySQL+Redis+Thymeleaf的博客网站
上线个人云服务器后,发现服务器访问慢。个人服务器是1核2G的,1M宽带,虽然服务器是低配的,但是可以通过优化代码,中间件等手段,来提升性能。

一、redis文章缓存

网站虽然用上了redis缓存,但是缓存只用到了文章点赞,文章访问量等等,根本没有发挥出缓存的真正作用,这个博客网站最常用的就是网站首页,博客文章,重点是要把这两个加入缓存。
缓存是基于内存的,读取速度比数据库快很多,数据库是基于硬盘的。

1、先理清逻辑,博客文章加入缓存之前是这样的逻辑:一般访问文章,先从数据库读取数据,如果有数据,直接返回,如果没有找到数据,返回404,或者返回空。
2、加入缓存的话,访问文章,先从缓存中读取,如果找到了,就不用再读取数据库,如果没找到数据,再读取数据库,从数据库读取数据,这里就跟步骤一相同。另外,缓存中没读到的数据,而数据库读到的数据,加入到缓存里面,这样,下次再访问这篇文章,就不用再访问数据库了,增加数据库的压力。
3、如果缓存没有这篇文章,数据库也没有这篇文章,那还要不要加缓存呢?

答案是要的,这是因为如果用户一直访问这篇不存在的文章,那么就会持续增加数据库的压力,因此加入缓存,减少数据库的压力。

4、内存是有限的,是要一直把数据库不存在的文章加入缓存吗?

比如把01文章,02文章,03文章…一大批文章都不存在,都要加入缓存吗?

答案是要的,可以设置缓存失效的时间,比如30秒,也可以设置一小时等等,具体看你具体使用。

5、更新文章之后,缓存记得也要进行更新。

更新缓存操作:先找缓存,找到该文章的缓存,对缓存进行删除,之后再进行新增操作。

理清了思路,接下来就是代码了:

/**
 * 向redis中保存文章内容
 */
public void putArticleOnRedis(String key, Object field, Object value) {
    hashRedisServiceImpl.put(key, field, value);
}

/**
 * 获得redis中的文章内容
 */
public Object getArticleOnRedis(String key, Object field) {
    boolean articleExist = hashRedisServiceImpl.hasHashKey(key, field);
    if (articleExist) {
        return hashRedisServiceImpl.get(key, field);
    }
    return null;
}
/**
 * 获取文章
 *
 * @param articleId 文章id
 * @return
 */
@PostMapping("/getArticleByArticleId")
public @ResponseBody
JSONObject getArticleById(@RequestParam("articleId") String articleId,
                          @AuthenticationPrincipal Principal principal) {
    String username = null;
    try {
        username = principal.getName();
    } catch (NullPointerException e) {
        logger.info("This user is not login");
    }
    //取缓存
    try {
        Object articleByRedis = redisService.getArticleOnRedis("article", articleId);
        if (articleByRedis != null) {
            JSONObject jsonObject = JSONObject.fromObject(articleByRedis);
            Object articleTitle = jsonObject.get("articleTitle");
            logger.info("取缓存里面的文章:" + articleTitle);
            return jsonObject;
        } else {
            //取数据库
            return getDBContent(articleId, username);
        }
    } catch (Exception e) {
        logger.error("取缓存报异常了:" + e.getMessage());
        //取数据库
        return getDBContent(articleId, username);
    }
}

private JSONObject getDBContent(@RequestParam("articleId") String articleId, String username) {
    JSONObject articleByDB = articleService.getArticleByArticleId(Long.parseLong(articleId), username);
    if (articleByDB != null) {
        logger.info("取数据库里面的文章");
        redisService.putArticleOnRedis("article", articleId, articleByDB);
        logger.info("保存文章到数据库");
    }
    return articleByDB;
}

更新缓存

public JSONObject updateArticleById(Article article) {
    Article realArticle = articleMapper.getArticleUrlById(article.getId());
    if ("原创".equals(article.getArticleType())) {
        article.setOriginalAuthor(article.getAuthor());
        String url = SiteOwner.SITE_OWNER_URL + "/article/" + realArticle.getArticleId();
        article.setArticleUrl(url);
    }
    articleMapper.updateArticleById(article);
    JSONObject articleReturn = new JSONObject();
    articleReturn.put("status", 200);
    articleReturn.put("articleTitle", article.getArticleTitle());
    articleReturn.put("updateDate", article.getUpdateDate());
    articleReturn.put("author", article.getOriginalAuthor());
    //本博客中的URL
    articleReturn.put("articleUrl", "/article/" + realArticle.getArticleId());

    try {
        //处理缓存,先删除之前的缓存,然后再新增缓存
        redisService.deleteArticleOnRedis("article", realArticle.getArticleId() + "");
        JSONObject jsonObject = genJsonObject(realArticle.getArticleId(), null, realArticle);
        jsonObject.put("articleContent", article.getArticleContent());
        //新增缓存
        redisService.putArticleOnRedis("article", realArticle.getArticleId() + "", jsonObject);
    } catch (Exception e) {
        logger.error("删除缓存报异常了:" + e.getMessage());
    }
    return articleReturn;

}
6、总结:

业务逻辑,先从缓存取文章,没有则从数据库取文章,然后新增文章到缓存。修改文章的时候,先删除缓存,再新增缓存。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

exodus3

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值