Sentinel4服务熔断
1.Sentinel服务熔断Ribbon环境预说
sentinel整合ribbon+openFeign+fallback
Ribbon系列
- 启动nacos和sentinel
- 提供者9003/9004
- 消费者84
提供者9003/9004
新建cloudalibaba-provider-payment9003/9004,两个一样的做法
POM
<dependencies><!--SpringCloud ailibaba nacos --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!-- SpringBoot整合Web组件 --><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><!--日常通用jar包配置--><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: 9003spring:application:name: zds-egg-provider-payment9003cloud:nacos:discovery:server-addr: 127.0.0.1:8848 #配置Nacos地址management:endpoints:web:exposure:include: '*'
主启动
import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.client.discovery.EnableDiscoveryClient;@SpringBootApplication@EnableDiscoveryClientpublic class PaymentMain9003 {public static void main(String[] args) {SpringApplication.run(PaymentMain9003.class, args);}}
业务类
@RestControllerpublic class PaymentController {@Value("${server.port}")private String serverPort;@GetMapping(value = "/paymentSQL/{id}")public SingleResult paymentSQL(@PathVariable("id") Long id){SingleResult singleResult = new SingleResult();singleResult.success("","from mysql,serverPort: "+serverPort);return singleResult;}}
测试地址 - http://localhost:9003/paymentSQL/1
消费者84
新建zds-egg-consumer-order84
pom
<dependencies><!--SpringCloud openfeign --><!-- <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency>--><!--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><!-- SpringBoot整合Web组件 --><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><!--日常通用jar包配置--><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><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-openfeign-core</artifactId></dependency></dependencies>
YML
server:port: 84spring:application:name: nacos-order-consumercloud:nacos:discovery:server-addr: localhost:8848sentinel:transport:#配置Sentinel dashboard地址dashboard: localhost:8080#默认8719端口,假如被占用会自动从8719开始依次+1扫描,直至找到未被占用的端口port: 8719#消费者将要去访问的微服务名称(注册成功进nacos的微服务提供者)service-url:nacos-user-service: http://zds-egg-provider-payment# 激活Sentinel对Feign的支持feign:sentinel:enabled: false
主启动
@EnableDiscoveryClient@SpringBootApplication@EnableFeignClientspublic class OrderNacosMain84 {public static void main(String[] args) {SpringApplication.run(OrderNacosMain84.class, args);}}
ApplicationContextConfig
@Configurationpublic class ApplicationContextConfig {@Bean@LoadBalancedpublic RestTemplate getRestTemplate() {return new RestTemplate();}}
CircleBreakerController
@RestController@Slf4jpublic class CircleBreakerController {public static final String SERVICE_URL = "http://zds-egg-provider-payment";@Resourceprivate RestTemplate restTemplate;@RequestMapping("/consumer/fallback/{id}")@SentinelResource(value = "fallback")//没有配置public SingleResult fallback(@PathVariable Long id) {SingleResult result = restTemplate.getForObject(SERVICE_URL + "/paymentSQL/" + id, SingleResult.class, id);if (id == 4) {throw new IllegalArgumentException("IllegalArgumentException,非法参数异常....");} else if (result.getData() == null) {throw new NullPointerException("NullPointerException,该ID没有对应记录,空指针异常");}return result;}}
测试地址 - http://localhost:84/consumer/fallback/1
2.Sentinel服务熔断无配置
3.Sentinel服务熔断只配置fallback
4.Sentinel服务熔断只配置blockHandler
5. Sentinel服务熔断fallback和blockHandler都配置
6.Sentinel服务熔断exceptionsToIgnore
7.Sentinel服务熔断OpenFeign
修改84模块
- 84消费者调用提供者9003
- Feign组件一般是消费侧
pom
<!--SpringCloud openfeign --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency>
yml
# 激活Sentinel对Feign的支持feign:sentinel:enabled: true
业务类
带@Feignclient注解的业务接口,fallback = PaymentFallbackService.class
@FeignClient(value = "zds-egg-provider-payment",fallback = PaymentFallbackService.class)public interface PaymentService {@GetMapping(value = "/paymentSQL/{id}")public SingleResult paymentSQL(@PathVariable("id") Long id);}
@Componentpublic class PaymentFallbackService implements PaymentService{@Overridepublic SingleResult paymentSQL(Long id) {return new SingleResult().except(44444,"服务降级返回,---PaymentFallbackService","","");}}
Controller
//==================OpenFeign@Resourceprivate PaymentService paymentService;@GetMapping(value = "/consumer/paymentSQL/{id}")public SingleResult paymentSQL(@PathVariable("id") Long id) {return paymentService.paymentSQL(id);}
启动类
@EnableDiscoveryClient@SpringBootApplication@EnableFeignClients//<--------------public class OrderNacosMain84 {public static void main(String[] args) {SpringApplication.run(OrderNacosMain84.class, args);}}
测试 - http://localhost:84/consumer/paymentSQL/1
测试84调用9003,此时故意关闭9003微服务提供者,84消费侧自动降级,不会被耗死。
熔断框架比较
| - | Sentinel | Hystrix | resilience4j | | —- | —- | —- | —- |
| 隔离策略 | 信号量隔离(并发线程数限流) | 线程池隔商/信号量隔离 | 信号量隔离 |
| 熔断降级策略 | 基于响应时间、异常比率、异常数 | 基于异常比率 | 基于异常比率、响应时间 |
| 实时统计实现 | 滑动窗口(LeapArray) | 滑动窗口(基于RxJava) | Ring Bit Buffer |
| 动态规则配置 | 支持多种数据源 | 支持多种数据源 | 有限支持 |
| 扩展性 | 多个扩展点 | 插件的形式 | 接口的形式 |
| 基于注解的支持 | 支持 | 支持 | 支持 |
| 限流 | 基于QPS,支持基于调用关系的限流 | 有限的支持 | Rate Limiter |
| 流量整形 | 支持预热模式匀速器模式、预热排队模式 | 不支持 | 简单的Rate Limiter模式 |
| 系统自适应保护 | 支持 | 不支持 | 不支持 |
| 控制台 | 提供开箱即用的控制台,可配置规则、查看秒级监控,机器发观等 | 简单的监控查看 | 不提供控制台,可对接其它监控系统 |
8.Sentinel持久化规则
是什么
一旦我们重启应用,sentinel规则将消失,生产环境需要将配置规则进行持久化。
怎么玩
将限流配置规则持久化进Nacos保存,只要刷新8401某个rest地址,sentinel控制台的流控规则就能看到,只要Nacos里面的配置不删除,针对8401上sentinel上的流控规则持续有效。
步骤
修改zds-egg-sentinel8401
POM
<!--SpringCloud ailibaba sentinel-datasource-nacos 后续做持久化用到--><dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-datasource-nacos</artifactId></dependency>
YML
server:port: 8401spring:application:name: zds-egg-sentinel-servicecloud:nacos:discovery:namespace: bcba2f23-08ae-45e7-9ef0-f659cdf60cebgroup: DEFAULT_GROUPserver-addr: 127.0.0.1:8848 #Nacos服务注册中心地址sentinel:transport:dashboard: 127.0.0.1:8080 #配置Sentinel dashboard地址port: 8719# Sentinel默认会将Controller方法做context整合,导致链路模式的流控失效# web-context-unify: falsedatasource: #<---------------------------关注点,添加Nacos数据源配置ds1: # 这里的flow名字随便取 流控规则nacos:namespace: bcba2f23-08ae-45e7-9ef0-f659cdf60cebserver-addr: 127.0.0.1:8848dataId: zds-egg-sentinel-servicegroupId: SENTINEL_GROUPdata-type: jsonrule-type: flow#暴露自己的端点management:endpoints:web:exposure:include: '*'feign:sentinel:enabled: true # 激活Sentinel对Feign的支持
添加Nacos业务规则配置
配置内容解析
[{"resource": "/rateLimit/byUrl","IimitApp": "default","grade": 1,"count": 1,"strategy": 0,"controlBehavior": 0,"clusterMode": false}]
- resource:资源名称;
- limitApp:来源应用;
- grade:阈值类型,0表示线程数, 1表示QPS;
- count:单机阈值;
- strategy:流控模式,0表示直接,1表示关联,2表示链路;
- controlBehavior:流控效果,0表示快速失败,1表示Warm Up,2表示排队等待;
- clusterMode:是否集群。
启动8401后刷新sentinel发现业务规则有了
快速访问测试接口 - http://localhost:8401/rateLimit/byUrl - 页面返回Blocked by Sentinel (flow limiting)
停止8401再看sentinel - 停机后发现流控规则没有了
新启动8401再看sentinel
- 乍一看还是没有,稍等一会儿
- 多次调用 - http://localhost:8401/rateLimit/byUrl
- 重新配置出现了,持久化验证通过
