(没有用注解)springboot+EHcache 实现文章浏览量的缓存和超时更新

2019-09-28 07:58:57

问题描述

当我们需要统计文章的浏览量的时候,最常规的做法就是:

1.访问文章链接www.abc.com/article/{id}

2.在控制层获取Article实体

3.得到文章浏览量count并且count++

4.最后update实体Article。

这么做对没有访问量的网站来说很棒,如果网站访问量很大,这么不停的读写数据库,会对服务器造成很大的压力。

解决思路

引入Ehcache,将文章的访问量存在cache中,每点击一次文章,将cache中的count加1.在有效的时间内访问文章只是将cache中的数据+1,超过指定时间则进行一次数据库更新。

解决方案

本文是在springboot整合ehcache的环境下验证的。springboot版本1.5.2 。ehcache版本2.6.11。springboot整合ehcache的步骤很简单,下面简单提一下,在pom文件中引入ehcache依赖

<dependency>
  <groupId>net.sf.ehcache</groupId>
  <artifactId>ehcache-core</artifactId>
  <version>2.6.11</version>
</dependency>

在类路径下存放ehcache.xml文件。

在application.yml中指定:

spring: 
 cache:
  jcache:
   config: classpath:ehcache.xml

最后在启动类标注@EnableCaching

引入缓存之后,接着我们的正题

在ehcache.xml文件中定义dayHits缓存

<cache name="dayHits" maxEntriesLocalHeap="500" eternal="true" overflowToDisk="true"> 
</cache>

表示保存当日点击量的

在controller层定义缓存点击量的方法

 public Integer cacheCount(Long articleId){
    Content content = contentRepository.findOne(articleId);
    Ehcache cache = cacheManager.getEhcache("dayHits");
    Element element = cache.get(articleId+"_count");
    Integer count = 0;
    if(element!=null){
      count = (Integer) element.getValue();
    }else{
      count = content.getHits()== null?0:content.getHits();
    }
    count++;
    cache.put(new Element(articleId+"_count",count));
    cache.put(new Element(articleId+"_dayHitsDate",SystemUtils.getNowDate()));
    Long time = System.currentTimeMillis();
    if(time > (viewArticleTime+ 300000)){
      viewArticleTime = time;
      content.setHits(count);
      contentRepository.save(content);
      cache.removeAll();
    }
    return count;
  }

3.在查看文章方法中进行调用。

 @RequestMapping(value = "article/{id}",method = RequestMethod. GET)
  public String detail(@PathVariable Long id,ModelMap map){
  Integer hits = cacheCount(id);
  }

4.其中局部变量的定义:

 private static CacheManager cacheManager = CacheManager.newInstance();
  private static Long viewArticleTime = System.currentTimeMillis();

5.保存访问看看效果吧。


  • 2018-02-04 23:46:16

    Android SQLite 升级数据库,在原有数据库的基础上添加一列

    原本以为很简单的问题,直接在原来创建数据库的语句中加上需要添加的列new_column,但是运行时发现,应用crash。原因是,原有数据库文件已经存在的情况下并不会重新创建数据库,也就是说此时数据库中并没有new_column列,这个时候,运行query()来查询数据库如果包括new_column列,就会导致应用crash。

  • 2018-02-06 22:23:01

    HTML5 Canvas 的事件处理

    DOM是Web前端领域非常重要的组成部分,不仅在处理HTML元素时会用到DOM,图形编程也同样会用到。比如SVG绘图,各种图形都是以DOM节点的形式插入到页面中,这就意味着可以使用DOM方法对图形进行操作。比如有一个<path id=”p1″>元素,可以直接用jquery增加click事件$(‘#p1’).click(function(){…})”。然而这种DOM处理方法在HTML5的Canvas里不再适用,Canvas使用的是另外一套机制,无论在Canvas上绘制多少图形,Canvas都是一个整体,图形本身实际都是Canvas的一部分,不可单独获取,所以也就无法直接给某个图形增加JavaScript事件。

  • 2018-02-09 01:32:48

    PHP时间戳和日期相互转换

    在php中我们要把时间戳转换日期可以直接使用date函数来实现,如果要把日期转换成时间戳可以使用strtotime()函数实现,下面我来给大家举例说明。

  • 2018-02-09 02:57:46

    如何防止多次打开Activity?

    android:launchMode="singleTask" 加上这句,每次打开如果已有此activity,就会打开原来的实例,否则会创建新的activity​

  • 2018-02-17 18:51:26

    Context都没弄明白,还怎么做Android开发?

    作为Android开发者,不知道你有没有思考过这个问题,Activity可以new吗?Android的应用程序开发采用JAVA语言,Activity本质上也是一个对象,那上面的写法有什么问题呢?估计很多人说不清道不明。