有商品服务,订单服务。

首先在父项依赖中统一依赖版本

<dependencyManagement>
    <!--声明spring-cloud的版本信息-->
    <dependencies>
        <!--声明spring-cloud的版本信息-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>2021.0.4</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <!--声明spring-cloud-alibaba的信息-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-dependencies</artifactId>
            <version>2021.0.4.0</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

一 、服务治理 Nacos Discovery

默认8848端口

用于实现各个微服务的自动化注册与发现。

①写nacos依赖

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

②在配置文件中添加Nacos服务的地址

spring:
  application:
    name: xxx          #告诉nacos我的名字
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848        #找到nacos的地址

二、远程调用负载均衡LoadBalancer

分为服务端负载均衡客户端负载均衡

①写入依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>

②注解@LoadBalanced

③负载均衡策略

1.RandomLoadBalancer-随机分配策略

2.RoundRobinLoadBalancer-轮询分配策略(默认)

三、远程调用Feign(默认集成了负载均衡)

①依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

②在启动类OrderServer.java上添加Fegin的扫描注解

@EnableFeignClients

③在shop-order-server项目中新增接口ProductFeignApi

/**
 *  name属性:访问远端服务器的名字
 *  fallback属性:当远端服务访问失败时,本地的错误处理类
 */
@FeignClient(name = "product",fallback = ProductFeignFallback.class)
public interface ProductFeignApi {
    @GetMapping("/product/get/{pid}")
    TShopProduct get(@PathVariable("pid") Long pid);
}

④访问失败处理类

/**
 *  本地容错类,当Feign接口请求远端服务器失败时,就会调用该类获取兜底数据
 */
@Component
public class ProductFeignFallback implements ProductFeignApi {

    @Override
    public TShopProduct get(Long pid) {
        TShopProduct product = new TShopProduct();
        product.setPid(-1L);
        product.setPname("商品错误");
        product.setPprice(0.0D);
        product.setStock(0);

        return product;
    }
}

⑤远程调用方法

//远程调用商品微服务,查询商品信息
Product product = productFeignApi.findByPid(productId);

四、服务熔断降级 Sentinel!!!!重点

规则默认放在内存中,如果想要进行持久化需要写配置

sentinel可视化控制台的端口号默认为:8080

sentinel与服务之间的交互端口号默认为:8719

sentinel中有两种资源:

1.在sentinel中,Controller中的接口默认被识别成sentinel的资源

2.使用@SentinelResource注解也可以声明资源,注解括号里的名字是资源名

常见容错方案:隔离机制、超时机制、限流机制、熔断机制、降级机制

①Sentinel依赖

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

②修改配置文件

spring:
  cloud:
    sentinel:
      transport:
        port: 9999 #跟控制台交流的端口,随意指定一个未使用的端口即可
         dashboard: localhost:8080 # 指定控制台服务的地址

sentinel规则种类:流控规则、降级规则、热点规则、系统规则、授权规则

4.1 流控规则

流控模式:直接、关联、链路

直接:谁超过阈值范围就给谁限流

关联:比如资源让行,自己超过阈值,则让其他限流

        实际案例:付费网站,普通用户给vip用户让行

链路:访问同一个资源,不同的用户走不同的链路,例如vip1走vip1链路、vip2走vip2链路、普通用户走普通用户链路

流控效果:快速失败、Warm Up、排队等待

快速失败(默认):直接抛出500异常或显示Blocked by Sentinel(flow limiting)

Warm up:经过预热时长最终会达到阈值数,开始的阈值数为设置的阈值数的三分之一,如果在此期间达到阈值也会抛出异常

        实际场景:(可理解为机械的最大性能)例如服务器刚启动性能还没有完全发挥,先让它预热

排队等待:如果超出阈值,则会进行等待,如果等待时间用完还不能进去,则一样抛出异常

        实际场景(用得少,仅适用于小网站,如果大一点的则会雪崩):网站用户量稳定假设只有2000,每年只增长100,服务器能承受的数量为2200,当超过2200则可以让超过的用户访问的慢一点,但是如果买了一个新的服务器,则需要20年才可以勉强用满

