博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
用SpringCloud Alibaba搭建属于自己的微服务(十九)~基础搭建~alibaba sentinel熔断
阅读量:4205 次
发布时间:2019-05-26

本文共 10508 字,大约阅读时间需要 35 分钟。

一.概述

熔断:当满足某个特定条件的时候,触发熔断,在熔断的时间内,接收到的请求将不会得到处理,而是快速失败响应给客户端.

sentinel提供了熔断功能,且熔断策略有三种:RT、异常比例和异常数量.

二.sentinel的熔断

1.sentinel的熔断策略.

熔断策略 含义
RT 平均响应时间超出阈值且在时间窗口内通过的请求数量>=5,两个条件同时满足后触发降级,窗口期过后关闭断路器
异常比例(秒级统计比例) qps>=5且异常比例(秒级统计)超过阈值时,触发断路器;时间窗口结束后,关闭断路器
异常数 异常数超过阈值时,触发断路器;时间窗口结束后,关闭断路器

2.sentinel熔断之控制台.

降级规则tab提供的就是熔断功能,只是sentinel文字描述个人觉得不是非常准确,只能说sentinel为自己的熔断功能也提供了降级功能,主功能在熔断.

在这里插入图片描述

3.sentinl熔断之RT策略.

(1).测试代码编写.

package com.ccm.server.user.controller;import com.ccm.common.exception.result.ResultSet;import io.swagger.annotations.Api;import io.swagger.annotations.ApiOperation;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;/** *  @Description sentinel熔断测试控制层 *  @Author ccm *  @CreateTime 2020/07/29 10:17 */@RestController@RequestMapping(value = "sentinelFusingTest")@Api(tags = "sentinel熔断测试控制层")public class SentinelFusingTestController {
@ApiOperation(value = "rt熔断策略") @GetMapping(value = "test01") public ResultSet test01() throws InterruptedException {
Thread.sleep(300L); return ResultSet.success("笑脸"); }}

(2).为测试接口配置rt策略的熔断.

配置的含义:在10秒钟内,如果请求数量大于5且请求的平均响应时间超过200毫秒,微服务在这个10秒钟的时间窗口开启断路器.10秒钟内,所有的请求不会访问到资源,会快速失败返回给客户端.断路器10秒之后自动关闭,允许客户端访问该资源.

在这里插入图片描述

(3).用jmeter压力测试,触发断路器打开.

10秒钟之内,发起20个请求.

在这里插入图片描述填写url.
在这里插入图片描述
发起请求,查看结果树,可以看到20个请求中,5个请求成功,15个请求失败,并返回了Blocked by Sentinel (flow limiting).
在这里插入图片描述

4.sentinl熔断之异常比例策略.

(1).测试代码编写,见方法test02().

package com.ccm.server.user.controller;import com.ccm.common.exception.result.ResultSet;import io.swagger.annotations.Api;import io.swagger.annotations.ApiOperation;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;/** *  @Description sentinel熔断测试控制层 *  @Author ccm *  @CreateTime 2020/07/29 10:17 */@RestController@RequestMapping(value = "sentinelFusingTest")@Api(tags = "sentinel熔断测试控制层")public class SentinelFusingTestController {
@ApiOperation(value = "rt熔断策略") @GetMapping(value = "test01") public ResultSet test01() throws InterruptedException {
Thread.sleep(300L); return ResultSet.success("笑脸"); } @ApiOperation(value = "异常比例熔断策略") @GetMapping(value = "test02") public ResultSet test02() {
int i = 1/0; return ResultSet.success("笑脸"); }}

(2).注释掉全局异常处理器(如果不去除异常处理器,那么异常会被异常处理器吞掉,sentinel会认为这个请求没有出现异常).

