springboot+redis实现文章浏览量记录

​ 之前,个人博客网站里的文章访问量都是存在MySQL中的。每次访问都需要通过文章id查数据库,获得浏览量后+1操作。之后在更新数据库,为了实时显示文章浏览量还要在读一遍数据库。访问量多了之后就带来了线程安全问题:两个线程同时获得数量,各自+1后更新,这个访问量就有问题了。对于这个情况,之前直接用synchronized粗暴的对操作加锁。这带来一个问题,多个线程只能有一个线程来获取文章信息,其他线程阻塞,。后来又想到另一个解决方案,浏览量的增加独立出来,不和读取文章信息绑定。每读取一个文章信息后返回调用一个接口来增加数量。这有一个缺陷就是显示的文章访问量不是实时的。

​ 最后决定使用redis来存储文章的访问量,redis的关键语句是incr key。作用是key的value+1;key和文章id绑定。由于redis是单线程的,单个语句的执行是线程安全的。

​ 理想很丰满,但操作的时候还是遇到了不少问题。

     <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency>

设置redis配置

redis:database: 0# Redis服务器地址 写你的iphost: XXX.XX.XX.XXX# Redis服务器连接端口port: 你的端口号# Redis服务器连接密码(默认为空)password: 你的密码timeout: 6000lettcue:pool:# 连接池中的最大空闲连接,默认值也是8。max-idle: 100# 连接池中的最小空闲连接,默认值也是0。min-idle: 10# 如果赋值为-1,则表示不限制;如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted(耗尽)max-active: 8# 等待可用连接的最大时间,单位毫秒,默认值为-1,表示永不超时。如果超过等待时间,则直接抛出JedisConnectionExceptionmax-wait: 2000

如果不设置redis的连接池属性的话默认只有一个连接,多线程来使用redisTemplate会报”redis连接异常“。

设置redisTemplate类模板


@Beanpublic RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory connectionFactory) {// 配置redisTemplateRedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();redisTemplate.setConnectionFactory(connectionFactory);redisTemplate.setKeySerializer(new StringRedisSerializer());//key序列化redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<Object>(Object.class));//value序列化return redisTemplate;}

JUnit测试类:

     @ResourceRedisUtils redisUtils;@Testpublic void redisTest(){try {Runnable runnable = new Runnable(){@SneakyThrows@Overridepublic void run() {for(int i=0;i<500;i++){Thread.sleep(1);System.out.println(Thread.currentThread().getName()+": "+addReadNums());}}};ExecutorService executorService = Executors.newFixedThreadPool(5);executorService.execute(runnable);//线程1executorService.execute(runnable);//线程2System.out.println("@Test线程执行完毕");} catch (Exception e) {System.out.println(e);}}public Long addReadNums(){return redisUtils.incrBy("test", 1);}

进行多线程模拟测试的时候就报错了,lettuce线程池在多线程下有问题,查找资料后都说用Jedis作为redis的线程池。

修改后

修改后的依赖:在spring-boot-starter-data-redis去除lettuce线程池,导入jedis

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId><exclusions><exclusion><groupId>io.lettuce</groupId><artifactId>lettuce-core</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId></dependency><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>3.3.0</version></dependency>

这里要注意Jedis的版本和spring-boot-starter-data-redis版本,版本不一致会导致redisTemplate创建失败。

参考:【异常】nested exception is java.lang.NoClassDefFoundError: redis/clients/jedis/util/SafeEncoder

还要修改redisTemplate类创建方式

@Bean
public RedisTemplate<String, Object> redisTemplate(JedisConnectionFactory connectionFactory) {// 配置redisTemplateRedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();redisTemplate.setConnectionFactory(connectionFactory);redisTemplate.setKeySerializer(new StringRedisSerializer());//key序列化redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<Object>(Object.class));//value序列化return redisTemplate;
}

这时候测试发现,线程运行一会就打印:Shutting down ExecutorService ‘applicationTaskExecutor‘ 。之后线程就停止了。发现是JUnit单元测试的坑:它会在主线程结束后调用相关的System.exit()方法,将JVM关闭,所以,子线程被动挂了。

参考:JUnit单元测试中多线程的坑

修改后的测试类:

@Test
public void redisTest(){try {Runnable runnable = new Runnable(){@SneakyThrows@Overridepublic void run() {for(int i=0;i<500;i++){Thread.sleep(1);System.out.println(Thread.currentThread().getName()+": "+addReadNums());}}};ExecutorService executorService = Executors.newFixedThreadPool(5);executorService.execute(runnable);//线程1executorService.execute(runnable);//线程2try {TimeUnit.SECONDS.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("@Test线程执行完毕");} catch (Exception e) {System.out.println(e);}
}
public Long addReadNums(){return redisUtils.incrBy("test", 1);
}

发现两个线程下新增500还是没有问题的。

看一下redis确实是1000。

最后对于文章浏览量,只要key传入的是文章的id即可。如果担心key与其他的内容重复,添加标识符区别即可。

springboot+redis实现文章浏览量记录相关推荐

  1. springboot整合redis实现HyperLogLog统计文章浏览量使用过期策略完成数据库同步

    springboot整合redis实现HyperLogLog统计文章浏览量&&使用过期策略完成数据库同步 本文目录 springboot整合redis实现HyperLogLog统计文章 ...

  2. php 文章浏览量 缓存,WordPress缓存文章浏览量访问不自动增加怎么办?WordPress缓存导致文章阅读数点赞数不更新...

    Wordpress 静态缓存目前对于何先生来说作用不是很大,比较适合一些流量比较大的博客或者网站. 之前接触过 Wordpress 静态缓存,遇到过这个问题后面没有去深究. WordPress缓存文章 ...

  3. Robotframework-ride 实例 - 提高文章浏览量 例某个Web

    我爱自动化胜过爱维C 环境搭建 脚本思路: 开启浏览器: 输入CSDN地址: 输入搜索想要刷浏览量的文章名: 点击搜索: 切换窗口,点击文章链接,打开文章阅读页: (共显示三个浏览器标签页): 关闭浏 ...

  4. wordpress列表页调用浏览器,wordpress显示文章浏览量!

    1.把下面这段代码加在想显示文章浏览次数的位置(例如模板内的content.php) <?php setPostViews(get_the_ID()); echo getPostViews(ge ...

  5. 【SpringBoot】SpringBoot + Redis集群配置(项目记录)

    开发过程中首次使用了redis,也是一点一点边学边开发,期间遇到了一些坑所以做下记录防止以后忘记. 首先代码里只用到了单机版的redis,但因为后续数据量的问题改成了集群版,这里记录集群版的基本配置, ...

  6. php原生 文章浏览量,调用WordPress函数统计文章访问量及PHP原生计数器的实现

    1.首先介绍WordPress的两款功能强大的插件: (1)Count per Day 是一个非常强大的访客数量统计插件,可以统计每天.昨天.每周.每月等等的访客数量(根据IP进行统计),统计在线访客 ...

  7. 刷新页面,js实现文章浏览量自动更新

    浏览次数:<script src="{:U('Show/news_read_count',array('id'=>$Rs['id']))}" type="te ...

  8. php redis访问量,redis实现点击量浏览量

    业务描述 CMS文章浏览量(标题被加载量),点击量统计(文章被点击开的量) 以下是本人设计的统计业务,主要技术redis,nodejs,redis应用点击量缓存以减少数据库压力,nodejs通过异步非 ...

  9. html怎么设置虚拟浏览量,WordPress修改增加文章浏览点击量(阅读量)

    新发布的WordPress文章点击浏览数量肯定是0,于是很多访问量网站觉得很不好意思. 比如我这3篇新发布的文章的浏览量都是0. 我个人觉得没什么. 需要的是坚持,每天坚持发布原创的优质文章,排名会好 ...

  10. mysql文章浏览计数_高并发文章浏览量计数系统设计

    最近因为个人网站的文章浏览量计数在Chrome浏览器下有BUG,所以打算重新实现这个功能. 原本的实现很简单,每次点击文章详情页的时候,前端会发送一个GET请求articles/id获取一篇文章详情. ...

最新文章

  1. labview初始学习过程中遇到串口读取框红蓝色交替闪烁的处理
  2. orcle与mysql的区别_Orcle与MySQL的SQL语法区别:
  3. 多级联动下拉菜单插件:jquery.cxselect.js
  4. C++ Primer 5th笔记(chap 19 特殊工具与技术)局部类
  5. Tools: geos 使用指南
  6. php mysql管理_MySQL 连接与管理
  7. P3292 [SCOI2016]幸运数字(树剖 + 线段树维护线性基)
  8. Python稳基修炼的经典案例7(计算机二级、初学者必须掌握的例题)
  9. 倍增法求LCA(最近公共最先)
  10. 深入理解Java三种IO模式和Epoll模型
  11. 一键重装深度linux系统下载,Deepin 20 Beta X64官方正式版(64位)
  12. 微pe工具箱是微软的吗_电脑装系统用一键装机好用还是微PE工具箱好用
  13. 三四线城市咖啡店的光荣与梦想
  14. SharePoint - CAML
  15. 汇编语言-实验6(学习打卡Day18)
  16. 2021中国开源年报发布!一篇报告带你读懂中国开源的2021~
  17. Win7环境安装Anaconda
  18. R语言---安装依赖包
  19. Day04 利用flex布局完成PC端网页设计CSS+html部分
  20. IL遇到的思路及问题

热门文章

  1. 【CRC】CRC推导(二)模二除法
  2. 什么是通配符SSL证书?
  3. 2020年全球区块链专利排行榜TOP100,中国52家公司上榜
  4. ILSVRC2015_VID数据集说明
  5. sim868 建立tcp链接时的步骤所对应hex码
  6. 如何将pdf文件压缩变小?
  7. 怎么用PS为一寸证件照更换底色背景色
  8. modelica语言学习记录V1.0
  9. Oracle数据库基础练习(一):Oracle数据库查询操作练习81题
  10. 结构体中的LNode与*LinkList