4.2 降级规则

根据服务器的状况来进行降级,流控规则是根据访问的线程数来进行管理。

①慢调用比例

RT:最大响应时间

最小请求数:自己设置

实际场景:tomcat每秒可以请求千八百个请求,如果只来了10个请求,还有问题,只能说明是网络或者硬件问题,不是服务器高并发问题

熔断时长

服务器默认是熔断关闭状态,当慢调用比例达到阈值会变成熔断开启状态,则接下来的熔断时长内的请求会自动被熔断。经过熔断时长后熔断器会进入半熔断状态,若接下来的一个请求响应的时间小于设置的慢调用RT则会结束熔断,否则会再次熔断

上面配置表示,如果在1S之内,有【超过1个的请求】且这些请求中【响应时间>最大RT】的【请求数量比例>10%】,就会触发熔断,在接下来的10s之内都不会调用真实方法,直接走降级方法。

②异常比例

③异常数

单位时间内,异常数超过阈值

4.3 热点规则

用来限定热点的

        实际场景:如果在商品网站中大家都来抢购热点商品,但是不能因为这个,让不来抢购热点商品的用户感受到卡顿

这里要注意!!!,在Controller中写接口的时候,要在接口上写上@SentinelResource("资源名")注解

参数索引:参数在的下标位置

单机阈值:几秒钟中最多访问几次

参数例外项是用来设置特殊商品的,例如热点商品

4.4 授权规则

①要写一个请求解析器,用来解析请求的目标来源

import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.RequestOriginParser;

@Component
public class RemoteOriginParser implements RequestOriginParser {

    @Override
    public String parseOrigin(HttpServletRequest httpServletRequest) {
        String fromsource = httpServletRequest.getHeader("fromsource");
        if (fromsource == null || "".equals(fromsource)){
            fromsource = "error";
        }
        return fromsource;
    }
}

②接口

@RequestMapping("/auth1")
public String auth1(String serviceName){
    log.info("应用:{},访问接口",serviceName);
    return "auth1";
}

③新增授权规则

④访问测试

4.5 系统规则

针对整个服务器层面,不针对指定的接口

一般实际开发中,用的多的是Load自适应和入口QPS

4.6 Sentinel 自定义返回异常

分为一下几种异常:
  • FlowException 限流异常
  • DegradeException 降级异常
  • ParamFlowException 参数限流异常(热点异常)
  • AuthorityException 授权异常
  • SystemBlockException 系统负载异常(系统异常)

4.6.1异常处理类(只捕获Sentinel的异常)

/**
 *  能解决在触发sentinel规则后,出现'block by sentinel(Flow limiting)'的异常;直接抛出500的异常解决不了
 *  只捕获sentinel的异常
 */
@Component
public class ShopBlockExceptionHandler implements BlockExceptionHandler {
    /**
    * 当发生异常就会进入这个方法
    */
    @Override
    public void handle(HttpServletRequest req, HttpServletResponse resp, BlockException e) throws Exception {

        Map<String,Object> map = new HashMap<>();
        if (e instanceof FlowException){
            // 限流异常
            map.put("code",-1);
            map.put("msg","限流异常");
        }else if (e instanceof DegradeException){
            // 降级异常
            map.put("code",-2);
            map.put("msg","降级异常");
        }else if (e instanceof ParamFlowException){
            // 热点异常
            map.put("code",-3);
            map.put("msg","热点异常");
        }else if (e instanceof AuthorityException){
            // 授权异常
            map.put("code",-4);
            map.put("msg","授权异常");
        }else if (e instanceof SystemBlockException){
            // 系统异常
            map.put("code",-5);
            map.put("msg","系统异常");
        }

        String jsonString = JSON.toJSONString(map);
        resp.setContentType("application/json;charset=utf-8");
        resp.getWriter().write(jsonString);
    }
}

4.6.2统一异常处理(可以捕获所有的异常)

/**
 * 统一异常处理,可以捕获所有的异常
 */
