0%

spring-web

MVC

SpringWeb项目结构推荐

  • model:模型
    • po(entity):数据库表结构类
    • dao(mapper or orm):数据库单表访问类
    • dal(use multiple dao):数据库多表访问层
    • bo(business):业务数据类
    • co(common):通用数据类
    • vo(view):视图数据类(后端生成网页时使用)
    • dto(transfer):传输数据类(前后端交互时使用,分为请求和响应)
  • view:视图
  • controller:控制器
  • service:业务逻辑实例类
  • manager:通用逻辑实例类
  • helper:业务逻辑静态类
  • utils:通用逻辑静态类

请求处理模型

JavaWeb三大组件

  • Servlet
  • Filter
  • Listener

Servlet

Filter

Listener

请求流程描述

  • web容器接收到请求后解析成Request对象
  • web容器将所有请求交给DispatcherServlet处理
  • DispatcherServlet通过HandlerMapping获取Handler
  • 通过相应的适配类HandlerAdapter调用Handler的处理方法处理请求并返回ModelAndView
  • 根据返回的ModelAndView选择一个适合的ViewResolver
  • ViewResolver结合Model和View渲染视图
  • 将结果放到Response对象中返回给web容器

请求过滤拦截

主要区别如下

  • 使用范围不同:Filter是Servlet规范,只能用于web应用,Interceptor是Spring的规范,还可以用于非web应用
  • 拦截时机不同:Filter在进入Servlet之前,Interceptor在进入Servlet之后且进入Controller之前

执行顺序如下

  • Filter(过滤器)
  • Servlet(DispatcherServlet)
  • Interceptor(拦截器)
  • Advice(通知)
  • Aop(切面)
  • Controller(控制器)

使用场景如下

  • 认证鉴权
  • 日志记录
  • 耗时统计

Filter(过滤器)

  • init:容器启动的时候执行一次
  • doFilter:每次请求和响应时都会执行
  • destroy:容器停止的时候执行一次

ps:Filter可以访问request和response,不能访问controller
ps:FilterChain.doFilter之前的代码在请求的时候执行
ps:FilterChain.doFilter之后的代码在响应的时候执行

Interceptor(拦截器)

  • preHandle:Controller调用之前执行
  • postHandle:Controller调用之后且视图渲染之前执行
  • afterCompletion:视图渲染之后执行

ps:Interceptor可以访问request和response,还可以访问controller和modelAndView

Advice(通知)

ps:切面可以通过RequestContextHolder访问request和response

AOP(切面)

ps:AOP可以通过RequestContextHolder访问request和response,还可以通过JoinPoint访问方法参数

Controller

Controller包含多个Handler,Controller里的每个方法都是一个Handler

Request

RequestEntity包含

  • 请求头(@RequestHeader)
  • 请求体(@RequestBody)

Route

Param

  • 参数名称
  • 参数个数
    • 单个参数
    • 多个参数
  • 参数类型
    • 基本类型
    • 对象类型
    • 容器类型
      • Map
      • Array/List/Set

Pass

  • Method
    • GET
    • POST
  • MIME
    • x-www-form-urlencoded(Post form type)
    • multipart/form-data(Post form type)
    • application/json(Post json type)
  • Type
    • 基本类型
    • 对象类型
    • 容器类型
      • Map
      • Array/List/Set
Method
MIME
Type

Fetch

Attribute和Parameter的来源

  • Request
  • Session
  • Model

Attribute和Parameter的获取

  • HttpServletRequest:可以获取Parameter和Attribute
  • HttpSession:可以获取Attribute
  • Model:可以获取Attribute

Attribute和Parameter的区别

  • Attribute:由后端生成,可以存在Request、Session和Model中
  • Parameter:由前端生成,只存在Request中,可以自行添加到Session和Model中

Attribute和Parameter的范围

  • Request:Request范围
  • Session:Session范围
  • Model:Request范围

ps:Request范围的数据只能被该请求单独访问,Session范围的数据可以多个请求共享访问
ps:Model的Attribute是Request范围的,如果要在Session范围内使用Model的Attribute,可以使用@SessionAttributes注解将Model的Attribute转到Session的Attribute中

