一、sentinel的持久化配置

上一章中我们通过Dashboard来为Sentinel客户端设置各种各样的规则,但是这些规则默认是存放在内存中,极不稳定,无法用于生成环境,所以需要将其持久化。

DataSource 扩展常见的实现方式有:

  • 拉模式:客户端主动向某个规则管理中心定期轮询拉取规则,这个规则中心可以是 RDBMS、文件,甚至是 VCS 等。这样做的方式是简单,缺点是无法及时获取变更;
  • 推模式:规则中心统一推送,客户端通过注册监听器的方式时刻监听变化,比如使用 Nacos、Zookeeper 等配置中心。这种方式有更好的实时性和一致性保证。

Sentinel 目前支持以下数据源扩展:

生产环境中一般常用的就是推模式。这里我们使用Nacos存储规则。推送模式的正确做法应该是 配置中心控制台/Sentinel 控制台 → 配置中心 → Sentinel 数据源 → Sentinel

1.1 sentinel同步nacos配置

  1. 增加sentinel的依赖和nacos存储扩展依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
  1. 添加nacos相关配置
spring:
cloud:
sentinel:
datasource:
# 名称随意
javatrip:
nacos:
server-addr: 127.0.0.1:8848
dataId: ${spring.application.name}-rules
groupId: SENTINEL_GROUP
# 规则类型,取值见:
# org.springframework.cloud.alibaba.sentinel.datasource.RuleType
rule-type: flow
  1. 提供接口用于测试限流
@RestController
class test{ @RequestMapping("/test")
public String test(){
return "Java旅途";
}
}
  1. nacos中增加限流规则的配置

  • resource:资源名,即限流规则的作用对象
  • limitApp:流控针对的调用来源,若为 default 则不区分调用来源
  • grade:限流阈值类型(QPS 或并发线程数);0代表根据并发数量来限流,1代表根据QPS来进行流量控制
  • count:限流阈值
  • strategy:调用关系限流策略
  • controlBehavior:流量控制效果(直接拒绝、Warm Up、匀速排队)
  • clusterMode:是否为集群模式
  1. 测试,访问test接口,发现sentinel-dashboard中出现了一条流控规则

1.2 sentinel-dashboard中修改规则同步到nacos

要想实现在sentinel-dashboard中修改规则并同步到nacos,我们就需要修改sentinel服务。首先我们去官网下载Sentinel。

  1. 修改pom文件
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
<scope>test</scope>
</dependency>

将test注释掉,因为这个是作用与test目录下的。

<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
<!--<scope>test</scope>-->
</dependency>
  1. 找到 sentinel-dashboard/src/test/java/com/alibaba/csp/sentinel/dashboard/rule/nacos目录,将整个目录拷贝到 sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/rule/
  2. 找到 com.alibaba.csp.sentinel.dashboard.controller.v2.FlowControllerV2 ,将默认动态规则修改为nacos动态规则。
@Autowired
@Qualifier("flowRuleDefaultProvider")
private DynamicRuleProvider<List<FlowRuleEntity>> ruleProvider;
@Autowired
@Qualifier("flowRuleDefaultPublisher")
private DynamicRulePublisher<List<FlowRuleEntity>> rulePublisher;

修改为:

@Autowired
@Qualifier("flowRuleNacosProvider")
private DynamicRuleProvider<List<FlowRuleEntity>> ruleProvider;
@Autowired
@Qualifier("flowRuleNacosPublisher")
private DynamicRulePublisher<List<FlowRuleEntity>> rulePublisher;
  1. 找到 sentinel-dashboard/src/main/webapp/resources/app/scripts/directives/sidebar/sidebar.html

将以下内容注释去掉

<!--<li ui-sref-active="active" ng-if="entry.appType==0">-->
<!--<a ui-sref="dashboard.flow({app: entry.app})">-->
<!--<i class="glyphicon glyphicon-filter"></i>&nbsp;&nbsp;流控规则 V1</a>-->
<!--</li>-->
  1. 重新编译打包,运行打包后的sentinel-dashboard.jar。

  2. 测试,我们删除nacos中的流量规则配置

  • 在sentinel-dashboard——>流量规则V1中新增一个规则。

  • 刷新nacos,发现多了一个配置

  • 在nacos中修改这个配置,将阀值改为1

  • 刷新sentinel-dashboard,流量阀值修改为1了。

  • 重启服务,重启sentinel-dashboard,发现流控规则依然存在。

注意:以上只是演示了流控规则的持久化,sentinel还支持其他规则,如果想实现哪种规则都可以采用相同的方式实现!

二、Gateway网关限流

限流:就是请求多了,对请求进行定制的快速响应处理,应用在服务提供者本身。

