1. 降级入门
/*降级入门*/
/*构建一个AtomicLong对象,提供了线程安全的自增,自减的操作*/
private AtomicLong atomicLong=new AtomicLong(1);
private int count;
@GetMapping("/sentinel04")
public String sentinel04() throws InterruptedException {
long num=atomicLong.getAndDecrement();
if(num%2==0){/*模拟慢调用*/
Thread.sleep(200);
}
return "sentinel 04 text";
}
2.热点参数限流规则
编辑Controller层
@GetMapping("/sentinel/findById")
@SentinelResource("resource")
public String doFindById(@RequestParam("id") Integer id){
return "resource id is "+id;
}
可以添加例外项
3.系统规则
4.授权规则(黑白名单)
4.1 通过参数限流
package com.jt.provider.controller;
import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.RequestOriginParser;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
/*构建DefaultRequestOriginParser对象,对请求数据进行解析
* 1)请求行
* 2)请求头
* 3)请求体
* */
@Component
public class DefaultRequestOriginParser implements RequestOriginParser {
@Override/*解析请求源*/
/*当设置了授权规则后,系统底层会拦截请求会调用此方法,对请求数据进行解析*/
public String parseOrigin(HttpServletRequest request) {
String origin=request.getParameter("origin");
return origin;
}
}
4.2 对ip地址授权访问
package com.jt.provider.controller;
import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.RequestOriginParser;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
/*构建DefaultRequestOriginParser对象,对请求数据进行解析
* 1)请求行
* 2)请求头
* 3)请求体
* */
@Component
public class DefaultRequestOriginParser implements RequestOriginParser {
@Override/*解析请求源*/
/*当设置了授权规则后,系统底层的拦截器会拦截请求会调用RequestOriginParser的parseOrigin方法,
对请求数据进行解析,与sentinel控制台的值进行比对(基于黑白名单)
不一定是参数 请求行、头、体...,根据返回的数据*/
public String parseOrigin(HttpServletRequest request) {
// String origin=request.getParameter("origin");
// return origin;
String ip=request.getRemoteAddr();
System.out.println("ip="+ip);
return ip;
}
}
5.模拟拦截器
创建拦截器
package com.jt.provider.controller;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.time.LocalTime;
import java.util.HashMap;
import java.util.Map;
@Component
/*springmvc中的拦截器,此对象可以在你执行controller的方法之前执行*/
public class TimeAccessInterceptor implements HandlerInterceptor {
/*此方法返回值为true表示放行,可执行后续业务,false表示到此结束*/
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
LocalTime now=LocalTime.now();//JDK8中的时间对象
int hour=now.getHour();//获取当前时间对应小时
if(hour<=18||hour>=22) {
//设置响应数据编码
response.setCharacterEncoding("utf-8");
//告诉客户端响应数据的类型,以及客户端显示内容的编码
response.setContentType("text/html;charset=utf-8");
//向客户端响应一个json格式的字符串
Map<String,Object> map=new HashMap<>();
map.put("status", 500);
map.put("message","请在18~22点进行访问");
String jsonStr=new ObjectMapper().writeValueAsString(map);
PrintWriter out = response.getWriter();
out.print(jsonStr);
out.flush();
out.close();
return false;
}
return true;
}
}
注册拦截器
package com.jt.provider.config;
import com.jt.provider.controller.TimeAccessInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class SpringWebConfig implements WebMvcConfigurer {
//配置spring mvc 拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new TimeAccessInterceptor())
.addPathPatterns("/provider/sentinel01");
}
}
实现效果
6.模拟框架执行链
package com.jt.common.interceptor;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* 如何理解框架?设计好的一个半成品?(类似简历模板)
* 框架设计时会有一些对象的定义以及这些对象的执行流程,类似一个执行链.
*/
interface Filter{
default void play(){}
}
//拦截器接口
interface HandlerInterceptor{
default void before(){}
default void after(){}
}
//处理器接口
interface Handler{
void processed();//处理业务的方法
}
//定义一个执行链
class ExecutionChain{//我是执行链的设计者
private Filter filter;
//一些拦截器
private List<HandlerInterceptor> interceptors=new CopyOnWriteArrayList<>();
//业务处理器
private Handler handler;
public ExecutionChain(Filter filter,List<HandlerInterceptor> interceptors,Handler handler){
this.filter=filter;
this.handler=handler;
this.interceptors.addAll(interceptors);
}
public void execute(){//负责执行业务的方法(例如处理请求)
//1.before
for(int i=0;i<interceptors.size();i++){
filter.play();
interceptors.get(i).before();
}
//2.processed
handler.processed();
//3.after
for(int i=interceptors.size()-1;i>=0;i--){
interceptors.get(i).after();
}
}
}
public class FrameworkTests {//框架应用者
public static void main(String[] args) {
List<HandlerInterceptor> interceptors=new CopyOnWriteArrayList<>();
interceptors.add(new HandlerInterceptor() {
@Override
public void before() {
System.out.println("考试开始了");
}
@Override
public void after() {
System.out.println("考试结束了");
}
});
//创建执行链对象
ExecutionChain chain=
new ExecutionChain(new Filter() {
@Override
public void play() {
System.out.println("过滤了");
}
},interceptors, new Handler() {
@Override
public void processed() {
System.out.println("考试进行中");
}
});
//执行执行链
chain.execute();
}
}
实现效果
总结
- spring web mvc: request→filter→servlet →interceptor→ @Controller
- 限流降级的父类异常:BlockException