SpringCloud之Sentinel

思维导图


SpringCloud之Sentinel_第1张图片


1.概述

1.1 概念

分布式服务架构的流量治理组件。

1.2 Sentinel有什么作用?

  1. 流控:QPS、线程数

  2. 熔断降级:降级–>熔断策略、时长、请求数等

  3. 授权:黑白名单

  4. 系统自适应过载保护
    提供保护机制让系统入口流量与负载达到平衡,使得系统在尽可能处理最多的请求

  5. 热点流量防护

2.Sentinel如何应用于项目中?

2.1 引入sentinel及持久化到nacos依赖

<dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
                <!-- Sentinel规则持久化至Nacos配置 -->
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-datasource-nacos</artifactId>
        </dependency>

2.2 配置

2.2.1 sentinel及nacos

spring:
  cloud:
    sentinel:
      enabled: true
      eager: true # 取消控制台懒加载,项目启动即连接Sentinel
      transport:
        client-ip: localhost
        dashboard: localhost:8080
      datasource:
        ds:
          nacos:
            server-addr: http://cloud.lebao.site:8848
            dataId: ams-admin-degrade-rules
            groupId: DEFAULT_GROUP
            data-type: json
            rule-type: flow

2.2.2 在nacos创建限流规则配置文件:

ams-admin-degrade-rules

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

2.3 添加sentinel公共模块

2.3.1 创建网关过滤器PortalFilter

package com.ams.gateway.security;

import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * @description:请求头中添加当前服务名称
 */
@Component
@Slf4j
@RequiredArgsConstructor
public class PortalFilter implements GlobalFilter, Ordered {

    @Value("${spring.application.name}")
    private String applicationName;

    @SneakyThrows
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        ServerHttpRequest request = exchange.getRequest().mutate()
                .header("serviceName", applicationName)
                .build();
        exchange = exchange.mutate().request(request).build();
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return -1;
    }
}

2.3.2 创建sentinel来源解析器RequestOriginParserDefinition

package com.ams.common.web.sentinel;

import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.RequestOriginParser;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
/**
 * @description:通过HttpServletRequest获取服务名
 */
@Component
public class RequestOriginParserDefinition implements RequestOriginParser {
    // 获取调用方标识信息并返回
    @Override
    public String parseOrigin(HttpServletRequest request) {
        String serviceName = request.getHeader("serviceName");
        StringBuffer url = request.getRequestURL();
        if (url.toString().endsWith("favicon.ico")) {
            // 浏览器会向后台请求favicon.ico图标
            return serviceName;
        }
 
        if (StringUtils.isEmpty(serviceName)) {
            throw new IllegalArgumentException("serviceName must not be null");
        }
 
        return serviceName;
    }
}

2.3.3 创建BlockExceptionHandler 阻塞异常处理器


package com.ams.common.web.sentinel;

import cn.hutool.http.HttpStatus;
import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.BlockExceptionHandler;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityException;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException;
import com.alibaba.csp.sentinel.slots.block.flow.FlowException;
import com.ams.common.result.R;
import com.ams.common.result.ResultCode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


/**
 * @description:捕获流控、降级、未授权异常
 */
@Component
public class DefaultBlockExceptionHandler implements BlockExceptionHandler {

    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception {
        response.setStatus(HttpStatus.HTTP_OK);
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json;charset=utf-8");

        ObjectMapper objectMapper = new ObjectMapper();

        // 流控
        if (e instanceof FlowException) {
            objectMapper.writeValue(response.getWriter(), R.failed(ResultCode.FLOW_LIMITING));
            // 降级
        } else if (e instanceof DegradeException) {
            objectMapper.writeValue(response.getWriter(), R.failed(ResultCode.DEGRADATION));
            // 未授权
        } else if (e instanceof AuthorityException) {
            objectMapper.writeValue(response.getWriter(), R.failed(ResultCode.SERVICE_NO_AUTHORITY));
        }
    }
}

3.Sentinel控制面板

下载安装sentinel面板添加设置流程、降级、授权规则等

3.1 流控


SpringCloud之Sentinel_第2张图片

配置规则:
SpringCloud之Sentinel_第3张图片

3.2 降级


SpringCloud之Sentinel_第4张图片


新建规则:

SpringCloud之Sentinel_第5张图片


3.3 授权

SpringCloud之Sentinel_第6张图片


设置规则:
SpringCloud之Sentinel_第7张图片


本文主要文章链接如下:
SpringCloud 实战|7.SpringCloud 整合Sentinel-轻轻松松实现限流


4.Sentinel插槽工作原理

关于插槽详细介绍: https://zhuanlan.zhihu.com/p/64786381






随心所往,看见未来。Follow your heart,see light!

欢迎点赞、关注、留言,收藏及转发,一起学习、交流!

你可能感兴趣的:(后端Java,开发学习拓展,微服务SpringCloud,sentinel,java,spring,cloud,微服务,负载均衡)