Attribute和Parameter的传递

  • Attribute:转发后的页面可以访问Request和Session范围的,重定向后的页面可以访问Session范围的
  • Parameter:转发后的页面不可以访问,GET重定向的页面可以访问(因为浏览器会携带参数重新请求)
Parameter
Attribute

Attribute相关注解的作用

  • @RequestAttribute:从HttpRequest中获取Attribute
  • @SessionAttribute:从HttpSession中获取Attribute
  • @ModelAttribute:从Model中获取Attribute或者将方法的返回值存入Model中
  • @SessionAttributes:将Model里面的Attribute存到Session域中(Model的有效范围默认是Request域的)

ps:@SessionAttributes和@SessionAttribute之间差一个 s ,但作用不同

Model

Model的作用是将数据传递给视图进行渲染,比Request和Session更符合MVC规范

ps:视图获取参数时建议使用哪个Model,也可以使用Request和Session,因为在使用Model时可以更加优雅的通过 ${param} 的方式取值

Session

Response

ResponseEntity包含

  • 响应头(ResponseHeader)
  • 响应体(@ResponseBody)
  • 响应状态(@ResponseStatus)

ps:ResponseEntity的优先级比@ResponseBody高

Result

Status

Header

View

Exception

  • 参数校验异常
  • 数据访问异常(mysql、redis)
  • 业务处理异常

Context

Invalid

Validation

Annotation

@Validated和@Valid的区别

  • @Validated是spring的注解,@Valid是java的注解
  • @Validated不支持标注字段,@Valid支持标注字段
  • @Validated不支持嵌套校验,@Valid支持嵌套校验
  • @Validated支持分组校验,@Valid不支持分组校验

Exception

MethodArgumentNotValidException和ConstraintViolationException的区别

  • BindException:表单请求数据绑定到参数出错时抛出的异常
  • MethodArgumentNotValidException:使用@Valid和@Validated注解标注的方法参数校验失败时抛出的异常
  • ConstraintViolationException:使用@NotNull等注解直接标注的方法参数校验失败时抛出的异常

Assertion

Converter

Date

Enum

Json

CORS

CORS:CrossSite(跨域)

  • 全局
    • WebMvcConfigurer
    • CorsFilter
    • 自定义Filter添加响应头(Access-Control-Allow-Origin)
  • 局部
    • @CrossOrigin
    • 手动在响应里面添加响应头(Access-Control-Allow-Origin)

Auth

登录跳转实现方案

  • 后端实现
    • 跳首页:返回302(浏览器负责实现跳转)
    • 跳当前页:返回302 + 前端将当前页地址存到sessionStorage中、返回302 + 前端请求时每次将当前页地址放到自定义header或者参数中传给后端(不推荐这个方案)
  • 前端实现
    • 跳首页:返回401(前端负责实现跳转)
    • 跳当前页:返回401 + 前端将当前页地址存到sessionStorage中

Service

  • Service:业务逻辑实例类
  • Manager:通用逻辑实例类
  • Helper:业务逻辑静态类
  • Utils:通用逻辑静态类

Model

POJO

*+ po(entity):数据库表结构类

  • dao(mapper or orm):数据库单表访问类
  • dal(use multiple dao):数据库多表访问层
  • bo(business):业务数据类
  • co(common):通用数据类
  • do(domain):领域数据类
  • vo(view):视图数据类(后端生成网页时使用)
  • dto(transfer):传输数据类(前后端交互时使用,分为请求和响应)

Transform

View

Jsp

Thymeleaf

spel:Spring Expression Language

Freemarker

Web

Protocol

Http

RPC

RPC是远端过程调用,调用协议通常包含

  • 序列化协议
    • Xml
    • Json
    • Bin
      • Hessian(比较早期的框架)
      • MessagePack(Json格式的优化版)
      • Protobuf(Google出品的框架)
      • Thrift(FaceBook出品的框架)
      • Avro(Hadoop的一个子项目)
      • Kyro(针对java的二进制协议)
      • Fct(针对java的二进制协议)
  • 传输协议
    • TCP
    • HTTP

ps:RPC的传输协议可以使用TCP来实现,也可以使用Http来实现

RPC框架

  • Dubbo(Ali)
  • Finagle(Twitter)
  • Thrift(Facebook)
  • grpc(Google)
  • brpc(Baidu)

WebSocket

