OpenFeign和Gateway集成Sentinel实现服务降级

目录

OpenFeign集成Sentinel实现fallback服务降级


cloud-alibaba-payment8003(支付服务)

1. 引入依赖

xml 复制代码
<!--SpringCloud alibaba sentinel -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!-- nacos-discovery -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- 引入自己定义的api通用包 -->
<dependency>
    <groupId>com.zzyy.cloud</groupId>
    <artifactId>cloud-common-api</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>
<!--SpringBoot通用依赖模块-->
<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>
<!--lombok-->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>
<!--test-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

2. yml配置

yaml 复制代码
server:
  port: 8003

spring:
  application:
    name: nacos-payment-service
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848  # 配置nacos地址
    sentinel:
      transport:
        dashboard: localhost:8080  #配置Sentinel dashboard控制台服务地址
        port: 8719  #默认8719端口,如果被占用会自动从8719开始依次+1扫描,直至找到未被占用的端口

3. 主启动类

java 复制代码
@SpringBootApplication
@EnableDiscoveryClient
public class Main8003 {

    public static void main(String[] args) {
        SpringApplication.run(Main8003.class, args);
    }
}

4. 控制类 PayController

java 复制代码
@RestController
public class PayController {

    @Value("${server.port}")
    private String port;

    @GetMapping("/pay/nacos/{id}")
    @SentinelResource(value = "PaySentinelResource", blockHandler = "payBlockHandler")
    public String getPayInfo(@PathVariable("id") Integer id) {
        return "支付端口" + port + ",订单" + id + "已付款/(O v O)/~~";
    }

    public String payBlockHandler(@PathVariable("id") Integer id, BlockException blockException) {
        return "支付服务限流,请稍后再试/(T o T)/~~";
    }
}

cloud-common-api(通用模块)

1. 引入依赖

xml 复制代码
<!--SpringBoot通用依赖模块-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- SpringCloud openfeign -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>

2. Feign 接口 PayFeignSentinelApi

java 复制代码
@FeignClient(value = "nacos-payment-service", fallback = PayFeignSentinelApiFallback.class)
public interface PayFeignSentinelApi {

    @GetMapping("/pay/nacos/{id}")
    public String getPayInfo(@PathVariable("id") Integer id);
}

3. 全局统一服务降级类 PayFeignSentinelApiFallback

java 复制代码
@Component
public class PayFeignSentinelApiFallback implements PayFeignSentinelApi {

    @Override
    public String getPayInfo(Integer id) {
        return "支付服务异常,服务降级...";
    }
}

cloud-alibaba-order9003(订单服务)

1. 引入依赖

xml 复制代码
<!-- 引入自己定义的api通用包 -->
<dependency>
    <groupId>com.zzyy.cloud</groupId>
    <artifactId>cloud-common-api</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>
<!--SpringCloud alibaba sentinel -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!-- SpringCloud openfeign -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- nacos-discovery -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- loadbalancer -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<!-- web + actuator -->
<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>
<!--lombok-->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>

2. yml配置

yaml 复制代码
server:
  port: 9003

spring:
  application:
    name: nacos-order-service
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
#订单模块也要引入Sentinel依赖,激活Sentinel对Feign的支持,否则Feign接口fallback将失效
feign:
  sentinel:
    enabled: true

3. 主启动类

java 复制代码
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class Main9003 {

    public static void main(String[] args) {
        SpringApplication.run(Main9003.class, args);
    }
}

4. 控制类 OrderController

java 复制代码
@RestController
public class OrderController {

    @Resource
    private PayFeignSentinelApi payFeignSentinelApi;

    @GetMapping("/order/pay/nacos/feign/{id}")
    public String getPayInfoByFeign(@PathVariable("id") Integer id) {
        String result = payFeignSentinelApi.getPayInfo(id);
        return "订单支付信息查询结果:" + result;
    }
}

Sentinel配置流控规则


测试结果

Gateway集成Sentinel实现服务降级


cloud-gateway9527(网关)

1. 引入依赖

xml 复制代码
<!-- gateway -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-transport-simple-http</artifactId>
    <version>1.8.8</version>
</dependency>
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-spring-cloud-gateway-adapter</artifactId>
    <version>1.8.8</version>
</dependency>

2. yml配置

yaml 复制代码
server:
  port: 9527