从 1.6.0 版本开始,Sentinel 提供了 Spring Cloud Gateway 的适配模块,可以提供两种资源维度的限流:

  • route 维度:即在 Spring 配置文件中配置的路由条目,资源名为对应的 routeId
  • 自定义 API 维度:用户可以利用 Sentinel 提供的 API 来自定义一些 API 分组
  1. 添加依赖
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-spring-cloud-gateway-adapter</artifactId>
<version>x.y.z</version>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-transport-simple-http</artifactId>
</dependency>
  1. 注入对应的 SentinelGatewayFilter 实例以及 SentinelGatewayBlockExceptionHandler 实例。
@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 MySentinelGatewayBlockExceptionHandler(viewResolvers,serverCodecConfigurer);
} @Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public GlobalFilter sentinelGatewayFilter() {
return new SentinelGatewayFilter();
}
}
  1. 自定义异常处理
public class MySentinelGatewayBlockExceptionHandler extends SentinelGatewayBlockExceptionHandler {

    private List<ViewResolver> viewResolvers;
private List<HttpMessageWriter<?>> messageWriters;
public MySentinelGatewayBlockExceptionHandler(List<ViewResolver> viewResolvers, ServerCodecConfigurer serverCodecConfigurer) {
super(viewResolvers,serverCodecConfigurer);
this.viewResolvers = viewResolvers;
this.messageWriters = serverCodecConfigurer.getWriters();
}
@Override
public Mono<Void> handle(ServerWebExchange serverWebExchange, Throwable throwable) { if(serverWebExchange.getResponse().isCommitted()){
return Mono.error(throwable);
}
if(!BlockException.isBlockException(throwable)){
return Mono.error(throwable);
}
return handleBlockedRequest(serverWebExchange, throwable).flatMap(response -> writeResponse(response, serverWebExchange));
}
private Mono<ServerResponse> handleBlockedRequest(ServerWebExchange exchange, Throwable throwable) {
return GatewayCallbackManager.getBlockHandler().handleRequest(exchange, throwable);
} private final Supplier<ServerResponse.Context> contextSupplier = () -> new ServerResponse.Context() {
@Override
public List<HttpMessageWriter<?>> messageWriters() {
return MySentinelGatewayBlockExceptionHandler.this.messageWriters;
} @Override
public List<ViewResolver> viewResolvers() {
return MySentinelGatewayBlockExceptionHandler.this.viewResolvers;
}
}; private Mono<Void> writeResponse(ServerResponse response, ServerWebExchange exchange) {
ServerHttpResponse resp = exchange.getResponse();
resp.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
String json = "{\"code\": -1, \"data\": null, \"msg\": \"访问量过大,请稍后再试\"}";
DataBuffer buffer = resp.bufferFactory().wrap(json.getBytes(StandardCharsets.UTF_8));
return resp.writeWith(Mono.just(buffer));
}
}
  1. 配置路由
