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 实战实用技巧的小伙伴,请关注后期发布的文章,认真看完一定能让你有所收获。

相关推荐
隔壁小邓15 分钟前
SpringCloud微服务拆分原则
spring cloud·微服务·架构
深念Y6 小时前
Nginx和Spring Cloud Gateway
运维·服务器·网络·网关·nginx·spring cloud·微服务
WZTTMoon1 天前
Spring Boot 启动报错:OpenFeign 隐性循环依赖,排查了整整一下午
java·spring boot·后端·spring cloud·feign
冬天豆腐2 天前
Springcloud,Nacos管理,打jar包后,启动报错
java·spring cloud·maven·jar
Fang fan2 天前
Redis基础数据结构
数据结构·数据库·redis·缓存·bootstrap·sentinel
爱吃山竹的大肚肚2 天前
依赖冲突快速解决
java·spring boot·后端·spring cloud·maven
用户8307196840822 天前
Spring Boot 启动报错:OpenFeign 隐性循环依赖,排查了整整一下午
java·spring boot·spring cloud
indexsunny2 天前
互联网大厂Java面试实战:从Spring Boot到微服务架构的音视频场景解析
java·spring boot·spring cloud·mybatis·spring security·jwt·flyway
⑩-2 天前
API 网关的作用?Spring Cloud Gateway 原理?
java·服务器·网络·spring cloud
better_liang2 天前
每日Java面试场景题知识点之-Spring Cloud微服务分布式事务解决方案
java·spring cloud·微服务·seata·面试题·分布式事务·tcc