Sentinel微服务流量控制组件

一、安装并启动Sentinel控制台
1.直接从官网下载Sentinel的jar包
2.保存到指定非中文目录运行

java -jar sentinel-dashboard-1.8.1.jar

如果要修改Sentinel的默认端口、账户、密码,可以通过下列配置:

配置项默认值说明
server.port8080服务端口
sentinel.dashboard.auth.usernamesentinel默认用户名
sentinel.dashboard.auth.passwordsentinel默认密码

例如,修改端口:

java -Dserver.port=8090 -jar sentinel-dashboard-1.8.1.jar

3.访问
在这里插入图片描述
二、微服务整合Sentinel
1.引入历依赖

<!--sentinel-->
<dependency>
    <groupId>com.alibaba.cloud</groupId> 
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

2.修改application.yaml文件,添加下面内容:

server:
  port: 8088
spring:
  cloud: 
    sentinel:
      transport:
        dashboard: localhost:8080

3.浏览器请求微服务数据
打开sentinel控制台,会显示出簇点链路,sentinel_spring_web_context就是这个springMVC项目的根,/order/{orderId}就是这个根的子链路
在这里插入图片描述
4.簇点链路

当请求进入微服务时,首先会访问DispatcherServlet,然后进入Controller、Service、Mapper,这样的一个调用链就叫做簇点链路。簇点链路中被监控的每一个接口就是一个资源

默认情况下sentinel会监控SpringMVC的每一个端点(Endpoint,也就是controller中的方法),因此SpringMVC的每一个端点(Endpoint)就是调用链路中的一个资源。

二、Sentinel控流
(一)控流模式——直接
当前资源路径设置QPS限流,即限制每秒的访问数量,如果当前路径达到设置的QPS值,其他访问该路径的请求会被限流处理。
在这里插入图片描述
(二)控流模式——关联
例如,监控/write路径的QPS,如果/write达到阈值,/read路径则会被限流处理
在这里插入图片描述
(三)控流模式——链路
链路是指调用路径, 假如某一个服务方法有多个调用来源, 如果我们只想限制来自于某一个来源的的调用路径, 就可以通过链路来限流,这个调用路径就是链路

比如在一个微服务中,两个接口都调用了同一个Service中的方法,并且该方法用SentinelResource(用于定义资源)注解标注了,然后对该注解标注的资源(方法)进行配置,则可以选择链路模式。
在这里插入图片描述
在这里插入图片描述

步骤:

  1. 在OrderService中添加一个queryGoods方法,不用实现业务

  2. 在OrderController中,改造/order/query端点,调用OrderService中的queryGoods方法

  3. 在OrderController中添加一个/order/save的端点,调用OrderService的queryGoods方法

  4. 给queryGoods设置限流规则,从/order/query进入queryGoods的方法限制QPS必须小于2

实现:

1)添加查询商品方法

在order-service服务中,给OrderService类添加一个queryGoods方法:

public void queryGoods(){
    System.err.println("查询商品");
}

2)查询订单时,查询商品

在order-service的OrderController中,修改/order/query端点的业务逻辑:

@GetMapping("/query")
public String queryOrder() {
    // 查询商品
    orderService.queryGoods();
    // 查询订单
    System.out.println("查询订单");
    return "查询订单成功";
}

3)新增订单,查询商品

在order-service的OrderController中,修改/order/save端点,模拟新增订单:

@GetMapping("/save")
public String saveOrder() {
    // 查询商品
    orderService.queryGoods();
    // 查询订单
    System.err.println("新增订单");
    return "新增订单成功";
}

4)给查询商品添加资源标记

默认情况下,OrderService中的方法是不被Sentinel监控的,需要我们自己通过注解来标记要监控的方法。

给OrderService的queryGoods方法添加@SentinelResource注解:

@SentinelResource("goods")
public void queryGoods(){
    System.err.println("查询商品");
}

链路模式中,是对不同来源的两个链路做监控。但是sentinel默认会给进入SpringMVC的所有请求设置同一个root资源,会导致链路模式失效。

我们需要关闭这种对SpringMVC的资源聚合,修改order-service服务的application.yml文件:

spring:
  cloud:
    sentinel:
      web-context-unify: false # 关闭context整合