server:
port: 7003
spring:
application:
name: alibaba-gateway
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
gateway:
enabled: true
discovery:
locator:
enabled: true # 开启从注册中心动态创建路由的功能,利用微服务名称进行路由
routes:
- id: sentinel-nacos # 路由id,建议配合服务名
uri: lb://sentinel-nacos #匹配路由名
predicates:
- Path=/sentinel/** # 断言,路径相匹配的进行路由
filters:
- StripPrefix=1
  1. 添加启动参数
-Dcsp.sentinel.app.type=1 -Dcsp.sentinel.dashboard.server=localhost:8081 -Dproject.name=alibaba-gateway

  1. 访问接口,查看效果

三、feign调用实现熔断降级

降级:就是服务崩溃了,所以降级逻辑应该应用在消费者(调用者)那里,加在服务提供者本身是毫无意义的,因为服务已经断开了。

我们根据实际需求在sentinel-dashboard中配置降级规则,然后编写代码。

  1. 定义接口
@RequestMapping("/test")
public String test(){
return "Java旅途";
}
  1. 定义远程服务调用接口
@FeignClient(name = "nacos-sentinel",fallback = RmoteTestFallback.class)
interface RemoteTest{
@RequestMapping("/test")
public String test();
}

为了简写fallback,我们更倾向于用fallbackFactory = RmoteTestFallbackFactory.class

@FeignClient(name = "nacos-sentinel",fallbackFactory = RmoteTestFallbackFactory.class)
interface RemoteTest{
@RequestMapping("/test")
public String test();
}
  1. 服务降级处理fallback
@Component
class RmoteTestFallback implements RemoteTest{
@Override
public String test() {
return null;
}
}
  1. 服务降级处理fallbackFactory
@Component
class RmoteTestFallbackFactory implements FallbackFactory<RemoteTest> {
@Override
public RemoteTest create(Throwable throwable) {
return null;
}
}

Spring Cloud Alibaba系列(六)sentinel的实际应用的更多相关文章

  1. Spring Cloud Alibaba系列(一)nacos作为服务注册中心

    Spring Cloud Alibaba各组件版本关系 Spring Cloud Alibaba Version Sentinel Version Nacos Version RocketMQ Ver ...

  2. Spring Cloud Alibaba系列之分布式服务组件Dubbo

    本博客的例子代码可以在github找到下载链接:代码下载 SpringBoot.SpringCloud Alibaba系列博客专栏:链接 1.分布式理论 1.1.分布式基本定义 <分布式系统原理 ...

  3. Spring Cloud Alibaba系列(二)nacos作为服务配置中心

    Nacos 提供用于存储配置和其他元数据的 key/value 存储,为分布式系统中的外部化配置提供服务器端和客户端支持.使用 Spring Cloud Alibaba Nacos Config,您可 ...

  4. Spring Cloud Alibaba系列(五)sentinel实现服务限流降级

    一.sentinel是什么 sentinel的官方名称叫分布式系统的流量防卫兵.Sentinel 以流量为切入点,从流量控制.熔断降级.系统负载保护等多个维度保护服务的稳定性.在Spring Clou ...

  5. spring cloud 入门系列六:使用Zuul 实现API网关服务

    通过前面几次的分享,我们了解了微服务架构的几个核心设施,通过这些组件我们可以搭建简单的微服务架构系统.比如通过Spring Cloud Eureka搭建高可用的服务注册中心并实现服务的注册和发现: 通 ...

  6. Spring Cloud Alibaba系列(三)使用feign进行服务调用

    什么是Feign Feign是spring cloud提供的一个声明式的伪http客户端,它使得调用远程服务就像调用本地服务一样简单,只需要创建一个接口并添加一天注解即可. Nacos很好的兼容了Fe ...

  7. Spring Cloud Alibaba系列(四)使用gateway作为服务网关

    什么是网关 在微服务架构里,服务的粒度被进一步细分,各个业务服务可以被独立的设计.开发.测试.部署和管理.这时,各个独立部署单元可以用不同的开发测试团队维护,可以使用不同的编程语言和技术平台进行设计, ...

  8. Spring Cloud Alibaba 新一代微服务解决方案

    本篇是「跟我学 Spring Cloud Alibaba」系列的第一篇, 每期文章会在公众号「架构进化论」进行首发更新,欢迎关注. 1.Spring Cloud Alibaba 是什么 Spring ...

  9. Spring Cloud Alibaba 从孵化到 "挂牌" 之旅

    背景 2014 年,Spring Boot 1.0 发布.Spring Boot 的发布绝对是 Pivotal 历史上具有里程碑意义的事件,它让我们能够非常简便地开发 Spring 应用,屏蔽了各种配 ...

随机推荐

  1. Java实现第九届蓝桥杯耐摔指数

    耐摔指数 题目描述 x星球的居民脾气不太好,但好在他们生气的时候唯一的异常举动是:摔手机. 各大厂商也就纷纷推出各种耐摔型手机.x星球的质监局规定了手机必须经过耐摔测试,并且评定出一个耐摔指数来,之后 ...

  2. java实现第七届蓝桥杯取球博弈

    题目9.取球博弈 取球博弈 两个人玩取球的游戏. 一共有N个球,每人轮流取球,每次可取集合{n1,n2,n3}中的任何一个数目. 如果无法继续取球,则游戏结束. 此时,持有奇数个球的一方获胜. 如果两 ...

  3. java实现第六届蓝桥杯熊怪吃核桃

    熊怪吃核桃 题目描述 森林里有一只熊怪,很爱吃核桃.不过它有个习惯,每次都把找到的核桃分成相等的两份,吃掉一份,留一份.如果不能等分,熊怪就会扔掉一个核桃再分.第二天再继续这个过程,直到最后剩一个核桃 ...

  4. Python脚本批量修改服务器密码

    搭建环境 centos 7.4 使用脚本 python 批量修改connect用户的密码 生成密码为随机密码 保存为xls文档   passwd_chang #!/usr/bin/env python ...

  5. SpringMVC+Mybatis初尝试

    一个月前简单学完了SpringMVC框架和Mybatis框架,一直没有使用过,今天主要用它做了个简单的学生管理系统,不过第一次用框架,实现的功能简单,比较low. 注:这里使用的数据库是SQLServ ...

  6. ubuntu qwt6.1.0安装

    1.ubuntu-12.04 qt-5.1.1 2.sudo apt-get install libgl1-mesa-dev libglu1-mesa-dev 3.qmake 4.make 5.sud ...

  7. Redis PHP扩展安装步骤

    ### 下载最新的扩展文件,解压并进入文件夹 wget https://codeload.github.com/phpredis/phpredis/tar.gz/2.2.7 tar -zxvf 2.2 ...

  8. scws中文分词安装和使用

    一.下载源码 wget http://www.xunsearch.com/scws/down/scws-1.2.3.tar.bz2 tar xvjf scws-1.2.3.tar.bz2 二.执行配置 ...

  9. Eureka加了secsecurity后注册失败

    报错信息: com.netflix.discovery.shared.transport.TransportException: Cannot execute request on any known ...

  10. @codeforces - 668E@ Little Artem and 2-SAT

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定两个 2-sat 问题,询问两个问题的解集是否相同. 如果不 ...