微服务保护-sentinel入门

目录

1.初识sentinel

1.雪崩问题及解决方案

2.安装sentinel控制台 

3.引入demo-cloud 

 4.微服务整合sentinel

2.限流规则

 1.给 /order/{orderId}这个资源设置流控规则,QPS不能超过 5

 2.流控模式

 3.流控效果

3.热点参数限流 

 3.隔离和降级

1.Feign整合Sentinel

2.线程隔离

 4.授权规则

1.授权规则

2.自定义异常结果 

5.规则持久化


1.初识sentinel

1.雪崩问题及解决方案

微服务调用链路中的某个服务故障,引起整个链路中的所有微服务都不可用,这就是雪崩。

解决雪崩问题的常见方式有四种:
超时处理:设定超时时间,请求超过一定时间没有响应就返回错误信息,不会无休止等待
舱壁模式:限定每个业务能使用的线程数,避免耗尽整个tomcat的资源,因此也叫线程隔离。
熔断降级:由断路器统计业务执行的异常比例,如果超出阈值则会熔断该业务,拦截访问该业务的一切请求
流量控制:限制业务访问的QPS,避免服务因流量的突增而故障。

Sentinel是阿里巴巴开源的一款微服务流量控制组件。官网地址:home

2.安装sentinel控制台 

sentinel入门

sentinel官方提供了UI控制台,方便我们对系统做限流设置。大家可以在GitHub下载

java -jar sentinel-dashboard-1.8.1.jar
然后访问: localhost:8080 即可看到控制台页面,默认的账户和密码都是 sentinel

微服务保护-sentinel入门_第1张图片

3.引入demo-cloud 

https://gitee.com/hsmymk/cloud-demo

要使用Sentinel肯定要结合微服务,这里我们使用SpringCloud实用篇中的cloud-demo工程。

微服务保护-sentinel入门_第2张图片

 4.微服务整合sentinel

微服务保护-sentinel入门_第3张图片

2.限流规则

微服务保护-sentinel入门_第4张图片

 1./order/{orderId}这个资源设置流控规则,QPS不能超过 5

微服务保护-sentinel入门_第5张图片

 2.流控模式

在添加限流规则时,点击高级选项,可以选择三种流控模式:

直接:统计当前资源的请求,触发阈值时对当前资源直接限流,也是默认的模式
关联:统计与当前资源相关的另一个资源,触发阈值时,对当前资源限流
链路:统计从指定链路访问到本资源的请求,触发阈值时,对指定链路限流

微服务保护-sentinel入门_第6张图片

微服务保护-sentinel入门_第7张图片

 微服务保护-sentinel入门_第8张图片

 微服务保护-sentinel入门_第9张图片

 微服务保护-sentinel入门_第10张图片

 3.流控效果

流控效果是指请求达到流控阈值时应该采取的措施,包括三种:

快速失败:达到阈值后,新的请求会被立即拒绝并抛出 FlowException 异常。是默认的处理方式。
warm up :预热模式,对超出阈值的请求同样是拒绝并抛出异常。但这种模式阈值会动态变化,从一个较小值逐渐增加到最大阈值。
排队等待:让所有的请求按照先后次序排队执行,两个请求的间隔不能小于指定时长

微服务保护-sentinel入门_第11张图片

 流控效果-warm up

微服务保护-sentinel入门_第12张图片

 流控效果-排队等待

 微服务保护-sentinel入门_第13张图片

3.热点参数限流 

微服务保护-sentinel入门_第14张图片

 微服务保护-sentinel入门_第15张图片

 微服务保护-sentinel入门_第16张图片

 3.隔离和降级

虽然限流可以尽量避免因高并发而引起的服务故障,但服务还会因为其它原因而故障。而要将这些故障控制在一定范围,避免雪崩,就要靠线程隔离(舱壁模式)和熔断降级手段了。
不管是线程隔离还是熔断降级,都是对
客户端(调用方)的保护。

1.Feign整合Sentinel

SpringCloud中,微服务调用都是通过Feign来实现的,因此做客户端保护必须整合FeignSentinel