WebSocket和Http对比

  • 都是应用层协议
  • WebSocket支持双向通信,Http只支持单向通信

WebSocket和Socket对比

  • WebSocket是应用层协议,Socket是传输层协议的封装
  • Socket比较原始,WebSocket则是在应用层面对于Socket的进一步封装

Specification

Restful(Web API)

SOAP(Web Service)

Reliability

Exception

Retry

Idempotent

幂等和去重的区别

  • 幂等:是一种概念,操作执行多次的结构都是一样的
  • 去重:是一种方案,操作只会执行一次

ps:去重是实现幂等的一种方案(如果操作本身就是支持幂等的就不需要去重)

如何实现幂等

  • 请求
    • token令牌
  • 数据
    • 插入操作
      • 去重表(mysql)
        • 直接插入 + 唯一约束:适合有唯一约束的
          • 使用insert into检测到插入失败(DuplicateKeyException)后换一个主键重试
          • 使用insert ignore into检测到插入失败后换一个主键重试
        • 检测插入 + 加锁控制:适合没有唯一约束的
          • 使用select for update检测到重复后换一个主键重试
      • 去重表(redis)
        • setnx
    • 更新操作
      • 状态机 + CAS思想
      • 版本号 + CAS思想
        • 计数
        • 时间戳

ps:去重时还可以使用布隆过滤器来优化去重的效率
ps:数据库的插入和更新都会主动加锁,所以不需要额外加锁

幂等和去重都需要唯一标识

唯一标识来源

  • 业务id(身份证号、手机号、设备指纹)
  • 逻辑id(发号器生成)
    • 顺序id
    • 随机id

唯一标识实现

  • 单机
    • 顺序id
      • mysql自增id
      • 时间戳
    • 随机id
      • UUID
  • 分布式
    • 顺序id
      • mysql发号器
      • redis发号器
    • 随机id
      • UUID
      • SnowflakeId
      • MongodbId

Repeat

如何防止重复提交

  • 前端
    • 进入页面时向后端请求一个去重token放入隐藏域中
    • 点击提交按钮后立即禁用提交按钮
    • 点击提交按钮后显示加载中或者跳转到其他页面
  • 后端
    • 取出前端提交的去重token
    • 如果token存在,则执行正常逻辑,并销毁去重token
    • 如果token不存在,则执行去重逻辑,即丢弃重复的请求

防抖和节流的区别

  • 防抖:debounce,延时后只执行一次,用于防止操作过快(操作的时间间隔短)
  • 截流:throttle,周期内只执行一次,用于防止操作过多(操作的触发频率高)

ps:防抖中再次触发时,会重置延时计时器和取消上一次的延时操作
ps:截流是限流的一种方式

Performance

  • 缓存加速
    • 本地缓存
    • 集中缓存
  • 异步处理
    • 子线程(多线程)
    • 消息队列
  • 并行处理
    • 分解任务并进行并行处理
  • 批量处理
    • 聚合任务并进行批量处理
  • 池化技术

异步处理时获取任务结果

  • 轮询
  • 回调(回调机制,耦合)
  • 监听(发布和订阅,不耦合)

系统三高

  • 高性能:每次请求的处理时间越短越好
  • 高并发:同时支持的请求数量越多越好
  • 高可用:集群或分布式系统中部分服务节点故障也不影响整体服务(备份机制)

性能模型

  • CPU密集型:需要CPU进行大量的处理,例如数学计算、加密解密、编码解码、压缩解压、正则表达式搜索
  • IO密集型:大部分的时间CPU都在等IO(内存、磁盘、网络),例如WEB服务、爬虫

性能指标

服务性能指标

关键概念

  • RT:响应时间(Response Time),实际包含请求时间(Request Time)、处理时间(Handle Time)、响应时间(Response Time)
  • ART:平均响应时间(Average Response Time),描述的是响应时间的平均值
  • HPS:每秒点击量(Hit Per Second),描述的客户端每秒点击量
  • RPS:每秒请求量(Request Per Second),描述的客户端每秒请求量
  • QPS:每秒查询量(Query Per Second),描述的是查询系统的每秒查询量
  • TPS:每秒事务量(Transaction Per Second),描述的是业务系统的每秒事务量
  • Concurrency:并发量,描述的后端能够同时处理的请求数量(不是单位时间能处理的数量)
  • Latency:延迟,用户等待请求或事务从开始到完成的时间(ART)
  • Throughput:吞吐量,系统单位时间内处理请求(QPS)和事务(TPS)的数量

