当前位置: 首页 > news >正文

为什么做动漫短视频网站如何建立自己的网络销售

为什么做动漫短视频网站,如何建立自己的网络销售,黑龙江省生产建设兵团知青网站,湖南网站建设360o文章目录 Feign整合Sentinel线程隔离熔断降级授权规则自定义异常结果 上一期教程讲解了 Sentinel 的限流规则: Sentinel限流规则,这一期主要讲述 Sentinel 的 隔离、降级和授权规则 虽然限流可以尽量避免因高并发而引起的服务故障,但服务还…

文章目录

  • Feign整合Sentinel
  • 线程隔离
  • 熔断降级
  • 授权规则
  • 自定义异常结果

上一期教程讲解了 Sentinel 的限流规则: Sentinel限流规则,这一期主要讲述 Sentinel 的 隔离、降级和授权规则

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

不管是线程隔离还是熔断降级,都是对客户端(调用方) 的保护

Feign整合Sentinel

在 SpringCloud 中,微服务调用一般都是通过 Feign 来实现的,因此做客户端保护必须整合Feign和Sentinel

Feign 的使用在之前的教程中有详细讲解过:Eureka结合Feign

实现的步骤如下:

1.在调用方的 application.yml 文件中,开启 Feign 对 Sentinel 的支持

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

2.为 FeignClient 编写失败后的降级逻辑

这里有两种方式:

FallbackClass,这种方式无法对远程调用的异常做处理
FallbackFactory,这种方式可以对远程调用的异常做处理

这里我们选择 FallbackFactory

定义一个类 UserClientFallbackFactory(名字可以任意),然后实现接口 FallbackFactory<UserClient>,这里泛型要和对应的 Feign 客户端对应

@Component
public class UserClientFallbackFactory implements FallbackFactory<UserClient> {@Overridepublic UserClient create(Throwable cause) {return new UserClient() {@Overridepublic String user() {cause.printStackTrace();// 异常时返回空值return "";}};}}

3.在 Feign 客户端的 @FeignClient 注解中,添加属性 fallbackFactory,值就是刚才定义的类的 class 对象

@FeignClient(name = "service2", url = "http://127.0.0.1:8082", fallbackFactory = UserClientFallbackFactory.class)

这里为了方便,就直接定义了对应服务的 url,如果结合了注册中心,这里只需要填写对应的服务名即可

4.启动测试

访问对应服务端点后,进入 Sentinel 控制台,可以看到如下界面,表示 Feign 已经成功整合了 Sentinel

image-20240724142527550

然后添加限流规则,将 QPS 设为 1,测试异常情况

image-20240724143327743

然后快速刷新浏览器,可以发现限流后,返回了空值,即触发了 Feign 客户端的失败降级逻辑

image-20240724143438130

线程隔离

线程隔离有两种方式实现:

1.线程池隔离

这种方式就是将服务消费者的资源划分成一个又一个独立的线程池,假设某一服务提供者挂掉了,也只有一个线程池的资源会被耗尽,不会导致所有的资源被耗尽

优点:

① 支持主动超时(可以通过线程池来控制线程,比如发现某个线程耗时较长,就可以直接终止这个线程)
② 支持异步调用(自己的线程继续接收消息,把调用交给线程池里的线程)

缺点: 线程的额外开销比较大(需要开启的线程较多,同时CPU还需要进行线程的上下文切换)

场景: 低扇出(扇出指的是原本的请求分散后的请求数),扇出越高,需要开启的线程就越多

2.信号量隔离(Sentinel 默认采用)

信号量隔离指的是不会为每个业务创建一个线程池,而是会统计当前业务已经使用的线程数,然后进行限制。当达到这个限制时,就会阻止对这个业务的请求,即限制每个业务能使用的线程数量

优点: 轻量级,无额外开销

缺点:

① 不支持主动超时
② 不支持异步调用

场景: 高频调用、高扇出

下面是两种方式的对比图:

线程隔离两种方式

在 Sentinel 控制台中,可以选择阈值类型,共有两种:

image-20240724143541602

① QPS:就是每秒的请求数
② 线程数:是该资源能使用的 tomcat 线程数的最大值。也就是通过限制线程数量,实现舱壁模式,对应信号量隔离

熔断降级

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

断路器是由内部的状态机实现的:

断路器状态机

整个的流程是:正常情况下,断路器关闭,处于 Closed 状态。如果断路器统计的慢调用或异常比例达到失败阈值,会开启断路器,进入 Open 状态,此时的请求会快速失败。直到熔断时间结束,会进入 Half-Open 状态(断路器半开启状态),此时会尝试放行一次请求,如果此次请求成功,则关闭断路器,进入 Closed 状态;如果请求失败,则重新打开断路器,回到 Open 状态,并重复刚才的过程

断路器熔断策略有三种:慢调用、异常比例、异常数

1.慢调用

业务的响应时长(RT)大于指定时长的请求认定为慢调用请求。在指定时间内,如果请求数量超过指定请求数,并且慢调用比例大于设定的阈值,则触发熔断

例如,在 Sentinel 控制台中选择新增降级规则,并填写如下信息

image-20240724144201880

image-20240724144336008

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

2.异常比例或异常数

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

例如,设置如下的降级规则

image-20240724144712522

image-20240724144737893

这两种设置方式都是一样的,区别在于一个是设置异常比例,一个是设置异常数,但表达的意思都是,统计最近 1000ms 内的请求,如果请求量不少于 10 次,并且异常比例不低于 0.4(或异常数不少于2),则触发熔断,熔断时长为 5 秒。然后进入 half-open 状态,放行一次请求做测试

授权规则

授权规则可以对调用方的来源做控制,有白名单黑名单两种方式

白名单:来源(origin)在白名单内的调用者允许访问
黑名单:来源(origin)在黑名单内的调用者不允许访问

在控制台中可以选择新增授权规则,此时就可以选择黑名单或白名单两种方式

image-20240724150439205

image-20240724150505414

Sentinel 是通过 RequestOriginParser 接口中的 parseOrigin() 方法来获取请求的来源的

public interface RequestOriginParser {/*** 从请求request对象中获取origin,获取方式自定义*/String parseOrigin(HttpServletRequest request);
}

但是,默认情况下,这个方法的返回值永远是 “default”。也就是说,Sentinel 默认无法区分所有的请求。因此,我们需要自己实现这个接口,并且编写业务逻辑

案例:

限定只允许从网关发来的请求来访问 service1

实现步骤如下:

1.编写类,实现 RequestOriginParser 接口并编写 parseOrigin() 方法,从 HTTP 请求中获取名为 origin 的请求头并返回

@Component
public class HeaderOriginParser implements RequestOriginParser {@Overridepublic String parseOrigin(HttpServletRequest httpServletRequest) {String origin = httpServletRequest.getHeader("origin");if(StringUtils.isEmpty(origin)) {origin = "blank";}System.out.println(origin);return origin;}
}

2.在 gateway 网关服务中,利用过滤器添加 origin 请求头,值为 gateway

server:port: 10010 # 网关端口
spring:application:name: gateway # 服务名称cloud:gateway:routes: # 网关路由配置- id: service1uri: http://localhost:8081 # 路由的目标地址predicates: # 路由断言,判断请求是否符合路由规则的条件- Path=/service1/** # 路径断言default-filters:- AddRequestHeader=origin,gateway # 添加名为origin的请求头,值为gateway

3.在控制台中配置授权规则

image-20240724160931183

4.测试

首先直接跨过网关访问 service1,如下图所示,可以发现访问失败

image-20240724161006709

然后,通过网关来访问 service1,如下图所示,可以发现访问成功

image-20240724161029014

自定义异常结果

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

public interface BlockExceptionHandler {/*** 处理请求被限流、降级、授权拦截时抛出的异常:BlockException*/void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception;
;}

可以看到,handle() 方法中有一个类型为 BlockException 的参数,这个参数表示了具体的异常,而 BlockException 包含很多个子类,分别对应不同的场景,如下所示

异常说明
FlowException限流异常
ParamFlowException热点参数限流的异常
DegradeException降级异常
AuthorityException授权规则异常
SystemBlockException系统规则异常

实现自定义异常返回结果的具体方式是,定义一个类,实现 BlockExceptionHandler 接口,然后编写业务逻辑,如下所示:

@Component
public class SentinelExceptionHandler implements BlockExceptionHandler {@Overridepublic 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 + "}");}
}

然后进行测试。先在控制台创建流控规则,将 QPS 设为1,如下

image-20240724162045896

然后快速刷新浏览器,结果如下所示,可以看出异常结果和代码所展现的一致

image-20240724162226250

其他的测试也是类似的,但是发现热点规则无法触发该逻辑,用 debug 设置断点发现在异常时没有进入到对应的代码里

因此建议对于热点规则的异常,直接使用全局异常处理即可,如下所示:

@RestControllerAdvice
public class GlobalExceptionHandler {@ExceptionHandler(ParamFlowException.class)public void handleParamFlowException(HttpServletRequest request, HttpServletResponse response, Exception e)throws IOException {response.setContentType("application/json;Charset=utf-8");response.setStatus(429);response.getWriter().println("{\"msg\": " + "请求被热点参数限流" + ", \"status\": " + 429 + "}");}}

测试后发现异常结果可以正常显示

image-20240724164030872

http://www.yidumall.com/news/78425.html

相关文章:

