浏览量的简单设计
哈喽,又是一天早起的日子,今天就写写昨天实现了的浏览量逻辑设计,顺带一些其它的小知识总结,
设计思路
基本需求是当用户进入到某一篇博客的时候,该博客的浏览量+1,并且同一个用户同一天访问的博客不会再次增加1,即一天一个用户只会绑定一次某个博客。
基于这个需求,最开始设计的时候就简单的对getBlogById进行了一个扩展,就是在获取博客之前先对博客的visit进行自增,之后再返回博客给前端。此外还支持事务操作,遇到异常就进行回滚。然而事实是纯粹的这样操作,无法甄别是否是同一个用户拼命刷浏览量,无法表达出一篇文章的真实价值。
所以就想着也许可以通过用户的ip进行处理,虽然说同一个网络下的内网该ip都一样,不过基本可以满足需求。那么数据使用什么来存储呢?那当然是redis了,将所有用户维系到一个redis的一个set中即可。当然了,对于不同博客一个用户当然是可以分别增加浏览量的,所以不能只依据ip来进行反馈,所以我简单的设计了一个规则来区分:
ip#blog:id
首先第一段是ip地址,后面是#号用来分隔,接着跟上目标大类,以及具体的文章id。每次判断set中是否存在来决定是否为其自增,不过不管怎样都要返回博客列表就是了。对于该set集合,每天0点的时候也需要自动清空一下。
实现代码
首先是原始的博客获取service代码:
@Override
public RetResult<Blog> getBlogById(Integer id) {
return RetResult.success(blogDao.getBlogById(id));
}
接着我们对该方法重载扩充功能实现,先尝试从库中尝试查找到该串,如果没找到或者未定义set,那么就添加该串并且调用增加访客量的逻辑:
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
@Override
public RetResult<Blog> getBlogById(Integer id, String addr) {
String targetSer = addr + "#blog:" + id;
String vsStr = RedisConst.VISIT_SET;
SetOperations<String,String> ops = redisTemplate.opsForSet();
Boolean res = ops.isMember(vsStr, targetSer);
if (res == null || !res){
// 该用户今日未访问该博客, 新增访问量,并且将访问记录记入redis的visitSet中
ops.add(vsStr, targetSer);
blogDao.increaseVisit(id);
// 如果已经访问,不增加新的访问。
}
return getBlogById(id);
}
对于定时任务,只要简单的调用一下delete即可:
@Scheduled(cron = "0 0 0 * * ?")
public void visitSetClear(){
Boolean delete = redisTemplate.delete(RedisConst.VISIT_SET);
if (delete != null)
log.info("redis:{} clear - {}", RedisConst.VISIT_SET, delete?"clear":"non 2 clear");
}
数据安全
现在的redis服务数据就有了一定的重要性,那么肯定也想到对redis服务进行备份,可以采用主从服务器的策略来实现。
首先另外一台服务器做好如下的配置:
port 6379
protected-mode yes
daemonize yes
dir /home/dai/server/redis
dbfilename dump_6379.rdb
logfile /home/dai/server/redis/redis.log
pidfile /home/dai/server/redis/redis.pid
requirepass xxxxxx
replicaof <ip> <port>
masterauth xxxxxx
这样这台redis服务器就会自动获得主服务器的数据了。
其它发现
这段时间,也发现了一些其它结论:
- springboot对于response的编码通过配置实现,如果直接设置response.setContentType好像并不能生效
server.servlet.encoding.force=true
- springboot的配置可以在jar包外的路径下新建application.yml来进行更改配置,但是如果是这样更改ssl的路径似乎并不能生效
相关文章
- 15个问题自查你真的了解java编译优化吗?
- 实现服务器和客户端数据交互,Java Socket有妙招
- 世界杯专题看板丨今晚8点开战,数据先睹为快!
- Crack App | 某合伙人登录参数 apisign 逻辑分析
- Crack App | 某都市魔幻 FM 请求参数 sign 的加密分析
- Crack App | 某赢+ 二手车 App 登录参数加密逻辑分析
- RocketMQ: 技术架构与启动流程
- 目前社区关于ServiceMesh的主要方向
- k8s的架构是怎么变成现在这个样子
- Envoy的lib库拓扑关系
- 转发“Istio共享代理新模式Ambient Mesh”
- 如何设计属于你自己的秒杀系统?
- 如何把Java代码玩出花?JVM Sandbox入门教程与原理浅谈
- 删错了文件怎么办,文件快速恢复
- ChatGPT 浏览器插件实现思路解析
- 存储系统中的算法:LSM 树设计原理
- 说透游戏中常用的两种随机算法
- 我用消息队列做了一款联机小游戏
- 用算法打败算法
- CRUD 一年多,我的破局思路