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

发布于:2025-06-02 ⋅ 阅读:(29) ⋅ 点赞:(0)

在这里插入图片描述

OpenFeign集成Sentinel实现fallback服务降级


cloud-alibaba-payment8003(支付服务)

1. 引入依赖

<!--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配置

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. 主启动类

@SpringBootApplication
@EnableDiscoveryClient
public class Main8003 {

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

4. 控制类 PayController

@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. 引入依赖

<!--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

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

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

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

@Component
public class PayFeignSentinelApiFallback implements PayFeignSentinelApi {

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

cloud-alibaba-order9003(订单服务)

1. 引入依赖

<!-- 引入自己定义的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配置

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. 主启动类

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class Main9003 {

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

4. 控制类 OrderController

@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配置流控规则

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

测试结果

  • 访问 http://localhost:9003/order/pay/nacos/feign/123 返回:订单支付信息查询结果:支付端口8003,订单123已付款/(O v O)/~~
  • 连续快速访问 http://localhost:9003/order/pay/nacos/feign/123 返回:订单支付信息查询结果:支付服务限流,请稍后再试/(T o T)/~~
  • 关闭支付服务8003(模拟宕机),访问 http://localhost:9003/order/pay/nacos/feign/123 返回:订单支付信息查询结果:支付服务异常,服务降级…

Gateway集成Sentinel实现服务降级


cloud-gateway9527(网关)

1. 引入依赖

<!-- 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配置

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. 主启动类

@SpringBootApplication
@EnableDiscoveryClient
public class Main9527 {

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

4. 配置类 GatewayConfiguration

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

测试结果

  • 访问 http://localhost:9527/pay/nacos/999 返回:支付端口8003,订单999已付款/(O v O)/~~
  • 连续快速访问 http://localhost:9527/pay/nacos/999 返回:{“errorCode”: “Too Many Requests”, “errorMsg”: “系统繁忙,触发限流…”}

总结


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


网站公告

今日签到

点亮在社区的每一天
去签到