微服务组件Sentinel的学习(3)

Sentinel

隔离和降级

虽然限流可以尽量避免因高并发而引起的服务故障,但服务还会因为其它原因而故障。而要将这些故障控制在一定范用避免雪崩,就要靠线程隔离(舱壁模式)和熔断降级。

Feign整合Sentinel

步骤一:修改application.yml文件,开启Feign的Sentinel功能

yaml 复制代码
  cloud:
    feign:
      sentinel:
        enabled: true

步骤二:给FeignClient编写失败后的降级逻辑

方式(1):FallbackClass,无法对远程调用的异常做处理

方式(2):FallbackFactory,可以对远程调用的异常做处理,

用FallbackFactory举例:

第一步:

java 复制代码
public class UserClientFallbackFactory implements FallbackFactory<UserQuery> {
    @Override
    public UserQuery create(Throwable throwable) {
        return new UserQuery() {
            @Override
            public User findById(Long id) {
                log.error("查询用户失败!", throwable);
                return new User();
            }
        };
    }
}

第二步:

java 复制代码
@Bean
public UserQueryFallbackFactory userQueryFallbackFactory(){
    return new UserQueryFallbackFactory();
}

第三步:

java 复制代码
@FeignClient(value = "userservice", fallbackFactory = UserQueryFallbackFactory.class) 
public interface UserQuery {
    @GetMapping("/user/{id}")
    User findById(@PathVariable("id") Long id);
}

线程隔离

线程数:是该资源能使用的tomcat线程数的最大值。也就是通过限制线程数量,实现舱壁模式。下面图片中,就可以直接指定线程数。

线程隔离的两种手段是?

(1)信号量隔离

(2)线程池隔离

信号量隔离的特点是?
基于计数器模式,简单,开销小

线程池隔离的特点是?
基于线程池模式,有额外开销,但隔离控制更强

熔断降级

熔断降级是解决雪崩问题的重要手段。其思路是由断路器统计服务调用的异常比例、慢请求比例,如果超出阈值则会熔断该服务。即拦截访问该服务的一切请求,而当服务恢复时,断路器会放行访问该服务的请求。其主要分为以下几个状态:

熔断策略

断路器熔断策略有三种:慢调用异常比例异常数
慢调用 :业务的响应时长(RT)大于指定时长的请求认定为慢调用请求。在指定时间内,如果请求数量超过设定的最小数量,慢调用比例大于设定的阈值,则触发熔断。例如:

RT超过500ms的调用是慢调用,统计最近1000ms内的请求,如果请求量超过10次,并且慢调用比例不低于0.5则触发熔断,熔断时长为5秒。然后进入half-open状态,放行一次请求做测试。

异常比例或异常数

异常比例或异常数:统计指定时间内的调用,如果调用次数超过指定请求数,并且出现异常的比例达到设定的比例阈值(或超过指定异常数),则触发熔断。

统计最近1000ms内的请求,如果请求量超过10次,并且异常比例不低于0.5,则触发熔断,熔断时长为5秒。然后进入half-open状态,放行一次请求做测试。

授权规则:

授权规则可以对调用方的来源做控制,有以下两种方式:
白名单 :来源在白名单内的调用者允许访问
黑名单 :来源在黑名单内的调用者不允许访问

Sentinel是通过RequestOriginParser 这个接口的parseOrigin来获取请求的来源的

java 复制代码
public interface RequestOriginParser {    
    String parseOrigin(HttpServletRequest request);
 }

例如,尝试从request中获取一个名为origin的请求头,作为origin的值:

java 复制代码
public class HeaderOriginParser implements RequestOriginParser {
    @Override
    public String parseOrigin(HttpServletRequest httpServletRequest) {
        String origin = httpServletRequest.getHeader("origin");
        if(StringUtils.isEmpty(origin)){
            return "black";
        }
        return origin;
    }
}

还需要在gateway服务中,利用网关的过滤器添加名为gateway的origin头:

yaml 复制代码
spring:
  cloud:
    gateway:
      default-filters: # 默认过滤器,会对所有的路由请求都生效
        - AddRequestHeader=origin, gateway # Sentinel授权规则,只有从网关服务的才合法,通过添加请求头标识

自定义异常

默认情况下,发生限流、降级、授权拦截时,都会抛出异常到调用方。如果要自定义异常时的返回结果,需要实现BlockExceptionHandler接口:

java 复制代码
@Component
public class SentinelExceptionHandler 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 + "}");
    }
}

来源:B站黑马学习视频

相关推荐
爱吃西瓜的小菜鸡2 小时前
【C语言】判断回文
c语言·学习·算法
小A1593 小时前
STM32完全学习——SPI接口的FLASH(DMA模式)
stm32·嵌入式硬件·学习
岁岁岁平安3 小时前
spring学习(spring-DI(字符串或对象引用注入、集合注入)(XML配置))
java·学习·spring·依赖注入·集合注入·基本数据类型注入·引用数据类型注入
武昌库里写JAVA3 小时前
Java成长之路(一)--SpringBoot基础学习--SpringBoot代码测试
java·开发语言·spring boot·学习·课程设计
qq_589568103 小时前
数据可视化echarts学习笔记
学习·信息可视化·echarts
兔C4 小时前
微信小程序的轮播图学习报告
学习·微信小程序·小程序
海海不掉头发4 小时前
苍穹外卖-day05redis 缓存的学习
学习·缓存
小木_.5 小时前
【Python 图片下载器】一款专门为爬虫制作的图片下载器,多线程下载,速度快,支持续传/图片缩放/图片压缩/图片转换
爬虫·python·学习·分享·批量下载·图片下载器
一棵开花的树,枝芽无限靠近你5 小时前
【PPTist】组件结构设计、主题切换
前端·笔记·学习·编辑器
DT辰白5 小时前
如何解决基于 Redis 的网关鉴权导致的 RESTful API 拦截问题?
后端·微服务·架构