ps:一个事务可能会包含多个请求或者请求链
ps: 前台交互型 应用追求的是 最低延迟 ,比如 Web服务 应用
ps: 后台计算型 应用追求的是 最大吞吐量 ,比如 大数据计算 应用

延迟和吞吐量之间的关系

  • 延迟和吞吐量之间没有必然的关系
  • 延迟变低(比如提高处理速度)可以提高吞吐量
  • 但是延迟变高(比如进行批量处理)也可以提高吞吐量

核心指标

  • 平均响应时间(ART)
  • 并发量(Concurrency)
  • QPS

QPS = Concurrency / ART(单位通常是毫秒,计算时需要换算成秒)

ps:QPS不是ART的倒数这种估算值,需要进行实测,因为处理请求时不止一个线程或进程
ps:而且ART不是一个固定的值,会受服务器资源(cpu、mem、disk、net)的状态影响
ps:因为ART不可调,所以可以不断增大Concurrency直到QPS开始下降来测出QPS的最大值

网络性能指标

  • RTT:往返时间(Round-Trip Time),表示从发送端发送数据开始,到发送端收到来自接收端的确认(接收端收到数据后便立即发送确认,不包含数据传输时间)
  • Latency:时延,是一个描述网络延迟时间的概念,包含RTT这个核心指标

业务评价指标

  • PV:单个页面访问量(Page View)
  • UV:独立用户访问量(Unique Visitor)
  • DAU:日活(Daily Active User)
  • MAU:月活(Month Active User)
  • GMV:总商品价值量(Gross Merchandise Volume)

Container

  • Tomcat
  • Netty(WebFlux)
  • Jetty
  • Undertow

Tomcat

Client

客户端的分类

  • 客户端的调用方式可以分为 编程式调用声明式调用
  • 客户端的请求方式可以分为 同步请求异步请求
  • 客户端的请求协议可以分为 Http请求RPC请求

客户端的实现

  • HttpClient:Apache组织出品的较早的Http请求库,支持编程式调用
  • OkHttp:Square公司出品的较新的Http请求库,支持编程式调用
  • Retrofit:Square公司出品的较新的Http请求库,基于OkHttp和RxJava,支持声明式调用
  • Forest:开源的轻量级Http请求库,基于OkHttp和RxJava,支持声明式调用
  • RestTemplate:Spring中使用,可以适配多种Http请求库,支持编程式调用
  • RestClient:Spring中使用,新一代的同步Http请求库,支持编程式调用
  • WebClient:Spring中使用,新一代的异步Http请求库,支持编程式调用
  • Feign:SpringCloud中使用,支持负载均衡的Http请求库,支持声明式调用
  • OpenFeign:SpringCloud中使用,支持负载均衡的Http请求库,支持声明式调用
  • Dubbo:SpringCloud中使用,支持负载均衡的RPC请求库,支持声明式调用

ps:OpenFeign是Spring对Feign支持SpringMVC的封装,可以使用SpringMVC的注解

Logging

Library

log4j2

logback

Optimize

Placeholder

Judgement

Question

Problem

Adapter

Specification

Category

Event

事件日志:程序的运行日志

  • 事件信息(what)
  • 事件时间(when)
  • 事件来源(who)
  • 事件位置(where):比如线程名、记录器名称、模块名、方法名、代码行
  • 事件标签(tag):比如事件属性、输入参数

Action

操作日志:用户的行为日志

  • 操作信息(what)
  • 操作时间(when)
  • 操作者(who)
  • 操作资源(resource):资源名称和资源id
  • 操作变化(change):资源变化前和变化后的状态

Trace

链路日志:服务的调用日志

Testing

Framework

Unit Test

  • Junit5使用了Extend机制(@ExtendWith),可以支持多个Extend
  • Junit4使用了Runner机制(@RunWith),只能支持一个Runner

Spring Test

SpringTest

SpringBootTest

Library

Mock Test

MockMvc

Mockito

Spock

Assert Test

Tools

Benchmark Test

Automation Test

Other

WebFlux

GraphQL

只想买包辣条