三、Sentinel流控效果
(一)快速失败
指的是如果超过QPS阈值,其他请求会直接被拒绝
(二)warm up
预热模式,但一个服务刚刚启动时,一些资源尚未完全处理,服务刚启动的时候性能相对较差,由于设置的QPS阈值较高,所以一开始高并发很容易发生问题,所以这个时候QPS应该慢慢增加至设置的值,即预热模式
(三)排队等待
排队等待则是让所有请求进入一个队列中,然后按照阈值允许的时间间隔依次执行。后来的请求必须等待前面执行完成,如果请求预期的等待时间超出最大时长,则会被拒绝。
例如:QPS = 5,意味着每200ms处理一个队列中的请求;timeout = 2000,意味着预期等待时长超过2000ms的请求会被拒绝并抛出异常。也就是说队列里最多可以排队5个等待

四、Sentinel热点参数限流
热点参数限流是分别统计参数值相同的请求,判断是否超过QPS阈值。
(一)添加@SentinelResource注解

@SentinelResource("/testIn")
    @RequestMapping("/test")
    @ResponseBody
    public String test(String a,String b) {
        System.out.println("=========================");
        System.out.println(a);
        System.out.println(b);
        System.out.println("=========================");
        return "success";
    }

(二)配置热点参数限流
1.参数索引是参数在方法中的位置,0是第一个;
2.上面配置的是全局参数限流,不考虑参数的值,如果请求时没有带上这个参数,则热点参数无效;
3.下面是热点参数限流,可以给参数配置详细值,参数类型为JAVA的基本类型;
在这里插入图片描述
五、Sentinel防止雪崩——隔离和熔断降级
(一)隔离
常见的隔离有信号量隔离和线程隔离,需要注意是的这两个起始都是多线程,信号量使用的是新线程,通过信号数来控制线程数,而线程隔离使用的是提前已经分配隔离好的线程。sentinel使用的是信号量隔离。
由于微服务调用其他微服务使用的是feign接口,所以我们需要feign接口添加sentinel功能
1.微服务yml添加如下配置

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

2.添加FallbackFactory编写访问失败处理逻辑,这里需要重写UserClient方法

public class UserClientFallbackFactory implements FallbackFactory<UserClient> {

    @Override
    public UserClient create(Throwable throwable) {
        return new UserClient(){

            @Override
            public User findById(Long id) {
                User user = new User();
                user.setUsername("nihao");
                return user;
            }
        };
    }
}

3.需要将FallbackFactory注册到spring容器中

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

4.需要在UserClient上添加注解fallbackFactory

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

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

5.在sentinel控制台找到GET:http://userservice/user/{id}资源名字添加流控,这里需要选择线程数,阈值即为线程的数量
在这里插入图片描述
在这里插入图片描述
最后需要说明一点,这里编写的流控并不是控制其他微服务调用自身微服务的,而是自身微服务内调用其他微服务时防止其他微服务故障而传导至自身的一种隔离,和之前设置的流控有所区别,所以设置需要选择线程数而不是QPS。

(二)熔断降级
在这里插入图片描述
1.慢调用
在这里插入图片描述
2.异常比例、异常数
在这里插入图片描述

六、Sentinel授权规则
这个授权并不是gateway网关的用户身份角色权限认证,而是防止微服务ip地址暴露后,浏览器跨过网关直接恶意访问微服务,当然本身微服务也可以设置安全组来拦截,sentinel有专门进行授权的功能。
1.在网关的过滤器中添加请求头

spring:
  cloud:
    gateway:
      default-filters:
        - AddRequestHeader=origin,gateway
      routes:
       # ...略

2.在微服务中编写实现RequestOriginParser类,并注入到spirng容器

package cn.itcast.order.sentinel;

import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.RequestOriginParser;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;

@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;
    }
}

3.配置授权规则
在这里插入图片描述
在这里插入图片描述
七、Sentinel自定义异常
默认情况下,发生限流、降级、授权拦截时,都会抛出异常到调用方。异常结果都是flow limmiting(限流)。这样不够友好,无法得知是限流还是降级还是授权拦截。
如果降级设置的有默认返回值,需要注意下

而如果要自定义异常时的返回结果,需要实现BlockExceptionHandler接口:

package cn.itcast.order.sentinel;

import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.BlockExceptionHandler;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityException;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException;
import com.alibaba.csp.sentinel.slots.block.flow.FlowException;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowException;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@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 + "}");
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值