1.修改OrderServiceapplication.yml文件,开启FeignSentinel功能

feign:
  sentinel:
    enabled: true #开启feign对sentinel支持

 2.FeignClient编写失败后的降级逻辑
feing-api项目中定义类,实现FallbackFactory

@Slf4j
public class UserClientFallbackFactory implements FallbackFactory {
    @Override
    public UserClient create(Throwable throwable) {
        return new UserClient() {
            @Override
            public User findById(Long id) {
                log.error("查询用户异常",throwable);
                return new User();
            }
        };
    }
}

3.feing-api项目中的DefaultFeignConfiguration类(配置类)中将UserClientFallbackFactory注册为一个Bean

    @Bean
    public UserClientFallbackFactory userClientFallbackFactory(){
        return new UserClientFallbackFactory();
    }

4.feing-api项目中的UserClient接口中使用UserClientFallbackFactory

@FeignClient(value = "userservice",
            fallbackFactory = UserClientFallbackFactory.class)
public interface UserClient {

    @GetMapping("/user/{id}")
    User findById(@PathVariable("id") Long id);
}

2.线程隔离

线程隔离有两种方式实现:

线程池隔离
信号量隔离( Sentinel 默认采用)

微服务保护-sentinel入门_第17张图片

 1.线程隔离(舱壁模式)

微服务保护-sentinel入门_第18张图片

 2.熔断降级

微服务保护-sentinel入门_第19张图片

 3.熔断策略-慢调用

微服务保护-sentinel入门_第20张图片

 4.熔断策略-异常比例、异常数

微服务保护-sentinel入门_第21张图片

 4.授权规则

1.授权规则

微服务保护-sentinel入门_第22张图片

 微服务保护-sentinel入门_第23张图片

 例如,我们尝试从request中获取一个名为origin的请求头,作为origin的值:

@Component
public class HeaderOriginParser implements RequestOriginParser {
    @Override
    public String parseOrigin(HttpServletRequest request) {
        //1.获取请求头
        String origin = request.getHeader("origin");
        //2.非空判断
        if (StringUtils.isEmpty(origin)){
            origin="blank";
        }
        return origin;
    }
}

我们还需要在gateway服务中,利用网关的过滤器添加名为gatewayorigin

spring:
  application:
    name: gateway
  cloud:
    nacos:
      server-addr: localhost:8848 # nacos地址
    gateway:
      routes:
        - id: user-service # 路由标示,必须唯一
          uri: lb://userservice # 路由的目标地址
          predicates: # 路由断言,判断请求是否符合规则
            - Path=/user/** # 路径断言,判断路径是否是以/user开头,如果是则符合
        - id: order-service
          uri: lb://orderservice
          predicates:
            - Path=/order/**
      default-filters:
        - AddRequestHeader=Truth,Itcast is freaking awesome!
        - AddRequestHeader=orign,gateway

微服务保护-sentinel入门_第24张图片

2.自定义异常结果 

默认情况下,发生限流、降级、授权拦截时,都会抛出异常到调用方。如果要自定义异常时的返回结果,需要实现BlockExceptionHandler接口:
微服务保护-sentinel入门_第25张图片

 微服务保护-sentinel入门_第26张图片

 我们在order-service中定义类,实现BlockExceptionHandler接口:

@Component
public class SentinelExceptionHandler implements BlockExceptionHandler {
    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception {
        String msg = "未知异常";
        int status = 429;

        if (e instanceof FlowException) {
            msg = "请求被限流了";
        } else if (e instanceof ParamFlowException) {
            msg = "请求被热点参数限流";
        } else if (e instanceof DegradeException) {
            msg = "请求被降级了";
        } else if (e instanceof AuthorityException) {
            msg = "没有权限访问";
            status = 401;
        }

        response.setContentType("application/json;charset=utf-8");
        response.setStatus(status);
        response.getWriter().println("{\"msg\": " + msg + ", \"status\": " + status + "}");
    }
}

5.规则持久化

https://blog.csdn.net/m0_61107050/article/details/122590486

你可能感兴趣的:(微服务,微服务,java,microservices)