SpringCloud-Nacos+Sentinel+Feign

SpringCloud-Nacos+Sentinel+Feign

  • 高并发
    • 问题
    • 解决方案
  • 面向失败编程-容错方案
  • Sentinel
    • 核心概念
    • 配置
    • 流量控制
    • 两种规则
    • 流量控制效果
    • 熔断策略
    • 熔断状态
  • Alibaba Cloud升级
    • 异常种类
  • Feign+Sentinel

高并发

问题

多个服务之间相互依赖,可能会导致系统负载过高,突发流量或网络异常等情况,导致服务不可用。

解决方案

面向失败编程:

  1. 不被外界影响
  2. 不被请求拖垮
    2.1 上游服务
    2.2 下游服务

面向失败编程-容错方案

  1. 限流
  2. 漏斗,不管流量多大,均匀的流入容器,令牌桶算法,漏桶算法
  3. 熔断
  4. 降级
  5. 隔离

Sentinel

  1. 以流量为切入点,从流量控制,熔断降级,负载均衡保护等多个维度保护服务的稳定性
  2. 消息削峰填谷、集群流量控制、实时熔断下游不可用应用
  3. 完备的实时监控,Sentinel提供实时的监控功能
  4. 与SpringCloud、Dubbo、gRPC整个

核心概念

  1. 资源:可以是服务或方法甚至代码
  2. 规则:定义什么样的方式保护资源,主要包括流控规则,熔断降级规则等
    SpringCloud-Nacos+Sentinel+Feign_第1张图片

配置

spring:
	cloud:
		sentinel:
			transport:
				dashboard: 127.0.0.1:8080
				port: 9999

微服务注册上去后,由于Sentinel是懒加载模式,所以需要访问微服务后才会在控制台出现。

流量控制

监控应用流量的QPS或并发线程数等指标,当达到指定的阈值时对流量进行控制,以避免被瞬间的流量高峰冲垮。

两种规则

  1. 基于统计并发线程数的流量控制
    并发数控制用于保护业务线程池不被耗尽,Sentinel并发控制线程数不负责创建和管理线程池,只是简单的统计当前请求上下文的线程数目(正在执行的调用数目),如果超出阈值,新的请求就会被立即拒绝,相当于信号量隔离。
  2. 基于流量QPS的流量控制
    当QPS超过某个阈值的时候,则采取控制流量

流控规则会下发到微服务,微服务如果重启,则流控规则会消失可以持久化配置

流量控制效果

  1. 直接拒绝:默认的流控方式,新请求会被直接拒绝
  2. Warm up:预热,如果系统在此之前长期处于空闲的状态,希望处理请求的数量缓步的增长,经过预期的时间之后,到底系统处理请求个数的最大值
  3. 匀速排队,严格控制请求通过的间隔时间,也即是让请求以均匀的速度通过,对应的是漏漏桶算法,主要用于处理理间隔性突发的流量量,如消息队列,想象一下这样的场景,在某一秒有大量量的请求到来,接下来的几秒则处于空闲状态,我们希望系统能够在接下来的空闲期间逐渐处理理这些请求,而不是在第一秒直接拒绝多余的请求
    3.1 匀速排队等待策略略是 Leaky Bucket 算法结合虚拟队列列等待机制实现的
    3.2 匀速排队模式暂时不不⽀支持 QPS > 1000 的场景

流控一般在单机内做限制

熔断策略

  1. 响应时):选择以响应时间作为阈值,需要设置最大允许的响应时间,请求的响应时间大于该值则统计为慢调用。
    1.1 阈值:修改后不生效,bug
    1.2 熔断时长:超过时间后会尝试修复
    1.3 最小请求数:熔断触发的最小请求数,小于该值时即使异常比例超出阈值也不会熔断
    1.4 异常比例:当单位时间内请求数目大于设置的最小请求数,并且异常比例大于阈值,则接下来的熔断时长内请求会自动被熔断
    1.5 异常数:当单位时间内请求的异常数超过阈值会自动被熔断

熔断状态

  1. 熔断关闭:服务没有故障时,对调用方的调用不做限制
  2. 熔断开启:后续对该服务接口的调用不再经过网络,直接执行本地的fallback方法
  3. 半熔断:尝试恢复服务调用,允许有限的流量调用该服务,并监控调用成功率

Alibaba Cloud升级

v2.1.0到v2.2.0后,Sentinel里面依赖进行了改动,不向下兼容

异常种类

  1. FlowException
  2. DegradeException
  3. ParamFlowException
  4. SystemBlockException
  5. AuthorityException
package com.example.demo.config;

@Component
public class MyBlockHandler implements BlockExceptionHandler {
    @Override
    public void handle(HttpServletRequest
                               httpServletRequest, HttpServletResponse
                               httpServletResponse, BlockException e) throws
            IOException {
        Map<String, Object> backMap = new HashMap<>();
        if (e instanceof FlowException) {
            backMap.put("code", -1);
        } else if (e instanceof
                DegradeException) {
            backMap.put("code", -2);
        } else if (e instanceof
                ParamFlowException) {
            backMap.put("code", -3);
        } else if (e instanceof
                SystemBlockException) {
            backMap.put("code", -4);
        } else if (e instanceof
                AuthorityException) {
            backMap.put("code", -5);
        }
        httpServletResponse.setStatus(200);
        httpServletResponse.setHeader("content-Type", " application / json; charset = UTF - 8 ");
        httpServletResponse.getWriter().write(JSON.toJSONString(backMap));
    }
}

Feign+Sentinel

feign:
	sentinel:
		enabled: true
@FeignClient(value = "xx-service",
fallback = XXServiceFallback.class)

你可能感兴趣的:(Nacos)