/*package com.ccm.common.handler;import com.ccm.common.exception.CcmMallException;import com.ccm.common.exception.CustomerException;import com.ccm.common.exception.ServerException;import com.ccm.common.exception.result.CodeEnum;import com.ccm.common.exception.result.ResultSet;import lombok.extern.slf4j.Slf4j;import org.apache.catalina.servlet4preview.http.HttpServletRequest;import org.springframework.beans.factory.annotation.Value;import org.springframework.http.converter.HttpMessageNotReadableException;import org.springframework.web.HttpMediaTypeNotAcceptableException;import org.springframework.web.HttpMediaTypeNotSupportedException;import org.springframework.web.HttpRequestMethodNotSupportedException;import org.springframework.web.bind.MethodArgumentNotValidException;import org.springframework.web.bind.MissingPathVariableException;import org.springframework.web.bind.MissingServletRequestParameterException;import org.springframework.web.bind.annotation.ExceptionHandler;import org.springframework.web.bind.annotation.RestControllerAdvice;import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;import org.springframework.web.servlet.NoHandlerFoundException;import javax.annotation.PostConstruct;import javax.validation.ConstraintViolationException;*//** * @Description 全局异常处理器 * @Author ccm * @CreateTime 2020/7/15 10:13 *//*@Slf4j@RestControllerAdvicepublic class GlobalExceptionHandler {    *//**     * 服务名     *//*    @Value("${spring.application.name}")    private String serverName;    *//**     * 错误信息前缀     *//*    private String errorMessagePrefix;    @PostConstruct    public void init() {        this.errorMessagePrefix = new StringBuffer().append("(")                .append(this.serverName)                .append("服务")                .append("->")                .append(") ").toString();    }    *//**     * @Description 处理系统内部异常(未知异常,入空指针,索引越界)     * @Author ccm     * @CreateTime 2020/7/15 10:13     * @Params [e, request]     * @Return com.ccm.common.exception.result.ResultSet     *//*    @ExceptionHandler(value = {Exception.class})    public ResultSet handlerException(Exception e, HttpServletRequest request) {        log.error("请求路径uri={},系统内部出现异常:{}", request.getRequestURI(),e);        ResultSet resultSet = ResultSet.error(CodeEnum.SYSTEM_INNER_ERROR,errorMessagePrefix+e.toString(),"服务器繁忙,请稍后再试");        return resultSet;    }   *//**    * @Description 非法请求异常(SpringAOP)    * @Author ccm    * @CreateTime 2020/7/15 10:14    * @Params [exception]    * @Return com.ccm.common.exception.result.ResultSet    *//*    @ExceptionHandler(value = {                                HttpMediaTypeNotAcceptableException.class,                                HttpMediaTypeNotSupportedException.class,                                HttpRequestMethodNotSupportedException.class,                                MissingServletRequestParameterException.class,                                NoHandlerFoundException.class,                                MissingPathVariableException.class,                                HttpMessageNotReadableException.class                              })    public ResultSet handlerSpringAOPException(Exception exception) {        ResultSet resultSet = ResultSet.error(CodeEnum.ILLEGAL_REQUEST, errorMessagePrefix+exception.getMessage(),exception.getMessage());        return resultSet;    }        *//**     * @Description 非法请求异常(@DateTimeFormat注解抛出异常)     * @Author ccm     * @CreateTime 2020/7/15 10:14     * @Params [e]     * @Return com.ccm.common.exception.result.ResultSet     *//*    @ExceptionHandler(value = MethodArgumentTypeMismatchException.class)    public ResultSet handlerSpringAOPException(MethodArgumentTypeMismatchException e) {        ResultSet resultSet = ResultSet.error(CodeEnum.ILLEGAL_REQUEST, errorMessagePrefix+e.getMessage(),e.getMessage());        return resultSet;    }        *//**     * @Description 非法请求(处理spring validation参数校验抛出异常1)     * @Author ccm     * @CreateTime 2020/7/15 10:14     * @Params [methodArgumentNotValidException]     * @Return com.ccm.common.exception.result.ResultSet     *//*    @ExceptionHandler(value = {MethodArgumentNotValidException.class})    public ResultSet handlerMethodArgumentNotValidException(MethodArgumentNotValidException methodArgumentNotValidException) {        //获取异常字段及对应的异常信息        StringBuffer stringBuffer = new StringBuffer();        methodArgumentNotValidException.getBindingResult().getFieldErrors().stream()                    .map(t -> t.getField()+"=>"+t.getDefaultMessage()+" ")                    .forEach(e -> stringBuffer.append(e));        String errorMessage = stringBuffer.toString();        ResultSet resultSet = ResultSet.error(CodeEnum.ILLEGAL_REQUEST, errorMessagePrefix+errorMessage,errorMessage);        return resultSet;    }    *//**     * @Description 非法请求异常(处理spring validation参数校验抛出异常2)     * @Author ccm     * @CreateTime 2020/7/15 10:14     * @Params [constraintViolationException]     * @Return com.ccm.common.exception.result.ResultSet     *//*    @ExceptionHandler(value = {ConstraintViolationException.class})    public ResultSet handlerConstraintViolationException(ConstraintViolationException constraintViolationException) {        String errorMessage = constraintViolationException.getLocalizedMessage();        ResultSet resultSet = ResultSet.error(CodeEnum.ILLEGAL_REQUEST,errorMessagePrefix+errorMessage,errorMessage);        return resultSet;    }    *//**     * @Description 处理自定义异常-CustomException     * @Author ccm     * @CreateTime 2020/7/15 10:14     * @Params [e]     * @Return com.ccm.common.exception.result.ResultSet     *//*    @ExceptionHandler(value = {CustomerException.class})    public ResultSet handlerCustomException(CustomerException e) {        String errorMessage = e.getErrorMessage();        ResultSet resultSet = ResultSet.error(e.getCodeEnum(), errorMessagePrefix+errorMessage,errorMessage);        return resultSet;    }    *//**     * @Description 处理自定义异常-ServerException     * @Author ccm     * @CreateTime 2020/7/15 10:14     * @Params [e]     * @Return com.ccm.common.exception.result.ResultSet     *//*    @ExceptionHandler(value = {ServerException.class})    public ResultSet handlerServerException(ServerException e) {        String errorMessage = e.getErrorMessage();        ResultSet resultSet = ResultSet.error(e.getCodeEnum(), errorMessagePrefix+errorMessage,errorMessage);        return resultSet;    }}*/