@RestControllerAdvice
public class MyExceptionHandler{

    @ExceptionHandler(BlockException.class)
    public Object handleBlockException(BlockException e){
        Map<String,Object> map = new HashMap<>();
        if (e instanceof FlowException){
            // 限流异常
            map.put("code",-1);
            map.put("msg","限流异常");
        }else if (e instanceof DegradeException){
            // 降级异常
            map.put("code",-2);
            map.put("msg","降级异常");
        }else if (e instanceof ParamFlowException){
            // 热点异常
            map.put("code",-3);
            map.put("msg","热点异常");
        }else if (e instanceof AuthorityException){
            // 授权异常
            map.put("code",-4);
            map.put("msg","授权异常");
        }else if (e instanceof SystemBlockException){
            // 系统异常
            map.put("code",-5);
            map.put("msg","系统异常");
        }
        return map;
    }

}

4.7@SentinelResource的使用

可用于:

        1.通过不同接口访问同一个资源

        2.热点规则,在接口上写上这个注解

主要参数:

         value:设置资源名称

                可以为空,此时资源名为包名.类名.方法名

        blockHandler/blockHandlerClass和fallback/fallbackClass用于指定异常的处理,但是一般不会这样用,我们基本都是用同一异常来进行异常处理

        blockHander用于处理Sentinel发生的异常,而fallback用于处理其他的异常

        exceptionsToIgnore:忽略某些异常

4.8 Feign整合Sentinel

之前写的代码思路都是正向请求,意思是我们请求的东西一定会被请求到。

现在我们如果请求不到某些东西,则要用Sentinel进行降级处理(fallback)

4.8.1依赖

feign:

  sentinel:

    enabled: true

之所以是写这个依赖,是因为现在的框架集成度很高,feign可以用别的来进行熔断处理不一定是sentinel,所以要把他开启

4.8.2创建容错类

/**
 *  本地容错类,当Feign接口请求远端服务器失败时,就会调用该类获取兜底数据
 */
@Component
public class ProductFeignFallback implements ProductFeignApi {

    @Override
    public TShopProduct get(Long pid) {
        TShopProduct product = new TShopProduct();
        product.setPid(-1L);
        product.setPname("商品错误");
        product.setPprice(0.0D);
        product.setStock(0);

        return product;
    }

}

4.8.3在feign接口中定义容错类

/**
 *  name属性:访问远端服务器的名字
 *  fallback属性:当远端服务访问失败时,本地的错误处理类
 */
@FeignClient(name = "product",fallback = ProductFeignFallback.class)
public interface ProductFeignApi {

    @GetMapping("/product/get/{pid}")
    TShopProduct get(@PathVariable("pid") Long pid);
}

有一种情况面试会问:当前项目中出现这么一个问题,A服务访问B服务第一次访问成功,第二次失败,以此类推

分析:一会请求成功,一会请求失败,说明有多台服务器,失败的情况就是访问到了不好用的服务器(网络问题、重编译了、下线了)

:因为负载均衡,其中有某一个服务器是挂了的情况

五、 服务网关Gateway

Gateway网关不是基于tomcat体系的,而是基于Netty服务器

Gateway也可以负载均衡

网关能找到服务器,则说明Gateway是nacos中的一个客户端

5.1 集成服务网关

①需要导入3个依赖

<!--Gateway依赖-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>

<!--nacos依赖-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

<!--负载均衡依赖-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>

②启动类没有什么好说的了

③配置文件

server:
  port: 9000
spring:
  application:
    name: gateway
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
    gateway:
      discovery:
        locator:
          enabled: true  # 让gateway可以发现nacos中的微服务
gateway是springCloud团队开发的,nacos是alibaba开发的,代码不是互通的,所以要写spring.cloud.gateway.discovery.locator.enabled=true这个配置
这样网关就配置好了,接下来进行测试
之前访问 localhost:8091/sentinel2
现在访问 localhost:9000/order/sentinel2 访问的是一个内容,其中9000是网关的端口号,order是要请求的服务名

5.2 自定义网关路由

