微服务——Sentinel--降级/规则/拦截器/执行链

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
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值