【微服务全家桶】-高级篇-1-Sentinel


1 初识Sentinel

1.1 雪崩问题

雪崩问题经常发生在同步问题中

在这里插入图片描述

雪崩问题的处理方式

在这里插入图片描述

1.2 服务技术

在这里插入图片描述

1.3 sentinel安装

在这里插入图片描述

在这里插入图片描述

cd D:\Download\BaiDu_download\javaFile
java -jar sentinel-dashboard-1.8.1.jar

在这里插入图片描述

在这里插入图片描述

账号密码都是sentinel

在这里插入图片描述

1.3.1 引入demo

引入cloud-demo

在这里插入图片描述

启动nacos

startup.cmd -m standalone

依次启动cloud-demo三个服务

1.3.2 整合Sentinel

在order-service中整合sentinel,并连接控制台

1)引入Sentinel依赖

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

2)配置控制台地址

server:
  port: 8088
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/cloud_order?useSSL=false
    username: root
    password: 123sjbsjb
    driver-class-name: com.mysql.jdbc.Driver
  application:
    name: orderservice
  cloud:
    nacos:
      server-addr: localhost:8848 # nacos服务地址
#      discovery:
#        namespace: 4d6ce343-9e1b-44df-a90f-2cf2b6b3d177 # dev环境
#        ephemeral: false # 是否是临时实例
    sentinel:
        transport:
            dashboard: localhost:8080 # sentinel控制台地址

3)访问微服务的任意端点(SpringSVC的Controller的任意一个localhost:8088/order/103),触发sentinel监控

在这里插入图片描述

2 限流规则

在这里插入图片描述

在这里插入图片描述

2.1 流控入门案例

在这里插入图片描述

data/tencent.nm/micromsg/download

打开JMeter,导入测试计划

[1.2 Jmeter快速入门](res1-微服务保护Sentinel\resource\1.2 Jmeter快速入门.md)

在这里插入图片描述

启动测试用例

在这里插入图片描述

sentinel监视

在这里插入图片描述

2.2 高级设置-流控模式

在这里插入图片描述

2.2.1 关联模式

在这里插入图片描述

案例

在这里插入图片描述

在controller中添加方法

    @GetMapping("/query")
    public String query() {
        return "查询订单成功!";
    }

    @GetMapping("/update")
    public String write() {
        return "更新订单成功!";
    }
}

给query添加限流,关联资源是/update,当update触发阈值5的时候,对/query进行限流

在这里插入图片描述

启动测试,/update每秒QPS为10

在这里插入图片描述

在这里插入图片描述

显示/update访问正常

在这里插入图片描述

但如果访问/query,则访问flow limiting

在这里插入图片描述

关联模式小结

在这里插入图片描述

2.2.2 链路模式

在这里插入图片描述

案例

在这里插入图片描述

1)

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

2)

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

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

sentinel默认监控controller方法,不监控service中的,没有被监控则不能配置相应规则,则需要添加注解

在这里插入图片描述

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

修改yaml文件,关闭context

    sentinel:
      transport:
            dashboard: localhost:8080 # sentinel控制台地址
      web-context-unify: false

重启服务,两个已经分开

在这里插入图片描述

在这里插入图片描述

测试

在这里插入图片描述

在这里插入图片描述

启动,query受影响,save不受影响

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

2.3 高级设置-流控效果

在这里插入图片描述

2.3.1 warm up

在这里插入图片描述

案例

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

启动,刚开始只有3个能通过,后面就越来越多

在这里插入图片描述

2.3.2 排队等待

在这里插入图片描述

案例

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

启动,进行流量控制

在这里插入图片描述

2.3.3 热点参数限流

在这里插入图片描述

在这里插入图片描述

案例

在这里插入图片描述

因为热点参数限流对SpringMVC资源无效,所以要为Controller中的queryOrderByUserId方法加注解@SentinelResource(“hot”)

    @SentinelResource("hot")
    @GetMapping("{orderId}")
    public Order queryOrderByUserId(@PathVariable("orderId") Long orderId) {
        // 根据id查询订单并返回
        return orderService.queryOrderById(orderId);
    }

在这里插入图片描述

这个

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

101默认是2 102默认是4 103默认是10

在这里插入图片描述

2.4 隔离与降级

2.4.1 Feign整合Sentinel

