OpenFeign和Gateway集成Sentinel实现服务降级
目录
- OpenFeign集成Sentinel实现fallback服务降级
- cloud-alibaba-payment8003(支付服务)
- cloud-common-api(通用模块)
- cloud-alibaba-order9003(订单服务)
- Sentinel配置流控规则
- 测试结果
- Gateway集成Sentinel实现服务降级
- cloud-gateway9527(网关)
- 测试结果
- 总结
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: 8003spring:application:name: nacos-payment-servicecloud: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 {@Overridepublic 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: 9003spring:application:name: nacos-order-servicecloud: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 {@Resourceprivate 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: 9527spring:application:name: cloud-gatewaycloud:gateway:routes:- id: pay_routh1 # 路由的ID(类似mysql主键ID),没有固定规则但要求唯一,建议配合服务名uri: http://localhost:8003predicates:- 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();}@PostConstructpublic 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() {@Overridepublic 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 实战实用技巧的小伙伴,请关注后期发布的文章,认真看完一定能让你有所收获。