如果用默认的网关路由会出现以下问题:
  • 暴露服务名,不安全
  • 服务名太长,输入地址不方便
编写自定义路由,只需要在application.yml中添加新的路由规则:
spring:
  cloud:
    gateway:
      routes:  # 一个网关中有多个路由,注意不要写成route
        - id: product_route
          uri: lb://product  # 这个要写微服务的名字
          predicates:
            - Path=/p/**   # 只有满足这个路径,才会走网关
          filters:
            - StripPrefix=1 # 跳过一级路径,也就是p
        - id: order_route
          uri: lb://order
          predicates:
            - Path=/o/**
          filters:
            - StripPrefix=1

注意还有一个重要参数order,值越小越先进行匹配

执行流程:

5.3 过滤器 Filter

过滤器就是在请求的传递过程中,对请求和响应做一些手脚。
在Gateway中,Filter的生命周期只有两个:“pre”和“post”
  • PRE:这种过滤器在请求被路由之前调用。我们可利用这种过滤器实现身份验证、在集群中选择请求的微服务、记录调试信息等。
  • POST:这种过滤器在路由到微服务以后执行。这种过滤器可用来为响应添加标准的HTTPHeader、收集统计信息和指标、将响应从微服务发送给客户端等。
在Gateway中,Filter的作用范围分为两种:
  • GatewayFilter:应用到单个路由或者一个分组的路由上。
  • GlobalFilter:应用到所有的路由上。

5.4 局部路由过滤器统计耗时

在配置路由规则中的filters下,加入- show=true
@Component
public class TimeGatewayFilterFactory extends AbstractGatewayFilterFactory<TimeGatewayFilterFactory.MyConfig> {

    public TimeGatewayFilterFactory(){
        super(MyConfig.class);
    }

    @Override
    public List<String> shortcutFieldOrder() {
//        Stream.of("a", "str", "b").toList();
        List<String> collect = Stream.of("show").collect(Collectors.toList());
        return collect;
    }

    // 加工过滤器的方法
    @Override
    public GatewayFilter apply(MyConfig config) {
        // 生成的过滤器,并返回
        return new GatewayFilter() {
            /**
             *  过滤器的过滤方法
             *  参数1:相当于tomcat容器体系下,request和response对象的整合
             *  参数2:过滤器链
             */
            @Override
            public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
                if (!config.show){ // 如果配置中设置为false,直接放行,不需要统计耗时
                    return chain.filter(exchange);
                }
                // pre过滤器
                long begin = System.currentTimeMillis();
                return chain.filter(exchange).then(Mono.fromRunnable(()->{
                    // post过滤器
                    long end = System.currentTimeMillis();
                    // 发请求的客户端域名
                    String ip = exchange.getRequest().getRemoteAddress().getHostName();
                    // 请求的资源地址
                    String path = exchange.getRequest().getURI().getPath();

                    StringBuffer stringBuffer = new StringBuffer();
                    stringBuffer.append(ip).append("访问接口").append(path).append("耗时").append(end-begin).append("毫秒");
                    System.err.println(stringBuffer.toString());
                }));
            }
        };
    }

    // 用于存放配置文件中的参数
    @Data
    public static class MyConfig{
        private boolean show;
    }
}

5.5 全局路由过滤器

@Component
public class ShopAuthFilter implements GlobalFilter {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//        System.err.println("全局路由过滤器被执行了");
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();
        String token = request.getQueryParams().getFirst("token");
        if (StringUtils.isBlank(token)) { // 传递的token是null,"",或者空白符
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            return response.setComplete();
        }else {
            // 验证token合法性
            // 如果token不合法,返回401
        }
        return chain.filter(exchange); // 放行
    }
}

5.6 集成Sentinel实现网关限流

①依赖

<!--Sentinel集成Gateway 依赖-->
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-spring-cloud-gateway-adapter</artifactId>
</dependency>
<!--Sentinel 依赖-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!--提供控制台支持 依赖-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency>

②添加配置

spring:
  cloud:
    sentinel:
      transport:
        port: 9999
        dashboard: localhost:8080