在这里插入图片描述

在这里插入图片描述

feign:
  httpclient:
    enabled: true # 支持HttpClient的开关
    max-connections: 200 # 最大连接数
    max-connections-per-route: 50 # 单个路径的最大连接数
  sentinel:
    enabled: true # 开启sentinel支持

在这里插入图片描述

在feign的client包下创建fallback包,并编写UserClientFallbackFactory类

@Slf4j
public class UserClientFallbackFactory implements FallbackFactory<UserClient> {
    @Override
    public UserClient create(Throwable throwable) {
        return new UserClient() {
            @Override
            public User findById(Long id) {
                log.error("远程调用用户服务失败", throwable);
                return new User();
            }
        };
    }
}

在这里插入图片描述

注册Bean

public class DefaultFeignConfiguration {
    @Bean
    public Logger.Level logLevel(){
        return Logger.Level.BASIC;
    }

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

使用注解@FeignClient声明UserClient

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

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

重新启动访问order{id}

在这里插入图片描述

在这里插入图片描述

2.4.2 线程隔离

在这里插入图片描述

在这里插入图片描述

以前使用QPS(每秒并发数)来进行控制,现在使用线程数来控制

在这里插入图片描述

案例

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

2.4.3 熔断降级

在这里插入图片描述

2.4.3.1 慢调用

在这里插入图片描述

案例

在这里插入图片描述

先修改UserService中Controller的业务,满足RT>50ms

    @GetMapping("/{id}")
    public User queryById(@PathVariable("id") Long id,
                          @RequestHeader(value = "Truth", required = false) String truth) throws InterruptedException {
        System.out.println("truth: " + truth);
        if(id == 1){
            Thread.sleep(60);
        }
        return userService.queryById(id);
    }

在这里插入图片描述

狂刷五次101,发现返回为null,且调用时间非常短,说明熔断已经生效

{
"id": 101,
"price": 699900,
"name": "Apple 苹果 iPhone 12 ",
"num": 1,
"userId": 1,
"user": {
"id": null,
"username": null,
"address": null
}
}
2.4.3.2 异常比例

在这里插入图片描述

案例

在这里插入图片描述

    @GetMapping("/{id}")
    public User queryById(@PathVariable("id") Long id,
                          @RequestHeader(value = "Truth", required = false) String truth) throws InterruptedException {
        System.out.println("truth: " + truth);
        if(id == 1){
            Thread.sleep(60);
        }else if(id == 2){
            throw new RuntimeException("故意抛出异常");
        }
        return userService.queryById(id);
    }

103刚开始从正常访问,刷新五次102,103不能访问,触发熔断

3 授权规则

3.1 授权规则

在这里插入图片描述

在这里插入图片描述

3.1.1 添加请求头分解器

为orderService中创建sentinel包,再创建HeaderOriginParser类,并用@Component注册成Bean

在这里插入图片描述

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

3.1.2 为网关添加请求头

修改Gateway的application.yaml。- AddRequestHeader=origin,gateway

    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=origin,gateway

重新启动,为/order/{orderId}添加授权信息

在这里插入图片描述

在这里插入图片描述

设置授权规则成功,如果通过http://localhost:8088/order/101直接访问,等于绕过网关,自然拒绝访问

在这里插入图片描述

则需要通过网关进行访问,网关端口10010,因为网关中加入了请求参数,则应该通过添加?authorization=admin来进行访问

http://localhost:10010/order/101?authorization=admin

在这里插入图片描述

请求—》网关—》OraginParser—》sentinel—》controller

3.2 自定义异常

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

放在cn.itcast.order.sentinel下

@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 + "}");
    }
}

将101的流控规则设置成1,访问101,提示被限流

在这里插入图片描述

在这里插入图片描述

4 规则持久化

4.1 规则管理模式

在这里插入图片描述

4.1.1 pull

在这里插入图片描述

4.1.2 push

在这里插入图片描述

4.1.3 实现push

启动持久化jar包,然后访问簇点,清空缓存并重新加载,在-Nacos后加入流控规则

在这里插入图片描述

返回Nacos

在这里插入图片描述

访问101,则返回

{"msg": 请求被限流了, "status": 429}

为了验证是否持久化

重启微服务,规则依旧存在

  • 34
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AAA码农宝哥.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值