微服务架构师成长之路(七)Sentinel

服务保护框架Sentinel

其实这个Sentinel应该放在网关直接来讲,这样的大家容易理解。学习过上节课的小伙伴肯定是对网关有了一定的了解,那肯定就会有疑问了,说上节课不是才说gateway+nginx对服务进行保护嘛,怎么又多出来一个保护框架,别急,我们继续往更深处去谈谈。举个例子,我们的公司有秒杀的业务,到特定时间端会有很多请求一起去请求秒杀接口,这就导致了服务器承载的压力过大,可能会导致接口的崩溃,严重点还可能导致服务的雪崩,即其他接口的线程被迫过来支援,导致各自的接口也出现了错误。这个时候,我们就需要sentinel去统一管理我们的接口。

运行Sentinel

1.去官网下载Sentinel的jar包 https://github.com/alibaba/Sentinel
2.打开cmd窗口,输入 java -Dserver.port=8718 -Dcsp.sentinel.dashboard.server=localhost:8718 -Dproject.name=sentinel-dashboard -Dcsp.sentinel.api.port=8719 –jar 命令运行jar包。这里做个简单的说明,8718指的是控制台的端口,8719指的是sentinel内部通讯端口,-jar后面直接拖上下载后的jar包。
微服务架构师成长之路(七)Sentinel_第1张图片
3.Springboot整合Sentinel


    org.springframework.cloud
    spring-cloud-alibaba-sentinel
    0.2.2.RELEASE


    org.springframework.boot
    spring-boot-starter-actuator

sentinel:
  transport:
    dashboard: 127.0.0.1:8718
  eager: true
//限流走的方法需要于限流方法参数保持一致
public String getOrderQpsException(BlockException e) {
    e.printStackTrace();
    return "该接口已经被限流啦!";
}

//该注解表示开启接口限流,value表示资源名称, blockHandler表示限流走的方法
@SentinelResource(value = "getOrderDashboard", blockHandler = "getOrderQpsException")
@RequestMapping("/getOrderDashboard")
public String getOrderDashboard() {
    return "getOrderDashboard";
}

4.访问127.0.0.1:8718访问sentinel控制台,找到对应的服务名称,点击流控规则
微服务架构师成长之路(七)Sentinel_第2张图片
新建流控规则(资源名称表示的是你代码中自定义的名称,qps表示每秒访问次数,这里为1次)
微服务架构师成长之路(七)Sentinel_第3张图片
5.降级规则(平均响应时间,异常个数)注意:降级和熔断一般是一个意思,是接口出现了异常
而采取的保护措施。限流是因为流量过大而采取的保护措施。
微服务架构师成长之路(七)Sentinel_第4张图片
6.热点规则(比如说我们秒杀中只允许一个手机号抢购一次,那么这个是一定要去配置的)
微服务架构师成长之路(七)Sentinel_第5张图片

Sentinel持久化

通过上面的学习,相信大家对Sentinel有了基本的了解,但是有个问题,就是如果说你重启了项目,那么你之前定义过的一些规则是会丢失,显然我们需要对Sentinel进行持久化,这里选用nacos。我们在nacos上新建一个配置文件,配置格式设为JSon,这里做个简单的说明。

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

[
    {
        "resource": "/ getOrderSentinel",
        "limitApp": "default",
        "grade": 1,
        "count": 5,
        "strategy": 0,
        "controlBehavior": 0,
        "clusterMode": false
    }
]


    com.alibaba.csp
    sentinel-datasource-nacos
    1.5.2

sentinel:
  transport:
    dashboard: 127.0.0.1:8718
  eager: true
  datasource:
    ds:
      nacos:
        ### nacos连接地址
        server-addr: localhost:8848
        ## nacos连接的分组
        group-id: DEFAULT_GROUP
        ###路由存储规则
        rule-type: flow
        ### 读取配置文件的 data-id
        data-id:order-sentinel
        ###  读取培训文件类型为json
        data-type: json

GateWay整合Sentinel

哈哈,终于到了大家万众瞩目的环节了。通过上面的学习我们可以看到,如果说我现在有100个接口需要做限流的保护,难道我写100个注解吗,配置100个流控规则吗,很显然这种做法属实太low,所以我们需要在统一请求如果做资源的限流或者是熔断的操作。

		
            org.springframework.cloud
            spring-cloud-starter-gateway
            2.0.0.RELEASE
        
        
            com.alibaba.csp
            sentinel-spring-cloud-gateway-adapter
            1.6.0
        
@Configuration
public class GatewayConfiguration {

    private final List viewResolvers;
    private final ServerCodecConfigurer serverCodecConfigurer;

    public GatewayConfiguration(ObjectProvider> 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(Ordered.HIGHEST_PRECEDENCE)
    public GlobalFilter sentinelGatewayFilter() {
        return new SentinelGatewayFilter();
    }
}
//加载流控规则
@Slf4j
@Component
public class SentinelApplicationRunner implements ApplicationRunner {

    @Override
    public void run(ApplicationArguments args) throws Exception {
        initGatewayRules();

    }

    /**
     * 配置限流规则
     */
    private void initGatewayRules() {
        Set rules = new HashSet<>();
        //网关中配置的路由策略
        rules.add(new GatewayFlowRule("app")
                // 限流阈值
                .setCount(1)
                // 统计时间窗口,单位是秒,默认是 1 秒
                .setIntervalSec(1)
        );
        GatewayRuleManager.loadRules(rules);
    }
}
//修改限流的代码提示,给客户端友好的返回数据
public class JsonSentinelGatewayBlockExceptionHandler implements WebExceptionHandler {
    public JsonSentinelGatewayBlockExceptionHandler(List viewResolvers, ServerCodecConfigurer serverCodecConfigurer) {
    }

    @Override
    public Mono handle(ServerWebExchange exchange, Throwable ex) {
        ServerHttpResponse serverHttpResponse = exchange.getResponse();
        serverHttpResponse.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
        byte[] datas = "{\"code\":403,\"msg\":\"API接口被限流\"}".getBytes(StandardCharsets.UTF_8);
        DataBuffer buffer = serverHttpResponse.bufferFactory().wrap(datas);
        return serverHttpResponse.writeWith(Mono.just(buffer));
    }
}


@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public JsonSentinelGatewayBlockExceptionHandler sentinelGatewayBlockExceptionHandler() {
    // Register the block exception handler for Spring Cloud Gateway.
    return new JsonSentinelGatewayBlockExceptionHandler(viewResolvers, serverCodecConfigurer);
}

Sentinel总结

随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。

Sentinel 具有以下特征:

丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
完备的实时监控:Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。
广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。
完善的 SPI 扩展点:Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。

你可能感兴趣的:(微服务架构师成长之路(七)Sentinel)