③配置完成后进行限流操作

5.7 API分组

是方法层面上的限流,更精细

一共有3种匹配模式:精确、前缀、正则

现在我们定义了如下的接口地址

@RestController
@RequestMapping("/v1")
public class TestController {
    @RequestMapping("/test1")
    public String test1() {
        return "test1";
    }

    @RequestMapping("/test2")
    public String test2() {
        return "test2";
    }

    @RequestMapping("/test3/test")
    public String test3() {
        return "test3";
    }
}

5.7.1 精准匹配

1.在API管理中新建API分组,匹配模式选择精准匹配,匹配串写请求URL地址

2.在流控规则中,API类型中选择API分组,然后在API名称中选择我们刚刚定义的V1限流

3.此时上面三个请求中,只有 /o/v1/test1会被限流

5.7.2 前缀匹配

然后在增加流控规则,此时/o/v1/**路径下的所有请求都会被流控

注意: 如果路径为/*表示匹配一级路径,如果路径为/**表示多级路径

5.7.3 正则匹配

5.8 修改限流默认返回格式

@Configuration
public class ShopGatewayConfig {
    // 不用主动调用
    @PostConstruct
    public void ShopGatewayExceptionHandle(){

        BlockRequestHandler blockRequestHandler = new BlockRequestHandler() {
            @Override
            public Mono<ServerResponse> handleRequest(ServerWebExchange serverWebExchange, Throwable throwable) {
                Map<String,Object> map = new HashMap<>();
                map.put("code",-100);
                map.put("message","网关路由被限流");
                return ServerResponse.status(HttpStatus.OK) // 状态
                        .contentType(MediaType.APPLICATION_JSON) // JSON类型
                        .body(BodyInserters.fromValue(map)); //用Body插入器插入map
            }
        };

        GatewayCallbackManager.setBlockHandler(blockRequestHandler);
    }
    
}

六、链路追踪 Sleuth&Zipkin

Sleuth是用来与@Slf4j配合打日志的

6.1 集成链路追踪组件Sleuth

导入依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>

6.2 日志参数解释

日志格式:

[order,c323c72e7009c077,fba72d9c65745e60,true]

1、第一个值,spring.application.name的值

2、第二个值,c323c72e7009c077 ,sleuth生成的一个ID,叫Trace ID,用来标识一条请求链路,一条请求链路中包含一个Trace ID,多个Span ID

3、第三个值,fba72d9c65745e60,spanID 基本的工作单元,获取元数据,如发送一个http

4、第四个值:true,是否要将该信息输出到zipkin服务中来收集和展示。

可以根据时间判断哪个日志先执行的

6.3 Zipkin+Sleuth整合

①导入依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-zipkin</artifactId>
    <version>2.2.8.RELEASE</version>
</dependency>

②加入配置

spring:
  zipkin:
    base-url: http://127.0.0.1:9411/   #zipkin server的请求地址
    discoveryClientEnabled: false   #让nacos把它当成一个URL,而不要当做服务名
  sleuth:
    sampler:
      probability: 1.0 #采样的百分比

七、配置中心 Nacos Config

微服务架构下关于配置文件的一些问题:

        1.配置文件相对分散。在一个微服务架构下,配置文件会随着微服务的增多变的越来越多,而且分散在各个微服务中,不好统一配置和管理。

        2.配置文件无法区分环境。微服务项目可能会有多个环境,例如:测试环境、预发布环境、生产环境。每一个环境所使用的配置理论上都是不同的,一旦需要修改,就需要我们去各个微服务下手动维护,这比较困难。

        3. 配置文件无法实时更新。我们修改了配置文件之后,必须重新启动微服务才能使配置生效,这对一个正在运行的项目来说是非常不友好的。

基于上面这些问题,我们就需要配置中心的加入来解决这些问题

配置中心的思路是:

首先把项目中各种配置全部都放到一个集中的地方进行统一管理,并提供一套标准的接口。

当各个服务需要获取配置的时候,就来配置中心的接口拉取自己的配置。

当配置中心中的各种参数有更新的时候,也能通知到各个服务实时的过来同步最新的信息,使之动态更新。

当加入了服务配置中心之后,我们的系统架构图会变成下面这样:

7.1 Nacos Config入门

1.导入依赖

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>

2.在微服务中添加config的配置

注意:不能使用原来的 application.yml 作为配置文件,而是新建一个 bootstrap.yml 作为配置文件

spring:
  application:
    name: product
  cloud:
    nacos:
      config:
        server-addr: 127.0.0.1:8848    #nacos中心地址
        file-extension: yml    # 配置文件格式
  profiles:
    active: dev   # 环境标识

3.在nacos中添加配置,然后把商品微服务application.yml配置复制到配置内容中.

4.注释本地的application.yam中的内容, 启动程序进行测试

7.2 配置动态刷新

只需一个注解@RefreshScope

1.在nacos中的product-service-dev.yaml配置项中添加下面配置:

appConfig:

  name: product

2. 在商品微服务中新增NacosConfigControlller.java

@RestController
@RefreshScope  // 配置动态刷新
public class NacosConfigController {
    @Value("${appConfig.name}")
    private String appConfigName;
    @RequestMapping("/nacosConfig1")
    public String nacosConfig(){
       return "远程信息:"+appConfigName;
    }
}

7.3 配置共享

  • 同一个微服务的不同环境之间共享配置
①环境不同
同一个product微服务可能有不同环境,例如开发环境、测试环境。
        把开发环境和测试环境的配置相同的部分抽取出来,放到product.yml中。        
        把独有的配置放到自己的配置文件中,开发环境独有的server.port=8091放到product-dev.yml中,测试环境独有的server.port=8099放到product-test.yml中。
当程序运行时,会先读取product.yml文件覆盖到本地的配置文件中,然后再读取相应环境的配置文件再进行覆盖。
②端口号不同
product微服务进行了集群,端口分别为8081、8082、8083。
也是先抽取相同的配置放到product.yml中,然后再将不同的配置分别放到product-dev8081.yml、product-dev8082.yml、product-dev8083.yml中。
然后通过idea来配置,
  • 不同微服务中间共享配置
用于网站外联

1. 在nacos中定义一个DataID为global-config.yaml的配置,用于所有微服务共享

globalConfig: global

2. 修改bootstrap.yaml

spring:
  application:
    name: product
  cloud:
    nacos:
      config:
        server-addr: 127.0.0.1:8848     #nacos中心地址
  file-extension: yml     # 配置文件格式
  shared-configs:
     - data-id: global-config.yaml     # 配置要引入的配置
       refresh: true
    profiles:
    active: test     # 环境标识

7.4Sentinel规则持久化

1.导入依赖

<!-- sentinel持久化访问Nacos的数据源依赖 -->
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-datasource-nacos</artifactId>
</dependency>

2.修改bootstrap.yml文件,增加datasource的配置

spring:
    sentinel:
      datasource:     # sentinel数据源
        ds1: # 自定义连接名
          nacos:
            server-addr: localhost:8848     # nacos服务地址
            data-id: sentinel-consumer-ds1     # nacos的dataId
            group-id: DEFAULT_GROUP     # 默认分组
            data-type: json        # 数据类型 json类型
            rule-type: flow        # flow表示流控规则
rule-type有五种的流控规则
  • authority (授权规则)
  • degrade (降级规则)
  • flow (流控规则)
  • param (热点规则)
  • system (系统规则)
3. 在Nacos的控制面板新建 sentinel-consumer-ds1 的DataId,具体配置内容如下
[
    {
        "resource":"/sentinel2",   // 资源名
        "limitApp":"default",    // 默认来源
        "grade": 1,        // QPS
        "count": 2,        // 一秒2请求
        "strategy": 0,        // 直接流控
        "controlBehavior": 0,    // 快速失败
        "clusterMode": false    // 是不是集群
    }
]

4. 然后访问/sentinel2,可以看到在Sentinel的管控台中看到流控规则了.

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