服务熔断 服务降级 解决 服务雪崩 以及流控规则

熔断

熔断含义:

        在互联网系统中,当下游服务因访问压力过大而响应变慢或失败,上游服务为了保护系统整 体的可用性,可以暂时切断对下游服务的调用。这种牺牲局部,保全整体的措施就叫做熔断。

目的:

         防止服务雪崩

如何实现的熔断:

        熔断存在的基础服务之间的调用使用的组件是openfeign

调用的时候下游的服务如果响应慢或者服务宕机 熔断:

@FeignClient(fallback=””)

直接走的是fallback中的代码 不再去访问下游  牺牲局部保整体

Openfeign支持熔断,记得开启  在 qpplication.preperties

Sentinel的概念和功能

基本概念

资源

资源就是Sentinel要保护的东西

资源是 Sentinel 的关键概念。它可以是 Java 应用程序中的任何内容,可以是一个服务,也可以是

一个方法,甚至可以是一段代码。

| 我们入门案例中的message方法就可以认为是一个资源

规则

规则就是用来定义如何进行保护资源的

作用在资源之上, 定义以什么样的方式保护资源,主要包括流量控制规则、熔断降级规则以及系统

保护规则。

Sentinel的主要功能

Sentinel的主要功能就是容错,主要体现为下面这三个:

流量控制

流量控制在网络传输中是一个常用的概念,它用于调整网络包的数据。任意时间到来的请求往往是随机不可控的,而系统的处理能力是有限的。我们需要根据系统的处理能力对流量进行控制。Sentinel 作为一个调配器,可以根据需要把随机的请求调整成合适的形状。

熔断降级

当检测到调用链路中某个资源出现不稳定的表现,例如请求响应时间长或异常比例升高的时候,则对这个资源的调用进行限制,让请求快速失败,避免影响到其它的资源而导致级联故障。Sentinel 对这个问题采取了两种手段:

l 通过并发线程数进行限制

Sentinel 通过限制资源并发线程的数量,来减少不稳定资源对其它资源的影响。当某个资源出现不稳定的情况下,例如响应时间变长,对资源的直接影响就是会造成线程数的逐步堆积。当线程数在特定资源上堆积到一定的数量之后,对该资源的新请求就会被拒绝。堆积的线程完成任务后才开始继续接收请求。

l 通过响应时间对资源进行降级

除了对并发线程数进行控制以外,Sentinel 还可以通过响应时间来快速降级不稳定的资源。当依赖的资源出现响应时间过长后,所有对该资源的访问都会被直接拒绝,直到过了指定的时间窗口之后才重新恢复。

系统负载保护

Sentinel 同时提供系统维度的自适应保护能力。当系统负载较高的时候,如果还持续让请求进入可能会导致系统崩溃,无法响应。在集群环境下,会把本应这台机器承载的流量转发到其它的机器上去。如果这个时候其它的机器也处在一个边缘状态的时候,Sentinel 提供了对应的保护机制,让系统的入口流量和系统的负载达到一个平衡,保证系统在能力范围之内处理最多的请求。

总之一句话: 我们需要做的事情,就是在Sentinel的资源上配置各种各样的规则,来实现各种容错的功能。

使用 Sentinel

Sentinel 是一个 容错组件 

地址: https://github.com/alibaba/Sentinel/wiki/%E4%BB%8B%E7%BB%8D

1 下载jar包,解压到文件夹

https://github.com/alibaba/Sentinel/releases/tag/1.8.1

2 启动控制台

# 直接使用jar命令启动项目(控制台本身是一个SpringBoot项目)

使用 8080 启动    java -jar sentinel-dashboard-1.8.1.jar

使用 8080 启动    ( 默认用户名密码是 sentinel/sentinel )

使用 8888 启动     java -Dserver.port=8888 -Dcsp.sentinel.dashboard.server=localhost:8888 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.1.jar

使用 8888 启动

3 修改 product ,在里面加入有关控制台的配置

# 该端口号为sentinal于服务之间的交互 随便写只要不被占用
spring.cloud.sentinel.transport.port=9999

#sentinal服务所在的地址和端口号
spring.cloud.sentinel.transport.dashboard=localhost:8080

#端口号也可以写  8888

然后访问 微服务项目  接着访问  sentinel客户端

进行流量控制  流控规则

资源名为:

资源名:唯一名称,默认是请求路径,可自定义

针对来源:指定对哪个微服务进行限流,默认指default,意思是不区分来源,全部限制

阈值类型/单机阈值

l QPS(每秒请求数量): 当调用该接口的QPS达到阈值的时候,进行限流

l 线程数:当调用该接口的线程数达到阈值的时候,进行限流

更改访问路径

设置阈值类型为QPS,单机阈值为2。即每秒请求量大于2的时候开始限流

然后快速访问接口,观察效果。此时发现,当QPS > 2的时候,服务就不能正常响应,而是返回Blocked by Sentinel (flow limiting)结果。

自定义限流的一个异常响应   

前后端分离的时候要   给前端一个响应  放到一个固定的  实现类  固定格式的响应

package com.aaa.exception;

import com.aaa.util.Result;
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.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowException;
import com.alibaba.csp.sentinel.slots.system.SystemBlockException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;

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

//  注入到对应的容器里面   通用的注解
// 代表把当前的一个类 作为 Bean 注入到 Spring 容器 里边
@Component
public class MyExceptionHandler implements BlockExceptionHandler {

    @Resource
    private ObjectMapper objectMapper;


    @Override
    public void handle(HttpServletRequest httpServletRequest, HttpServletResponse response, BlockException e) throws Exception {
        Result r = null;


        if (e instanceof FlowException) {
            r = new Result(100, "限流了", "");


        }


        //返回json数据
        response.setStatus(500);   //  http 的状态码
        response.setCharacterEncoding("utf-8");
        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
        //  new ObjectMapper().writeValue(response.getWriter(), r);
        // 把  ObjectMapper()   当做 Bean  注入  以后使用可直接  @Resource  引入
        // @Resource
        //  private ObjectMapper objectMapper;
        objectMapper.writeValue(response.getWriter(), r);
        // response.getWriter();
    }
}

完全版本的异常响应固定的  实现类 

@Component

public class MyExceptionHandler implements BlockExceptionHandler {

@Override

public void handle(HttpServletRequest httpServletRequest, HttpServletResponse response, BlockException e) throws Exception {

Result r = null;

if (e instanceof FlowException) {

r =new Result(100,"限流了","");

} else if (e instanceof DegradeException) {

r =r =new Result(101,"服务降级了");

} else if (e instanceof ParamFlowException) {

r =new Result(102,"热点参数限流了");

} else if (e instanceof SystemBlockException) {

r = new Result(103,"触发系统保护规则了");

} else if (e instanceof AuthorityException) {

r = new Result(104,"授权规则不通过");

}

//返回json数据

response.setStatus(500);

response.setCharacterEncoding("utf-8");

response.setContentType(MediaType.APPLICATION_JSON_VALUE);

new ObjectMapper().writeValue(response.getWriter(), r);

}

}

sentinel共有三种流控模式,分别是:

l 直接(默认):接口达到限流条件时,开启限流

l 关联:当关联的资源达到限流条件时,开启限流 [适合做应用让步]

l 链路:当从某个接口过来的资源达到限流条件时,开启限流

直接

就是默认的模式,上边写的方式

关联

链路流控模式

链路流控模式

链路流控模式指的是,当从某个接口过来的资源达到限流条件时,开启限流

注解:@SentinelResource

我们可以对某一个方法进行限流控制,无论是谁在何处调用了它,这里需要使用到@SentinelResource,一旦方法被标注,那么就会进行监控@SentinelResource,一旦方法被标注,那么就会进行监控。

第1步: 编写一个service,在里面添加一个方法message

@Service
public class ProductService {
        @SentinelResource("message")
        public void message(){
            System.out.println("hello====message!!!");
        }
}

第2步: 在Controller中声明两个方法,分别调用service中的方法message

@RestController
public class MessageController {
   
    @Resource
    private ProductService service;

    @GetMapping("message1")
    public String message1(){
        service.message();
        return "message1";
    }
    @GetMapping("message2")
    public String message2(){
        service.message();
        return "message2";
    }
}


第3步: 禁止收敛URL的入口 context

在application.properties中添加:

spring.cloud.sentinel.web-context-unify=false

#用于控制是否收敛context。将其配置为 false 即可根据不同的URL 进行链路限流。

第4步: 控制台配置限流规则

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

机械能实验

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值