(3).为测试接口配置异常比例策略的熔断.

配置解读:以10秒钟为一个时间窗口期,qps(每秒的并发量)>=5且请求的异常比例大于50%(秒级统计比例)时,会触发断路器开启,时间窗口期结束,断路器关闭.

在这里插入图片描述

(4).使用jmeter进行压力测试,触发断路器.

一秒钟内发起10个请求(保证qps>=5,且这秒级统计的异常比例会是100%,保证触发断路器).

在这里插入图片描述

填写url.

在这里插入图片描述

发起请求,查看结果树,可以看到从第6个请求开始,触发了断路器.

在这里插入图片描述

在这里插入图片描述

5.sentinl熔断之异常数策略.

(1).编写测试代码,见方法test03().
package com.ccm.server.user.controller;import com.ccm.common.exception.result.ResultSet;import io.swagger.annotations.Api;import io.swagger.annotations.ApiOperation;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;/** *  @Description sentinel熔断测试控制层 *  @Author ccm *  @CreateTime 2020/07/29 10:17 */@RestController@RequestMapping(value = "sentinelFusingTest")@Api(tags = "sentinel熔断测试控制层")public class SentinelFusingTestController {
@ApiOperation(value = "rt熔断策略") @GetMapping(value = "test01") public ResultSet test01() throws InterruptedException {
Thread.sleep(300L); return ResultSet.success("笑脸"); } @ApiOperation(value = "异常比例熔断策略") @GetMapping(value = "test02") public ResultSet test02() {
int i = 1/0; return ResultSet.success("笑脸"); } @ApiOperation(value = "异常数熔断策略") @GetMapping(value = "test03") public ResultSet test03() {
int i = 1/0; return ResultSet.success("笑脸"); }}
(2).为接口配置异常数的熔断策略.

配置含义:在10秒钟的时间窗口内,如果异常数超过5个,断路器会开启.10秒钟以后断路器关闭,恢复正常,进入下一个10秒时间窗口.

在这里插入图片描述

(3).用jmeter进行压力测试,触发断路器开启.

10秒钟发出6个请求.

在这里插入图片描述配置url
在这里插入图片描述发起请求,查看结果树,发现第6个请求开始,断路器被打开了.
在这里插入图片描述

在这里插入图片描述

至此,完事!

源码地址:

您的点赞、收藏、转发和关注是我持续创作的动力!

转载地址:http://pktli.baihongyu.com/

你可能感兴趣的文章
Gym 101196D Lost in Translation(BFS)
查看>>
KMP求前缀函数(next数组)
查看>>
KMP
查看>>
poj 3863Business Center
查看>>
C#基本语法里几点和C不一样的地方
查看>>
Libpcap库编程指南--分析数据包
查看>>
LintCode 二叉树的路径和
查看>>
字符编码笔记:ASCII,Unicode 和 UTF-8
查看>>
C++中的Unicode编码:wchar, UTF-8,UTF-16,UTF-32
查看>>
C++中const的用法:使代码更加健壮
查看>>
C++ 11:delete关键词和一条《Effective C++》的过时条款
查看>>
Google C++ 风格指南 :尽可能用 sizeof(varname) 代替 sizeof(type).
查看>>
C++中的委托构造
查看>>
RTP/RTCP 和 SRTP/SRTCP协议
查看>>
AES加密算法(Rijndael算法)
查看>>
WebRTC简介与代码架构
查看>>
WebRTC in the real world: STUN, TURN and signaling
查看>>
C++11的enum class 、enum struct 和 enum
查看>>
【转载】 webrtc中的网络反馈与控制
查看>>
C++11中的“万能引用”
查看>>