spring:
  application:
    name: cloud-gateway
  cloud:
    gateway:
      routes:
        - id: pay_routh1  # 路由的ID(类似mysql主键ID),没有固定规则但要求唯一,建议配合服务名
          uri: http://localhost:8003
          predicates:
            - Path=/pay/**  # 断言,路径相匹配的进行路由

3. 主启动类

java 复制代码
@SpringBootApplication
@EnableDiscoveryClient
public class Main9527 {

    public static void main(String[] args) {
        SpringApplication.run(Main9527.class, args);
    }
}

4. 配置类 GatewayConfiguration

java 复制代码
@Configuration
public class GatewayConfiguration {

    private final List<ViewResolver> viewResolvers;
    private final ServerCodecConfigurer serverCodecConfigurer;

    public GatewayConfiguration(ObjectProvider<List<ViewResolver>> viewResolversProvider,
                                ServerCodecConfigurer serverCodecConfigurer) {
        this.viewResolvers = viewResolversProvider.getIfAvailable(Collections::emptyList);
        this.serverCodecConfigurer = serverCodecConfigurer;
    }

    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public SentinelGatewayBlockExceptionHandler sentinelGatewayBlockExceptionHandler() {
        // Register the block exception handler for Spring Cloud Gateway.
        return new SentinelGatewayBlockExceptionHandler(viewResolvers, serverCodecConfigurer);
    }

    @Bean
    @Order(-1)
    public GlobalFilter sentinelGatewayFilter() {
        return new SentinelGatewayFilter();
    }

    @PostConstruct
    public void doInit() {
        initBlockHandler();
    }

    //处理+自定义返回的例外信息,类似我们的调用触发了流控规则保护
    private void initBlockHandler() {
        Set<GatewayFlowRule> rules = new HashSet<>();
        rules.add(new GatewayFlowRule("pay_routh1").setCount(2).setIntervalSec(1));
        GatewayRuleManager.loadRules(rules);
        BlockRequestHandler blockRequestHandler = new BlockRequestHandler() {
            @Override
            public Mono<ServerResponse> handleRequest(ServerWebExchange serverWebExchange, Throwable throwable) {
                HashMap<String, String> map = new HashMap<>();
                map.put("errorCode", HttpStatus.TOO_MANY_REQUESTS.getReasonPhrase());
                map.put("errorMsg", "系统繁忙,触发限流...");
                return ServerResponse.status(HttpStatus.TOO_MANY_REQUESTS)
                                      .contentType(MediaType.APPLICATION_JSON)
                                      .body(BodyInserters.fromValue(map));
            }
        };
        GatewayCallbackManager.setBlockHandler(blockRequestHandler);
    }
}

测试结果

总结


以上主要介绍了 OpenFeign 和 Gateway 集成 Sentinel 实现服务降级的相关知识,想了解更多 Sentinel 知识的小伙伴请参考 Sentinel 官网Spring Cloud Alibaba 官网 进行学习,学习更多 Spring Cloud 实战实用技巧的小伙伴,请关注后期发布的文章,认真看完一定能让你有所收获。

相关推荐
程序员小潘22 分钟前
Spring Gateway动态路由实现方案
后端·spring cloud
熙客1 小时前
分布式ID解决方案
java·分布式·spring cloud·微服务
whltaoin2 小时前
SpringCloud 项目阶段十:kafka实现双端信息同步以及ElasticSearch容器搭建示例
elasticsearch·spring cloud·kafka
龙茶清欢2 小时前
具有实际开发参考意义的 MyBatis-Plus BaseEntity 基类示例
java·spring boot·spring cloud·mybatis
齐 飞3 小时前
Spring Cloud Alibaba快速入门-Sentinel熔断规则
spring boot·spring cloud·sentinel
麦兜*4 小时前
Redis 7.0 新特性深度解读:迈向生产级的新纪元
java·数据库·spring boot·redis·spring·spring cloud·缓存
龙茶清欢4 小时前
最新版 springdoc-openapi-starter-webmvc-ui 常用注解详解 + 实战示例
java·spring boot·ui·spring cloud
whltaoin12 小时前
SpringCloud 项目阶段九:Kafka 接入实战指南 —— 从基础概念、安装配置到 Spring Boot 实战及高可用设计
spring boot·spring cloud·kafka
麦兜*1 天前
Redis数据迁移实战:从自建到云托管(阿里云/腾讯云)的平滑过渡
java·spring boot·redis·spring·spring cloud·阿里云·腾讯云
椰椰椰耶1 天前
[SpringCloud][7]负载均衡介绍,以及一些实现
java·spring cloud·负载均衡