微服务-sentinel降级熔断+nacos注册中心+riboon负载+openfeign服务调用

环境搭建

nacos 2.0.0
官方文档地址:https://nacos.io/zh-cn/docs/what-is-nacos.html

下载链接:https://pan.baidu.com/s/1mm0cnJepEVUJ7ZcoeDZCtg
提取码:kunt

sentinel-dashboard-1.8.1
官方文档地址:https://github.com/alibaba/Sentinel/wiki/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8
下载链接:https://pan.baidu.com/s/1aDLQYtMissPH1Z1AoJPpbw
提取码:yna3

启动方式

1.启动nacos:

进入nacos的bin目录执行命令

.\startup.cmd -m standalone

进入管理界面

管理界面
http://localhost:8848/nacos/#/login
账号:nacos
密码:nacos
在这里插入图片描述

2.启动sentinel

java -Dserver.port=8718 -Dcsp.sentinel.dashboard.server=localhost:8718 -Dproject.name=sentinel-dashboard -Dcsp.sentinel.api.port=8719 -jar D:\sentinel\sentinel-dashboard-1.8.1.jar

管理界面
http://localhost:8718/#/login
账号:sentinel
密码:sentinel
在这里插入图片描述

项目搭建集成

消费端:
cloudalibaba-consumer-nacos-order84
服务端:
cloudalibaba-consumer-nacos-payment9003
cloudalibaba-consumer-nacos-payment9004

服务端:

1.引入pom

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!-- 基础配置 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

2.修改yml

server:
  port: 9003
spring:
  application:
    name: nacos-payment-provider
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848 #配置nacos地址
management:
  endpoints:
    web:
      exposure:
        include: '*'

3.修改启动类

@SpringBootApplication
@EnableDiscoveryClient
public class PaymentMain9003 {
    public static void main(String[] args) {
        SpringApplication.run(PaymentMain9003.class,args);
    }
}

4.修改controller
简单demo没有连数据库,id不等于100就返回内容,如果id等于100的话data就返回null

import com.atguigu.springcloud.entities.CommonResult;
import com.atguigu.springcloud.entities.Payment;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


@RestController
@RequestMapping("/payment")
@Slf4j
public class PaymentController {
    @Value("${server.port}")
    private String serverPort;

    @GetMapping(value = "/{id}")
    public CommonResult echo(@PathVariable("id") Long id) {
        CommonResult<Payment> result = new CommonResult<>();
        if(id!=100){
            Payment payment = new Payment();
            payment.setId(id);
            payment.setSerial("202104113113");
            result = new CommonResult(
                    200,"success:"+serverPort,payment);
        }else {
            result = new CommonResult(
                    200,"success:"+serverPort,null);
        }
        return result;
    }
}

消费端

1.修改pom

<dependencies>
        <!--nacos -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!-- nacos后续持久化 -->
        <dependency>
        <groupId>com.alibaba.csp</groupId>
        <artifactId>sentinel-datasource-nacos</artifactId>
        </dependency>
        <!-- sentinel-->
        <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
        <!-- openfeign-->
        <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!-- 基础配置 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

2.修改yml

server:
  port: 84
spring:
  application:
    name: nacos-order-consumer
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848 #配置nacos地址
    sentinel:
      transport:
        dashboard: localhost:8718 #sentinel地址
        port: 8719
      # nacos配置持久化
      datasource:
        ds1:
          nacos:
            server-addr: 127.0.0.1:8848 #nacos地址
            dataId: ${spring.application.name}
            groupId: DEFAULT_GROUP
            data-type: json
            rule-type: flow
#消费者访问微服务服务端名称
service-url:
  nacos-user-service: http://nacos-payment-provider
#激活sentinel对feign的支持
feign:
  sentinel:
    enabled: true

3.目录结构
在这里插入图片描述

4.修改启动类

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class OrderMain84 {
    public static void main(String[] args) {
        SpringApplication.run(OrderMain84.class,args);
    }
}

5.配置RestTemplate+负载

@Configuration
public class ApplicationContextConfig {
    @Bean
    @LoadBalanced//开启负载均衡的功能
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

6.服务熔断降级配置详解

1. 不配置服务熔断

	@GetMapping(value = "/fallback/{id}")
    @SentinelResource(value = "fallback")//没有配置
    public CommonResult<Payment> fallback(@PathVariable Long id) {
        CommonResult result = restTemplate.getForObject(SERVICE_URL + "/payment/"
                + id, CommonResult.class, id);
        if(id==4){
            throw new IllegalArgumentException("IllegalArgumentException,非法参数异常");
        }else if (result.getData()==null){
            throw new NullPointerException("NullPointerException,改id没有对应记录,空指针异常");
        }
        return result;
    }

根据上面demo逻辑

id为4的时候会报非法参数异常
id为100的时候会报空指针异常

在这里插入图片描述

2.配置fallback(管理代码业务异常)

配置fallback之后,代码的业务逻辑出现异常之后,不直接把异常抛给用户,而是用一个捕获异常的方法,称之为兜底服务,你出错,我来兜底,为你的报错买单,给用户友好提示

fallback的参数就是兜底的方法名,这里是handlerFallback方法

