云原生时代下Java的发展
分享一个之前做的slides :)
Redis实现计数统计
场景分析在社区项目中,我们有很多计数相关的需求,比如
文章相关的:
点赞数
阅读数
收藏数
评论数
用户相关的:
用户发表的文章数
用户文章的阅读总数
用户文章被收藏数
用户文章被点赞数
用户粉丝数
用户关注数
首先看一下我们的场景:
文章阅读数是个单独的表,每次从数据库查询文章详情的时候,DB中阅读量就会+1,然后返回。
除此之外,其他计数并不会直接存储在DB中,比如对于点赞数,我们在DB中存储的是什么呢?是点赞这个记录,而点赞数通过查询DB计算出来的,我们通过在SQL中使用sum函数计算出来。
我们再来看,在业务中,什么场景是高频的,什么场景是低频的。
查询操作是高频的:对上述计数的查询是高频的,每次刷新页面,打开任何一个页面都需要查询。
更新操作是低频的:很多人只是浏览查看,参与社区活动(点赞,评论,收藏)还是比较少的。
那么针对这种场景,我们的做法是这样的,
对这些计数的查询是比较高频的业务,如果每次都要查询数据库(使用SQL语句计算出来),是比较耗时的,因为可以基于Redis的incr指令实现一个计数器。
更新计数的话,我们的方案会把记录写DB。因为更新计 ...
实现用户活跃度排行榜
需求分析用户活跃度榜单是一个能够鼓励用户参与社区活动的有效手段。
用户活跃度计算方式:
用户每访问一个新的页面+1分
对于一篇文章,点赞、收藏+2分;取消点赞、取消收藏,将之前的活跃分收回
文章评论+3分,删除评论,将之前的活跃分收回
关注用户 +2分,取消关注,将之前的活跃分收回
发布—篇审核通过的文章+10分,删除文章,将之前的活跃分收回
榜单(分为月榜和日榜):
展示活跃度最高的前三十名用户
方案设计首先是存储单元,针对一个排行榜,思考排行榜上面每一位需要存储哪些信息:
123456//用来表明具体的用户long userId;//用户在排行榜上的排名long rank;//用户的积分long score;
我们可以使用Redis中的 zset 数据结构来实现,zset维护了一个带权重的有序集合:
set:集合确保里面的每个元素只出现一次
权重:就是我们的score
zset:根据score进行排序的集合
从zset的特性来看,我们每个用户的积分,丢到zset中,就是一个带权重的元素,而且是已经排好序的了,只需要获取元素对应的index,就是我们预期的排名,非常方便 ...
Redis benchmark使用教程
Redis 包括 redis-benchmark 实用程序,它模拟同时发送 M 个总查询的 N 个客户端执行的命令。redis-benchmark提供默认的一组测试,或者我们可以提供自定义的一组测试。
语法redis 性能测试的基本命令如下:
1redis-benchmark [option] [option value]
注意:该命令是在 redis 的目录下执行的,而不是 redis 客户端的内部指令。
可选参数如下所示:
序号
选项
描述
默认值
1
-h
指定服务器主机名
127.0.0.1
2
-p
指定服务器端口
6379
3
-s
指定服务器 socket
4
-c
指定并发连接数
50
5
-n
指定请求数
10000
6
-d
以字节的形式指定 SET/GET 值的数据大小
3
7
-k
1=keep alive 0=reconnect
1
8
-r
SET/GET/INCR 使用随机 key, SADD 使用随机值
9
-P
通过管道传输 <numreq> ...
如何实现API接口的幂等性
幂等性什么是幂等性在实际的开发项目中,一个对外暴露的接口往往会面临很多次请求。这就需要考虑到一个幂等性问题。
幂等的数学概念幂等是源于一种数学概念。其主要有两个定义
如果在一元运算中,x 为某集合中的任意数,如果满足 f(x) = f(f(x)) ,那么该 f 运算具有幂等性,比如绝对值运算 abs(a) = abs(abs(a)) 就是幂等性函数。
如果在二元运算中,x 为某集合中的任意数,如果满足 f(x,x) = x,前提是 f 运算的两个参数均为 x,那么我们称 f 运算也有幂等性,比如求大值函数 max(x,x) = x 就是幂等性函数。
幂等性在开发中的概念在数学中幂等的概念或许比较抽象,但是在开发中幂等性是极为重要的。简单来说,对于同一个系统,在同样条件下,一次请求和重复多次请求对资源的影响是一致的,就称该操作为幂等的。比如说如果有一个接口是幂等的,当传入相同条件时,其效果必须是相同的。
特别是对于现在分布式系统下的 RPC 或者 Restful 接口互相调用的情况下,很容易出现由于网络错误等等各种原因导致调用的时候出现异常而需要重 ...
SpringBoot 全局异常处理的几种常见姿势
异常处理方式的发展web.xml在还没有Spring的时候,开发使用的是原生的Servlet + tomcat容器。那个时候就提供了通用的异常的处理配置方式的:在web.xml里进行如下配置:
1234567891011<!-- 根据状态码 --><error-page> <error-code>500</error-code> <location>/500.jsp</location></error-page><!-- 根据异常类型 --><error-page> <exception-type>java.lang.RuntimeException</exception-type> <location>/500.jsp</location></error-page>
SpringMVCSpring MVC提供处理异常的方式主要分为两种:
实现HandlerExceptionResolver方式
@Exc ...
结合AOP和SpEL表达式实现日志切面
需求结合AOP技术和SpEL表达式实现一个简单的AOP切面
计算耗时,并打印日志
用户可以在注解中添加指定的字段名称,切面自动解析出值,放在日志里一起打印。
示例:在添加注解的时候,指定bizCode = "#msg",那么在方法被调用的时候,就会计算变量articleId在当前上下文中的值,并在日志中打印出来。
123456@MdcDot(bizCode = "#articleId")@RequestMapping("/hello")public String sayHello(String articleId) { System.out.println("Hello, World :" + articleId); return "success";}
测试效果如下:
实现定义注解MdcDot123456789101112import java.lang.annotation.Documented;import java.lang.annotat ...
Spring AOP在什么场景下会失效?
刚刚遇到了Spring AOP失效的问题,趁这个机会总结一下~
什么是Spring AOPSpring AOP是Spring框架中的一个重要组成部分,它提供了一种面向切面编程(Aspect-Oriented Programming, AOP)的实现方式。AOP的核心思想是将那些分布在多个对象或方法中的共同行为(即横切关注点)提取出来,形成一个独立的模块,称为“切面”(Aspect)。这样做的好处是可以增强的代码模块化,减少重复代码,提高系统的可维护性和可扩展性。
AOP基于什么实现Spring AOP 的实现主要基于动态代理和字节码增强两种技术。
首先,Spring AOP利用动态代理技术在运行时生成代理对象,这些代理对象能够拦截对目标对象的调用,并在调用前后执行切面逻辑。具体来说,如果目标对象实现了接口,Spring AOP会使用JDK动态代理来生成代理对象;而如果目标对象没有实现接口,Spring AOP则会使用CGLIB动态代理来生成代理对象。
其次,Spring AOP还利用了AspectJ框架来实现字节码增强。这是一种在编译时或运行时修改目标对象的字节码的技术,以此来插入 ...
如何搭建一个社区系统 —— 4. Filter之全局上下文与全链路traceId
在项目中,我们使用拦截器filter拦截所有的web请求,主要做以下两件事情:
实现用户身份识别,并将识别出来的用户信息,保存到ThreadLocal对应的上下文中,这样在后续的请求链路中,在任何地方都可以直接获取当前的登录用户,从而减少查询数据库的次数。
打印请求日志,记录请求耗时,通过MDC添加全链路的traceId,方便追踪定位。
Filter基础知识Filter称为过滤器,主要用来拦截http请求,在请求之前或者之后做一些事情。
Filter和Interceptor的区别:
具体的流程如下所示:
filter的应用场景主要包括:
在filter层,来获取用户的身份
可以考虑在filter层做一些常规的校验(如参数校验,referer校验、权限控制等)
可以在filter层做运维、安全防护相关的工作(如全链路打点,可以在filter层分配一个traceld;也可以在这一层做限流等)
具体做法
在过滤器的doFilter方法中,分为三部分:
doBefore:表示将请求转发到Controller执行之前
记录开始执行时间
记录请求相关信息(ThreadLocal变 ...
如何搭建一个社区系统 —— 3. 如何进行登录认证
登录认证永远是社区网站最核心的功能之一。本文从无状态的HTTP协议讲起,详细梳理了Cookie、Session、Token、JWT等相关技术,并给出本项目的做法。
无状态的HTTP协议HTTP 无状态协议,是指协议对于业务处理没有记忆能力,每次请求都是完全独立互不影响的,没有任何上下文信息。假如一直用这种原生无状态的 HTTP 协议,我们每换一个页面可能就得重新登录一次,这肯定是不行的。那么如何做呢?
在客户端第一次请求之后,服务端生成并向客户端分配唯一标识,然后后续客户端请求服务端的时候,只需要携带者唯一标识就可以了,如下图所示:
Cookie方案Cookie的概念HTTP Cookie(也叫 Web Cookie 或浏览器 Cookie)是服务器发送到用户浏览器并保存在本地的一小块数据。它会在浏览器下次向同一服务器再发起请求时,被携带并发送到服务器上。通常 Cookie 用于告知服务端两个请求是否来自同一浏览器,如保持用户的登录状态。Cookie 使基于无状态的 HTTP 协议记录稳定的状态信息成为了可能。
Cookie 主要用于以下三个方面:
会话状态管理(如用户登录状态 ...