前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SpringCloud 实战|SpringCloud 整合Sentinel-轻轻松松实现限流

SpringCloud 实战|SpringCloud 整合Sentinel-轻轻松松实现限流

作者头像
AI码师
发布2022-09-19 11:47:44
7071
发布2022-09-19 11:47:44
举报

引言

这一期主要是整合sentinel,实现流控、降级和授权功能

开整

引入依赖

在common-web子模块下添加sentinel相关依赖,使用nacos作为数据源,目的是为了能够让配置的规则能够持久化到nacos中。

代码语言:javascript
复制
        <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>

创建配置文件

创建默认阻塞异常处理器

只要实现BlockExceptionHandler 接口的handle方法就可以了. 这里主要对 降级、未授权、限流三种异常进行了处理

代码语言:javascript
复制
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;


/**
 * Created with IntelliJ IDEA.
 *
 * @author:AI码师 关注公众号"AI码师"获取完整源码
 * @date:2021/11/24
 * @description:
 * @modifiedBy:
 * @version: 1.0
 */
@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));
        }
    }
}

创建sentinel 来源解析器

这个主要是辅助sentinel 收取功能,如果配置了服务授权的话,则会回调这个配置,获取调用方来源。这里的处理逻辑是从请求头获取调用方名称

代码语言:javascript
复制
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;
/**
 * Created with IntelliJ IDEA.
 *
 * @author:AI码师 关注公众号"AI码师"获取完整源码
 * @date:2021/11/24
 * @description:
 * @modifiedBy:
 * @version: 1.0
 */
@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;
    }
}

创建网关过滤器

该过滤器用来在请求头中添加当前服务名称

代码语言:javascript
复制
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;

/**
 * Created with IntelliJ IDEA.
 *
 * @author:AI码师 关注公众号"AI码师"获取完整源码
 * @date:2021/11/24
 * @description:
 * @modifiedBy:
 * @version: 1.0
 */
@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;
    }
}

修改nacos配置

编辑 ams-admin,新增如下配置,注意sentinel面板地址要填写你自己的,nacos地址也要换成自己的nacos地址

代码语言:javascript
复制
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

创建限流规则配置文件

在nacos 新建一个 ams-admin-degrade-rules 配置

代码语言:javascript
复制
[
    {
        "resource": "/hello",
        "limitApp": "default",
        "grade": 1,
        "count": 5,
        "strategy": 0,
        "controlBehavior": 0,
        "clusterMode": false
    }
]

安装sentinel

推荐使用docker 安装,这里贴上docker安装sentinel的步骤

  • 拉取镜像
代码语言:javascript
复制
docker pull bladex/sentinel-dashboard
  • 运行镜像
代码语言:javascript
复制
docker run --name sentinel -d -p 8080:8858 -d bladex/sentinel-dashboard
  • 访问地址

http://localhost:8080 默认用户名/密码:sentinel/sentinel

启动 ams-admin、ams-auth 和ams-gateway 模块 再次访问sentinel面板,就会看到我们配置的限流规则

在这里插入图片描述

演示sentinel 基本功能

目前虽然说已经集成了nacos做规则持久化,但是不能将sentinel中手动添加的规则持久化到nacos中,这一块将在后面有专门的文章对这块进行补充,通过修改sentinel源码实现双向推送。

为我们先发起一个获取加密密码请求,生成调用链:

http://localhost:9999/ams-admin/passwd/genPasswd/ams

演示流控

  • 点击流控

在这里插入图片描述

  • 配置规则

在这里插入图片描述

  • 访问刚才的接口

在这里插入图片描述

  • 快速访问

会返回限流错误

演示授权

  • 点击授权

在这里插入图片描述

  • 设置规则

设置只允许ams-test 才能调用

  • 访问

http://localhost:9999/ams-admin/passwd/genPasswd/ams目前是通过网关转发调用的,调用方是ams-gateway,,所以不会通过授权

现在修改白名单为ams-gateway

  • 再次访问
  • 访问成功,通过授权

在这里插入图片描述

演示降级

  • 点击降级

在这里插入图片描述

  • 新建规则

在这里插入图片描述

  • 访问

在这里插入图片描述

  • 连续访问

在这里插入图片描述

总结

本节主要介绍了sentinel的安装,以及如何使用springcloud 整合 sentinel实现接口服务的流控、降级和授权功能,下一节将会介绍如何整seata,实现分布式事务,敬请期待吧。

关注公众号领取2021最新面试题一套和项目源码

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-12-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 乐哥聊编程 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 引言
  • 开整
    • 引入依赖
      • 创建配置文件
        • 创建默认阻塞异常处理器
        • 创建sentinel 来源解析器
        • 创建网关过滤器
      • 修改nacos配置
        • 创建限流规则配置文件
      • 安装sentinel
        • 演示sentinel 基本功能
          • 演示流控
          • 演示授权
          • 演示降级
      • 总结
      相关产品与服务
      对象存储
      对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档