	@GetMapping(value = "/fallback/{id}")
    @SentinelResource(value = "fallback",fallback = "handlerFallback")//fallback只负责业务
    public CommonResult<Payment> fallback(@PathVariable Long id) {
        CommonResult result = restTemplate.getForObject(SERVICE_URL + "/payment/"
                + id, CommonResult.class, id);
        if(id==4){
            throw new IllegalArgumentException("IllegalArgumentException,非法参数异常");
        }else if (result.getData()==null){
            throw new NullPointerException("NullPointerException,改id没有对应记录,空指针异常");
        }
        return result;
    }
    // 服务熔断降级处理,函数签名与原函数一致或加一个 Throwable 类型的参数
    public CommonResult handlerFallback(Long id,Throwable exception){
        return new CommonResult(444,"handlerFallback异常兜底服务"+exception.getMessage()+" 服务端服务不可用");
    }

这时候我们调用接口发现,当id为4非法参数异常的时候,没有向之前那样,直接返回报错信息,而是返回了我们自定义的异常信息。
在这里插入图片描述

3.配置blockHandler(配合Sentinel控制台配置)

配置接口流控规则,1s访问一次
在这里插入图片描述
在这里插入图片描述

	@GetMapping(value = "/fallback/{id}")
    @SentinelResource(value = "fallback")//没有配置
    public CommonResult<Payment> fallback(@PathVariable Long id) {
        CommonResult result = restTemplate.getForObject(SERVICE_URL + "/payment/"
                + id, CommonResult.class, id);
        if(id==4){
            throw new IllegalArgumentException("IllegalArgumentException,非法参数异常");
        }else if (result.getData()==null){
            throw new NullPointerException("NullPointerException,改id没有对应记录,空指针异常");
        }
        return result;
    }

当我们频繁点击,超过1s一次的限制之后,页面会返回异常,当我们不想让它直接抛出异常,而是给友好提示,这时候就需要配置blockHandler搭配页面配置使用
在这里插入图片描述
修改

@SentinelResource(value = "fallback",blockHandler = "blockHandler")//blockHandler只负责Sentinel控制台配置

添加blockHandler指向的方法

 // 服务流量控制处理,参数最后多一个 BlockException,其余与原函数一致。
 public CommonResult blockHandler(Long id,BlockException exception){
     return new CommonResult(444,exception.getClass().getCanonicalName()+"\t 服务端服务不可用");
 }

再来测试,1s中调用多次,这次超过接口调用限制之后,使用了我们自己的异常信息。
在这里插入图片描述

4.举一反三

如果两者都配置则 被限流降级而抛出BlockException时只会进入blockHandler

@SentinelResource(value = "fallback",fallback = "handlerFallback",blockHandler = "blockHandler")

exceptionsToIgnore排除异常

@SentinelResource(value = "fallback",fallback = "handlerFallback",blockHandler = "blockHandler", exceptionsToIgnore={IllegalArgumentException.class})

这里大家可以自己去尝试一下,不在演示。

5.openfeign服务调用

1.controller

 @GetMapping(value = "/payment/{id}")
 public CommonResult<Payment> payment_ok(@PathVariable("id") Long id){
     return paymentService.payment_ok(id);
 }

2.service

@Component
@FeignClient(value = "nacos-payment-provider",fallback = PaymentServiceImpl.class)
public interface PaymentService {
    @GetMapping(value = "/payment/{id}")
    public CommonResult<Payment> payment_ok(@PathVariable("id") Long id);
}

3.serviceImpl
注意
//import org.springframework.stereotype.Component;

@Component
public class PaymentServiceImpl implements PaymentService {
    @Override
    public CommonResult<Payment> payment_ok(Long id) {
        return new CommonResult<>(-99999,"服务降级返回,PaymentServiceImpl");
    }
}
@FeignClient(value = "nacos-payment-provider",fallback = PaymentServiceImpl.class)

在这里插入图片描述
代码详解
value表示的服务名,这里也就是上面服务端注册进nacos的服务名称,fallback指的是,当服务端接口出现了异常的时候,指向自己的兜底接口,我们这里直接指向了实现类,当关闭服务端之后,调用controller测试,服务端关闭,走了我们自己的实现类方法,保证了系统的稳定,没有因为服务端的异常影响到自己。
在这里插入图片描述

6.sentinel持久化

当sentinel重新启动时,sentinel dashboard中原来的数据将会全部消失,这样就需要重新定义限流规则,无疑是不可取的。所以需要将sentinel中定义的限流规则保存到配置中心里面。

1.关键pom

  <dependency>
  	<groupId>com.alibaba.csp</groupId>
  	<artifactId>sentinel-datasource-nacos</artifactId>
  </dependency>

2.yml

      # nacos配置持久化
      datasource:
        ds1:
          nacos:
            server-addr: 127.0.0.1:8848 #nacos地址
            dataId: ${spring.application.name}
            groupId: DEFAULT_GROUP
            data-type: json
            rule-type: flow

在这里插入图片描述
3.nacos添加配置
在这里插入图片描述

参数描述描述
resource资源名,即规则的作用对象
grade熔断策略,支持慢调用比例/异常比例/异常数策略慢调用比例
count慢调用比例模式下为慢调用临界 RT(超出该值计为慢调用);异常比例/异常数模式下为对应的阈值
timeWindow熔断时长,单位为 s
minRequestAmount熔断触发的最小请求数,请求数小于该值时即使异常比率超出阈值也不会熔断(1.7.0 引入)5
statIntervalMs统计时长(单位为 ms),如 60*1000 代表分钟级(1.8.0 引入)1000 ms
slowRatioThreshold慢调用比例阈值,仅慢调用比例模式有效(1.8.0 引入)

在这里插入图片描述

[
  {
    "resource": "GET:http://nacos-payment-provider/payment/{id}",
    "count": 1,
    "grade": 1,
    "limitApp": "default",
    "strategy": 0,
    "controlBehavior": 0
  }
]
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值