  • 专门做喷涂设备的网站免费网站友情链接
  • 学ui可以做网站么seo引擎优化是什么
  • 20亿做网站营销型外贸网站建设
  • 网站建设 电话谷歌商店安卓版下载
  • 网站建设哪里最好龙岗网站建设
  • 网站logo如何做链接百度热搜榜怎么打开
  • 单位做网站需要准备什么上海网站建设开发
  • 用pdf怎么做电子书下载网站手机网页制作app
  • 淘宝不允许 网站建设怎么做谷歌推广
  • 郑州网站建设企起免费发布推广平台
  • 有什么做网站好用的软件唐山seo快速排名
  • 做网站多少人教你免费申请个人网站
  • 人妖和人妖做的小视频网站个人介绍网页制作
  • web网站开发书籍品牌运营策略有哪些
  • 制作网页软件手机版seo查询
  • 做娱乐网站被坑郑州网站建设用户
  • 网站怎么做才能赚钱网站seo排名优化方法
  • 郑州网站运营实力乐云seo湖人最新排名最新排名
  • 东营网站建设入门发布软文的平台
  • 数据库 网站 模板360网站关键词排名优化
  • 好的企业网站建设推广排名
  • 网站设计基本流程成都关键词自然排名
  • 泉州网站设计平台网站很卡如何优化
  • 个人网站域名所有权微信推广方式有哪些
  • 做加盟网站赚钱吗百度知道网页版登录入口
  • 大型网站架设需要考虑哪些问题广告网站有哪些
  • .wordpress淘宝客模版seo推广方法集合
  • 类似抖音网站开发费用淘宝竞价排名
  • 烟草许可证每年做证去那个网站发广告推广平台
  • 安装wordpress出现500谷歌seo详细教学