springcloud(12)SentinelResource注解配置应用及其他
本篇接上篇的sentinel,主要介绍sentinelResource注解和兜底的方法fallback的各种参数和使用。
1.配置服务提供者集群。
pom文件
<dependencies> <!-- SpringCloud ailibaba nacos--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!-- SpringCloud ailibaba sentinel--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency> <dependency> <groupId>com.bai</groupId> <artifactId>cloud-api-common</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <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> <!--热部署--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
yml文件
server:
port: 9004
spring:
application:
name: nacos-payment-provider
cloud:
nacos:
discovery:
server-addr: localhost:8848
management:
endpoints:
web:
exposure:
include: '*'
controller加入集合数据充当数据库进行测试
@RestController public class PaymentController { @Value("${server.port}") private String serverPort; public static HashMap<Long, PayMent > map = new HashMap<>(); static { map.put(1L,new PayMent(1L,"1111")); map.put(2L,new PayMent(2L,"2222")); map.put(3L,new PayMent(3L,"3333")); } @GetMapping(value = "/paymentSQL/{id}") public CommonResult<PayMent> paymentSQL(@PathVariable("id") Long id) { PayMent payment = map.get(id); CommonResult<PayMent> result = new CommonResult<>(200,"from mysql,serverPort: " + serverPort,payment); return result; } }
主启动类还是常规配置注解两个
另一个服务提供者配置同上,只需要改一下端口即可。
2.消费者配置
pom文件
<dependencies> <!-- SpringCloud ailibaba nacos--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!-- SpringCloud ailibaba sentinel--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency> <dependency> <groupId>com.bai</groupId> <artifactId>cloud-api-common</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <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> <!--热部署--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
yml文件
server:
port: 84
spring:
application:
name: nacos-order-consumer
cloud:
nacos:
discovery:
server-addr: localhost:8848
sentinel:
transport:
dashboard: localhost:8080
port: 8719
#消费者将去访问的微服务名称
server-url:
nacos-user-service: http://nacos-payment-provider
#激活Sentinel对Feign的支持
feign:
sentinel:
enabled: true
本次采用的有restTemplate所以添加配置类
@Configuration public class ApplicationConfig { @Bean @LoadBalanced public RestTemplate gettemple(){ return new RestTemplate(); } }
主启动类
@EnableDiscoveryClient @SpringBootApplication @EnableFeignClients public class Consumer84 { public static void main(String[] args) { SpringApplication.run(Consumer84.class,args); } }
controller
@RestController @Slf4j public class CircleBreakerController { public static final String SERVICE_URL = "http://nacos-payment-provider"; @Resource private RestTemplate restTemplate; @RequestMapping("/consumer/fallback/{id}") // @SentinelResource(value = "fallback") // @SentinelResource(value = "fallback",fallback ="handlerFallback") @SentinelResource(value = "fallback",fallback ="handlerFallback",blockHandler = "blockHandler") public CommonResult<PayMent> fallback(@PathVariable Long id) { CommonResult<PayMent> result = restTemplate.getForObject(SERVICE_URL + "/paymentSQL/" + id, CommonResult.class,id); //设置特定参数报错,进行降级 if(id == 4){ throw new IllegalArgumentException("IllegalArgument ,非法参数异常..."); }else if(result.getData() == null) { throw new NullPointerException("NullPointerException,该ID没有对应记录,空指针异常"); } return result; } public CommonResult handlerFallback(@PathVariable Long id,Throwable e) { PayMent payment = new PayMent(id,"null"); return new CommonResult(444,"异常handlerFallback,exception内容: " + e.getMessage(), payment); } public CommonResult blockHandler(@PathVariable Long id, BlockException e) { PayMent payment = new PayMent(id,"null"); return new CommonResult(444,"blockHandler-sentinel 限流,BlockException: " + e.getMessage(), payment); } @Resource private PaymentFeign paymentFeign; @GetMapping(value = "/consumer/paymentSQL/{id}") public CommonResult<PayMent> paymentSQLC(@PathVariable("id") Long id){ return paymentFeign.paymentSQL(id); } }
创建feign接口
@FeignClient(value ="nacos-payment-provider",fallback = PaymentFallback.class) public interface PaymentFeign { @GetMapping(value = "/paymentSQL/{id}") public CommonResult<PayMent> paymentSQL(@PathVariable("id") Long id); }
兜底的fallback
@Component public class PaymentFallback implements PaymentFeign{ @Override public CommonResult<PayMent> paymentSQL(Long id) { return new CommonResult<>(444,"服务降级返回,---PaymentFallbackService",new PayMent(id,"ErrorSerial")); } }
3.sentenelResource注解参数分析
@SentinelResource(value = "fallback",fallback ="handlerFallback",blockHandler = "blockHandler")
其中有两个比较重要的参数,fallback和blockHandler这两个都是兜底的方法,不过处理的情况却不相同。
blockhandler处理的是sentinel工具出现的限制级错误,本身方法自己出现的错误不属于block管,若是方法出现自身的错误等,该报错还是报错。
fallback则是正常的降级策略,方法出现各种报错的信息都会有fallback来兜底。
4.sentinel熔断
从controller中调用的PaymentFeign接口,实现了openfeign的功能,同时也为接口中配置了兜底的fallback方法,所以sentinel的熔断和之前的没有区别,都是一样的配置。
5.规则持久化。
在学习的过程中 可能发现了随着每次重启应用,后台sentinel中的配置规则所有的 都消失了。下面介绍配合nacos进行持久化规则,避免每次重启都进行复制的配置。
之前的sentinel测试项目yml配置datasource进行持久化
server:
port: 8401
spring:
application:
name: cloudalibaba-sentinal-service
cloud:
nacos:
discovery:
#Nacos服务注册中心地址
server-addr: localhost:8848
sentinel:
transport:
#配置Sentin dashboard地址
dashboard: localhost:8080
# 默认8719端口,假如被占用了会自动从8719端口+1进行扫描,直到找到未被占用的 端口
port: 8719
datasource: #配置流控规则持久化
ds1:
nacos:
server-addr: localhost:8848
dataId: cloudalibaba-sentinel-service
groupId: DEFAULT_GROUP
data-type: json
rule-type: flow
management:
endpoints:
web:
exposure:
include: '*'
里面的参数在之前的nacos文章中有介绍,其实就是在nacos的配置列表中创建记录的对应信息。
还需要在nacos配置列表中新建想要配置的规则持久化。大致如下。
配置的内容参数含义,可以从sentinel的界面用开发者工具进行查看内部名称,决定填写对应的参数名的值。
6.版本冲突
openfeign和sentinel在整合的时候出现的版本问题报错。提供解决方案,推荐选择第二种添加额外的类。
https://blog.csdn.net/qq_29860591/article/details/108139270
本篇所有代码均在GitHub: