首页 > 其他分享 >Sentinel 对分布式服务进行流量控制

Sentinel 对分布式服务进行流量控制

时间:2024-03-29 11:14:46浏览次数:24  
标签:服务 请求 阈值 流量 分布式服务 限流 Sentinel public

可以下载sentinel的jar包,用java -jar命令直接启动

 默认端口就是8080,这里随便写一下演示,其他修改还是直接看Sentinel网站吧

java -jar -Dserver.port=8080 sentinel的jar包名.jar

 

对需要进行流量控制的服务进行依赖导入(这个依赖直接在父工程引入似乎无效,不知为何)

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

配置application.yml

spring:
  cloud:
    sentinel:
      transport:
        dashboard: localhost:8088 #sentinel控制台地址

 

提示:可以用jmeter模拟请求测试。

流控模式

我们可以直接在sentinel的控制台对每个簇点链路添加限流规则,sentinel有三种流控模式可以选择:

1、直接:统计当前资源的请求,出发阈值时对当前资源直接限流,默认是该模式

2、关联:统计与当前资源相关的另一个资源,当关联资源触发阈值时,对当前资源限流

3、链路:统计从指定链路访问到本资源的请求,触发阈值时,对指定链路限流(也就是指定某个方法每秒调用本方法的次数,如果超过阈值,就限制那个方法的调用请求)

Sentinel默认只标记Controller中的方法为资源,如果想标记其他方法,需要在方法上加上@SentinelResource("取一个资源名")注解

另外,Sentinel默认会将Controller方法做context整合,这会导致所有Conrtoller方法都为同一个父链路的子链路,这样一来链路模式将会失效,所以我们需要给application.yml配置文件添加配置来取消整合

spring:
  cloud:
    sentinel:
      web-context-unify: false

 

流控效果

1、快速失败:QPS(每秒请求数)超过阈值时,拒绝新的请求

2、warm up:QPS超过阈值时,拒绝新的请求;QPS阈值是逐渐提升的,可以避免冷启动时的高并发导致服务宕机

3、排队等待:所有请求都会进入队列,然后按照设定好的阈值依次执行请求。如果请求预期等待时间大于超时时间,则直接拒绝

 

热点参数限流

有时候,对于同一个资源,我们不能对所有请求采取同样的阈值限流。可能因为参数值的不同,我们也需要设定不同的阈值。

例如商品的查询功能,对不同商品,热门商品的阈值理论上应该比普通商品更高。所以我们需要热点参数限流。

注意:热点参数限流对默认的SpringMVC资源无效。用人话来说就是,类似于/order/{orderId}这种自动从Controller中识别的资源名无法设置热点参数限流,我们需要在Controller方法中手动添加@SentinelResource("取一个资源名")注解,使用这种手动添加的资源名才能对该方法进行热点参数限流

 

线程隔离和熔断降级

线程隔离:服务A需要去调用服务B和服务C,那么服务A会给调用服务B和服务C的请求专门划分固定的线程数,这样假如服务B故障了,我们可以只损耗留给服务B的线程,而不会影响服务C。

熔断降级:当服务A去访问服务B时,统计失败次数(如何算失败看具体怎么设定),如果失败比例过高,则后续会直接拒绝服务B的访问。

 

简单使用Feign

我们在SpringCloud中,使用的是Feigh进行服务之间的调用,而且Feigh支持Sentinel功能。所以我们只需要将Feigh和Sentinel进行整合即可。

此处我们将Feigh单独做了一个子工程,然后让其他项目调用他。

先对使用Feigh的项目的application.yml进行配置

feign:
  sentinel:
    enabled: true #开启feigh对sentinel的支持

 

接下来对Feigh项目模块做配置

实现FallbackFactory接口,UserClients为书写远程调用的接口

用匿名内部类实现UserClients接口,书写我们的降级方法,我们采用直接返回一个空的对象

@Slf4j
public class UserClientFallbackFactory implements FallbackFactory<UserClients> {
    @Override
    public UserClients create(Throwable throwable) {
        return new UserClients() {
            @Override
            public User findById(Long id) {
                log.error("查询用户异常",throwable);
                return new User();
            }
        };
    }
}

将实现好的接口类注册为Bean

public class DefaultFeignConfiguration {
    @Bean
    public UserClientFallbackFactory userClientFallbackFactory(){
        return new UserClientFallbackFactory();
    }

}

//已经在使用Feign模块的项目的启动类中配置了该类为默认配置类
//@EnableFeignClients(clients = UserClients.class,defaultConfiguration = DefaultFeignConfiguration.class)

在接口中使用UserClientFallbackFactory

@FeignClient(value = "userservice", fallbackFactory = UserClientFallbackFactory.class)
public interface UserClients {

    @GetMapping("/user/{id}")
    User findById(@PathVariable("id") Long id);
}

线程隔离

接下来就能在Sentinel控制台看见GET:http://userservice/user/{id}这种资源名

然后在Sentinel中对该资源进行流量控制,流控选择线程数就可设定为线程隔离

熔断降级

直接在Sentinel控制台中的簇点链路中点击降级操作设置即可

熔断策略有三种:

1、慢调用比例。每次请求超过指定时长则视为慢调用,统计时长内慢调用比例超过限定值,熔断

2、异常比例。统计时长内异常比例超过限定值,熔断

3、异常数。统计时长内异常调用次数超过限定值,熔断

 

授权规则

为了服务的安全,我们一般会设置网关服务,由网关对请求进行处理,筛选,然后再向对应服务发起请求。但网关并不能限制用户直接去访问服务的IP地址,如果服务的IP一旦泄露,网关的作用就消失了。所以,为了确保所有请求一定要经过网关,将未经过网关的请求全部拒绝访问,我们可以使用Sentinel的授权规则。

 

我们需要在进行服务的项目中,实现RequestOriginParser接口。这样当有请求访问该服务时,该方法会向Sentinel传入一个参数,根据该参数是否 处于白名单/不处于黑名单 来判断是否允许访问该服务

@Component
public class HeaderOriginParser implements RequestOriginParser {
    @Override
    public String parseOrigin(HttpServletRequest httpServletRequest) {
        String origin = httpServletRequest.getHeader("origin");
        if (StringUtils.isEmpty(origin)){
            origin="empty";
        }
        return origin;
    }
}

可以在网关的application.yml添加如下配置,将网关的所有路由都添加默认的请求头,可以看Gateway实现统一网关

我们此处添加了Key为origin,Value为gateway的请求头。上述实现的RequestOriginParser接口中获取了Value,由于Value值是上述图中的白名单,所以网关发出的请求通过授权。

spring:
  cloud:
    gateway:
      default-filters:
        - AddRequestHeader=origin,gateway

 

自定义异常结果

当我们使用Sentinel进行流量控制的时候,如果Sentinel拒绝了访问,返回的消息都是一样的,这样对前端非常不友好,我们可以实现BlockExceptionHandler接口,来辨别异常信息,并对异常进行处理

@Component
public class SentinelExceptionHeadler implements BlockExceptionHandler {

    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception {
        String msg = "未知异常";
        int status = 429;

        if (e instanceof FlowException){
            msg = "请求被限流了";
        } else if (e instanceof ParamFlowException) {
            msg = "请求被热点参数限流";
        } else if (e instanceof DegradeException) {
            msg = "请求被降级了";
        } else if (e instanceof AuthorityException) {
            msg = "没有访问权限";
            status = 401;
        }
        response.setContentType("application/json;charset=utf-8");
        response.setStatus(status);
        response.getWriter().println("msg:"+msg+",status:"+status);

    }
}

 

规则持久化

Sentinel的规则默认是存在内存中的,所以每次重启服务,都会导致规则消失。所以我们需要对规则进行持久化。最好的是将持久化规则写在nacos等微服务的远程配置中心里,不过这需要去修改Sentinel的源码,具体网上查吧。

标签:服务,请求,阈值,流量,分布式服务,限流,Sentinel,public
From: https://www.cnblogs.com/cyknote/p/18098007

相关文章

  • 用docker创建nginx反向代理tcp流量
    有这样一个需求,需要反向代理一个tcp连接,我打算用nginx来做,比较简单的实现掉./conf/nginx.conf配置文件usernginx;worker_processesauto;error_log/var/log/nginx/error.lognotice;pid/var/run/nginx.pid;events{worker_connections1024;}......
  • 带流量主功能的外卖菜谱小程序源码:助你轻松领取优惠券,个人使用也可通过审查
    外卖菜谱小程序源码-带流量主功能-外卖领劵个人也可过审这套小程序优点就带很多菜谱,各种你爱吃菜的做法与各类食材介绍营养搭配,相信很多小姐姐会感兴趣。宝妈宝爸这个小程序肯定能留的住这个群体的人脉流量,这是小程序最大的亮点;其它功能也没有什么对接外卖劵加个流量主。源......
  • 面试必问流量控制
    问题:如果发送方一直保持很快的速度发送数据,容易导致接收方处理不过来,触发重传机制,导致流量浪费;解决方法:接收方根据自己剩余缓冲区的大小,通过TCP首部中的16位窗口大小字段,告诉发送方自己最多还能接收多少个字节的数据,发送方就知道自己当前阶段最多可以给接收方发送多少个字......
  • 无忧微服务:如何实现大流量下新版本的发布自由
    作者:项良、十眠微服务上云门槛降低,用好微服务才是关键据调研数据显示,约70%的生产故障是由变更引起的。在阿里云上的企业应用如茶百道、极氪汽车和来电等,他们是如何解决变更引起的稳定性风险,实现了在白天高流量情况下应用发布平滑无损。今天我们将揭开阿里云微服务全链路无损发......
  • 【逆向】利用Objection实现移动应用抓取https流量
    那女孩对我说说我保护她的梦说这个世界对她这样的不多她渐渐忘了我但是她并不晓得遍体鳞伤的我一天也没再爱过                     ......
  • 数据链路层(三):流量控制和链路管理
    目录1流量控制和链路管理1.1流量控制介绍1、什么是流量控制2、流量控制的功能和方法1.2停止等待1.3滑动窗口1、滑动窗口2、发送方滑动窗口3、接收方滑动窗口4、滑动窗口的流量控制使用滑动窗口如何实现流量控制的为什么滑动窗口的大小比模数小1滑动窗口控制流量采取......
  • 海量数据处理项目-账号微服务和流量包数据库表+索引规范(下)
    海量数据处理项目-账号微服务和流量包数据库表+索引规范(下)第2集账号微服务和流量包数据库表+索引规范讲解《下》简介:账号微服务和流量包数据库表+索引规范讲解账号和流量包的关系:一对多traffic流量包表思考点海量数据下每天免费次数怎么更新?海量数据付费流量套餐包每天......
  • Windows 防火墙中设置规则以拒绝所有流量,但允许特定 IP 通过
    在Windows防火墙中设置规则以拒绝所有流量,但允许特定IP通过,可以通过以下步骤进行设置:打开控制面板:点击“开始”按钮,然后输入“控制面板”并按回车键。打开WindowsDefender防火墙:在控制面板中,找到并点击“系统和安全”>“WindowsDefender防火墙”。设置......
  • sql盲注流量
    先使用http协议过滤,发现很多get方法中存在sql注入语句随便点击一个,对其语句进行url解码发现黑客是在猜解flag表的keyid字段,大概率flag就是keyid的值盲注的区别就是返回包的不同状态失败会返回nothing,并且返回包的长度是661,成功会返回文章内容,长度是695之后写脚本: 1impo......
  • sentinel中StatisticSlot数据采集的原理
    StatisticSlot数据采集的原理时间窗口固定窗口在固定的时间窗口内,可以允许固定数量的请求进入;超过数量就拒绝或者排队,等下一个时间段进入,如下图时间窗长度划分为1秒单个时间窗的请求阈值为3上述存在一个问题,假如9:18:04:333-9:18:05:000产生了2个请求,9:18:0......