双剑合璧 Nacos 结合 Sentinel 实现流量安全控制 (6)

Redis 配置规则

文件配置规则

Sentinel 支持通过本地文件加载规则配置,使用方式如下(限流规则作为演示):

spring: cloud: # 配置 Sentinel sentinel: datasource: ds1: file: file: classpath:flowRule.json data-type: json rule-type: flow

flowRule.json 对应 com.alibaba.csp.sentinel.slots.block.RuleConstant 各属性。

[ { "resource": "selectProductList", "count": 1, "grade": 1, "limitApp": "default", "strategy": 0, "controlBehavior": 0 } ]

重要属性:

Field 说明 默认值
resource   资源名,资源名是限流规则的作用对象    
count   限流阈值    
grade   限流阈值类型,QPS 模式(1)或并发线程数模式(0)   QPS 模式  
limitApp   流控针对的调用来源   default,代表不区分调用来源  
strategy   调用关系限流策略:直接、链路、关联   根据资源本身(直接)  
controlBehavior   流控效果(直接拒绝 / 排队等待 / 慢启动模式),不支持按调用关系限流   直接拒绝  
clusterMode   是否集群限流    

访问客户端以后,刷新控制台,查看流控规则如下:

双剑合璧 Nacos 结合 Sentinel 实现流量安全控制

RestTemplate 支持

Spring Cloud Alibaba Sentinel 支持对 RestTemplate 调用的服务进行服务保护。需要在构造 RestTemplate Bean 时添加 @SentinelRestTemplate 注解。

启动类

OrderServiceRestApplication.java

package com.example; import com.alibaba.cloud.sentinel.annotation.SentinelRestTemplate; import com.example.exception.ExceptionUtil; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.context.annotation.Bean; import org.springframework.web.client.RestTemplate; @SpringBootApplication public class OrderServiceRestApplication { @Bean @LoadBalanced @SentinelRestTemplate(blockHandler = "handleException", blockHandlerClass = ExceptionUtil.class, fallback = "fallback", fallbackClass = ExceptionUtil.class) public RestTemplate restTemplate() { return new RestTemplate(); } public static void main(String[] args) { SpringApplication.run(OrderServiceRestApplication.class, args); } } 服务熔断处理类

ExceptionUtil.java 必须使用静态方法。

package com.example.exception; import com.alibaba.cloud.sentinel.rest.SentinelClientHttpResponse; import com.alibaba.csp.sentinel.slots.block.BlockException; import com.alibaba.fastjson.JSON; import com.example.pojo.Product; import org.springframework.http.HttpRequest; import org.springframework.http.client.ClientHttpRequestExecution; import org.springframework.http.client.ClientHttpResponse; public class ExceptionUtil { // 服务流量控制处理 public static ClientHttpResponse handleException(HttpRequest request, byte[] body, ClientHttpRequestExecution execution, BlockException exception) { exception.printStackTrace(); return new SentinelClientHttpResponse( JSON.toJSONString(new Product(1, "服务流量控制处理-托底数据", 1, 2666D))); } // 服务熔断降级处理 public static ClientHttpResponse fallback(HttpRequest request, byte[] body, ClientHttpRequestExecution execution, BlockException exception) { exception.printStackTrace(); return new SentinelClientHttpResponse( JSON.toJSONString(new Product(1, "服务熔断降级处理-托底数据", 1, 2666D))); } } 访问

控制台设置流量控制规则,定义资源访问的 QPS 为 1(每秒能处理查询数目)。

快速刷新页面多次访问::9090/order/1 结果如下:

双剑合璧 Nacos 结合 Sentinel 实现流量安全控制

OpenFeign 支持 添加依赖 <!-- spring cloud alibaba sentinel 依赖 --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency> <!-- spring cloud openfeign 依赖 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> 开启 Sentinel server: port: 9091 # 端口 spring: application: name: order-service-feign # 应用名称 cloud: # 配置 Nacos 注册中心 nacos: discovery: enabled: true # 如果不想使用 Nacos 进行服务注册和发现,设置为 false 即可 server-addr: 127.0.0.1:8848 # Nacos 服务器地址 # 配置 Sentinel sentinel: transport: port: 8719 dashboard: localhost:8080 # feign 开启 sentinel 支持 feign: sentinel: enabled: true 熔断降级

ProductServiceFallback.java

package com.example.fallback; import com.example.pojo.Product; import com.example.service.ProductService; import feign.hystrix.FallbackFactory; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; /** * 服务熔断降级处理可以捕获异常 */ @Slf4j @Component public class ProductServiceFallbackFactory implements FallbackFactory<ProductService> { @Override public ProductService create(Throwable throwable) { return new ProductService() { @Override public Product selectProductById(Integer id) { // 获取日志,在需要捕获异常的方法中进行处理 log.error("product-service 服务的 selectProductById 方法出现异常,异常信息如下:" + throwable); return new Product(id, "托底数据", 1, 2666D); } }; } } 消费服务

ProductService.java

package com.example.service; import com.example.fallback.ProductServiceFallbackFactory; import com.example.pojo.Product; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; // 声明需要调用的服务 @FeignClient(value = "product-service", fallbackFactory = ProductServiceFallbackFactory.class) public interface ProductService { /** * 根据主键查询商品 * * @param id * @return */ @GetMapping("/product/{id}") Product selectProductById(@PathVariable("id") Integer id); }

OrderServiceImpl.java

package com.example.service.impl; import com.example.pojo.Order; import com.example.service.OrderService; import com.example.service.ProductService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.Arrays; @Service public class OrderServiceImpl implements OrderService { @Autowired private ProductService productService; /** * 根据主键查询订单 * * @param id * @return */ @Override public Order selectOrderById(Integer id) { return new Order(id, "order-001", "中国", 2666D, Arrays.asList(productService.selectProductById(1))); } } 控制层 package com.example.controller; import com.example.pojo.Order; import com.example.service.OrderService; import org.springframework.beans.factory.annotation.Autowired; 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("/order") public class OrderController { @Autowired private OrderService orderService; /** * 根据主键查询订单 * * @param id * @return */ @GetMapping("/{id}") public Order selectOrderById(@PathVariable("id") Integer id) { return orderService.selectOrderById(id); } } 启动类 package com.example; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.openfeign.EnableFeignClients; // 开启 FeignClients 注解 @EnableFeignClients // 开启 @EnableDiscoveryClient 注解,当前版本默认会开启该注解 //@EnableDiscoveryClient @SpringBootApplication public class OrderServiceFeignApplication { public static void main(String[] args) { SpringApplication.run(OrderServiceFeignApplication.class, args); } } 测试

控制台信息如下:

双剑合璧 Nacos 结合 Sentinel 实现流量安全控制

添加流量控制规则,定义资源访问的 QPS 为 1(每秒能处理查询数目)。

双剑合璧 Nacos 结合 Sentinel 实现流量安全控制

快速刷新页面多次访问::9091/order/1 结果如下:

双剑合璧 Nacos 结合 Sentinel 实现流量安全控制

或者关闭服务提供者,访问::9091/order/1 结果如下:

双剑合璧 Nacos 结合 Sentinel 实现流量安全控制

Gateway 支持

Sentinel 支持对 Spring Cloud Gateway、Netflix Zuul 等主流的 API Gateway 进行限流。

双剑合璧 Nacos 结合 Sentinel 实现流量安全控制

官网文档:

https://github.com/alibaba/spring-cloud-alibaba/wiki/Sentinel

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyfpfd.html