房屋建设网站,上海市政网,网站推广员是什么,我的网站设计联盟一、什么是雪崩#xff1f;
微服务调用链路中的某个服务发生故障#xff0c;引起整个链路中的所有微服务都不可用#xff0c;这就是雪崩。 二、解决雪崩问题的常见措施
1、超时处理
设定超时时间#xff0c;请求超过一定时间没有响应就返回错误信息#xff0c;不会无休…一、什么是雪崩
微服务调用链路中的某个服务发生故障引起整个链路中的所有微服务都不可用这就是雪崩。 二、解决雪崩问题的常见措施
1、超时处理
设定超时时间请求超过一定时间没有响应就返回错误信息不会无休止等待。 弊端假设等待时间为1s但是每秒钟传递过来的请求为2个迟早有一天线程数量也会填满整个tomcat服务器。
2、舱壁模式
限定每个业务能使用的线程数避免耗尽整个tomcat的资源因此也叫线程隔离。 3、熔断降级
由断路器统计业务执行的异常比例如果超出阈值则会熔断该业务拦截访问该业务的一切请求。 假设上层服务调用了三次下层服务其中两次都调用失败那么此时的异常比例就为百分之66此时就熔断对下层服务的访问一切访问下层服务的请求都将被立即拦截。
4、流量控制
限制业务访问的QPS避免服务因流量的突增而故障。主要针对高并发场景下进行流量控制假设某服务处理请求的效率为每秒2个当某一时刻大量的请求涌入时就会控制请求的传递效率保证服务的正常运行否则该服务将被大量请求直接拖垮。 5、总结 三、Sentinel与SpringCloud整合
1、引入依赖 !--引入sentinel依赖--dependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-starter-alibaba-sentinel/artifactId/dependency
2、配置连接
spring:cloud:sentinel:transport:dashboard: localhost:8080 #sentinel控制台地址
四、限流规则
1、如何设置流量控制 在学习如何设置流量控制前我们先了解什么是簇点链路 簇点链路就是项目内的调用链路链路中被监控的每个接口就是一个资源。默认情况下sentinel会监控SpringMVC的每一个端点Endpoint因此SpringMVC的每一个端点Endpoint就是调用链路中的一个资源。 简单点来说就是Controller层当中的各个请求接口。 下面我们来看看如何设置单个接口的流量控制 2、流量控制模式 在添加限流规则时点击高级选项可以选择三种流控模式 直接统计当前资源的请求触发阈值时对当前资源直接限流也是默认的模式关联统计与当前资源相关的另一个资源触发阈值时对当前资源限流链路统计从指定链路访问到本资源的请求触发阈值时对指定链路限流 ①、关联模式
使用场景比如用户支付时需要修改订单状态同时用户要查询订单。查询和修改操作会争抢数据库锁产生竞争。业务需求是有限支付和更新订单的业务因此当修改订单业务触发阈值时需要对查询订单业务限流。 模拟案例 代码 GetMapping(/query)public String queryOrder(){return 查询订单成功;}GetMapping(/update)public String updateOrder(){return 更新订单成功;} sentinel控制台 对谁进行限流就 设置谁的流量控制 这个配置的意思就是说当update的QPS触发阈值时此时就限制对query的访问即拦截。这么做的目的就在于优先执行订单修改服务。 此处update和query就针对数据库的锁产生了竞争即读的时候不可以修改修改的时候也不可以读因此则设置优先执行写操作而限制读操作的进行。 ②、链路模式 链路模式常常用于对资源的一种分配比如有一个服务A同时被服务B和服务C调用服务A处理请求的能力有限每秒处理6条)并不能同时处理B和C同一时刻传递过来的请求每秒各4条共8条此时我们就需要对B或C的部分请求进行拦截了具体拦截谁的就看谁的优先级低假设B是订单支付C是订单查询支付的优先级是高于查询的因此我们就会针对服务A的请求来源服务C进行限流。 模拟案例 代码 SentinelResource(goods)public void queryGoods(){System.err.println(查询商品);} GetMapping(/save)public String saveOrder(){//查询商品orderService.queryGoods();//新增订单System.out.println(新增订单);return 新增订单成功;} GetMapping(/query)public String queryOrder(){//查询商品orderService.queryGoods();//查询订单System.out.println(查询订单);return 查询订单成功;} Sentinel控制台 针对goods服务设置链路流控 设置完成后创建订单服务和查询服务同时进行各自每秒访问4次就可以发现查询服务每秒只有两条请求成功了其余两条则会被sentinel拦截。 注意创建订单服务和查询订单服务并没有竞争关系链路模式是出于对代码可靠性的一种保护措施防止服务压力过大导致的宕机。 3、流控效果 流控效果是指请求达到流控阈值时应该采取的措施包括三种 快速失败达到阈值后新的请求会被立即拒绝并抛出FlowException异常。是默认的处理方式。warm up预热模式对超出阈值的请求同样是拒绝并抛出异常。但这种模式阈值会动态变化从一个较小值逐渐增加到最大阈值。排队等待让所有的请求按照先后次序排队执行两个请求的间隔不能小于指定时长 ①、warm up
warm up也叫预热模式是应对服务冷启动的一种方案。
请求阈值初始值是 threshold 最大阈值/ coldFactor持续指定时长后逐渐提高到threshold值。而coldFactor的默认值是3.
例如我设置QPS的threshold为10预热时间为5秒那么初始阈值就是 10 / 3 也就是3然后在5秒后逐渐增长到10. 假设我们每秒的访问量为10在起初的1s内会有3条请求响应成功其余的都会被sentinel拦截了在接下来的4s内阈值会逐步增大逐渐增大到10在未增大到10时部分请求仍然会被拦截。
②、排队等待 模拟案例 给/order/{orderId}这个资源设置限流最大QPS为10利用排队的流控效果超时时长设置为5s 计算 我们假设每秒有15个请求到达该服务此处的单机阈值为10即可以假设每个请求的处理时间为100ms则每秒钟就会有5个请求放到队列当中当到第十秒时队列当中的请求就会放满此时再来的请求就有可能会被直接拦截。 ③、总结 4、热点参数限流
之前的限流是统计访问某个资源的所有请求判断是否超过QPS阈值。而热点参数限流是分别统计参数值相同的请求判断是否超过QPS阈值。 热点参数限流即限制对热点参数的访问限制其控制在一个特定值范围内防止大量相同请求访问同一资源。
五、隔离和降级
1、FeignClient整合Sentinel
SpringCloud中微服务调用都是通过Feign来实现的因此做客户端保护必须整合Feign和Sentinel。
①、修改OrderService的application.yml文件开启Feign的Sentinel功能
feign:httpclient:enabled: true #支持httpClient的开关max-connections: 200 #最大连接数max-connections-per-route: 50 #单个请求路径的最大连接数sentinel:enabled: true #开启feign对sentinel的支持
②、在feing-api项目中定义类实现FallbackFactory
Slf4j
public class UserClientFallbackFactory implements FallbackFactoryUserClient {Overridepublic UserClient create(Throwable throwable) {return new UserClient() {Overridepublic User findById(Long id) {log.error(查询用户异常,throwable);return new User();}};}
}
③、在feing-api项目中的DefaultFeignConfiguration类中将UserClientFallbackFactory注册为一个Bean Beanpublic UserClientFallbackFactory userClientFallbackFactory(){return new UserClientFallbackFactory();}
④、在feing-api项目中的UserClient接口中使用UserClientFallbackFactory
FeignClient(value userservice,configuration DefaultFeignConfiguration.class,fallbackFactory UserClientFallbackFactory.class)//只针对userservice服务有效 全局有效在启动类的注解当中配置即可
public interface UserClient {GetMapping(/user/{id})User findById(PathVariable(id) Long id);
}
2、线程隔离舱壁模式 线程隔离有两种方式 线程池隔离信号量隔离Sentinel默认方式 在添加限流规则时可以选择两种阈值类型 3、熔断降级 熔断降级是解决雪崩问题的重要手段。其思路是由断路器统计服务调用的异常比例、慢请求比例如果超出阈值则会熔断该服务。即拦截访问该服务的一切请求而当服务恢复时断路器会放行访问该服务的请求。 断路器熔断策略有三种慢调用、异常比例、异常数。 if (id 1){Thread.sleep(60);}else if (id 2){throw new RuntimeException(故意出错触发熔断);}
①、慢调用 业务的响应时长RT大于指定时长的请求认定为慢调用请求。在指定时间内如果请求数量超过设定的最小数量慢调用比例大于设定的阈值则触发熔断。 解读RT超过500ms的调用是慢调用统计最近10000ms内的请求如果请求量超过10次并且慢调用比例不低于0.5则触发熔断熔断时长为5秒。然后进入half-open状态放行一次请求做测试。 ②、异常比例或异常数 异常比例或异常数统计指定时间内的调用如果调用次数超过指定请求数并且出现异常的比例达到设定的比例阈值或超过指定异常数则触发熔断。 解读统计最近1000ms内的请求如果请求量超过10次并且异常比例不低于0.5则触发熔断熔断时长为5秒。然后进入half-open状态放行一次请求做测试。 六、授权规则和规则持久化 授权规则可以对调用方的来源做控制有白名单和黑名单两种方式。 白名单来源origin在白名单内的调用者允许访问黑名单来源origin在黑名单内的调用者不允许访问 案例限定只允许从网关来的请求访问order-service那么流控应用中就填写网关的名称。 ①、网关过滤器添加请求头 - AddRequestHeaderOrigin,gateway ②、Sentinel是通过RequestOriginParser这个接口的parseOrigin来获取请求的来源的。 实现这个接口判断请求来源。 Component
public class HeaderOriginParser implements RequestOriginParser {Overridepublic String parseOrigin(HttpServletRequest httpServletRequest) {//获取请求头String origin httpServletRequest.getHeader(Origin);//判断请求头if (StringUtils.isEmpty(origin)){origin black;// 黑名单}return origin;}
} ③、Sentinel控制台配置授权 ④、测试 http://localhost:10010/order/101?authorizationadmin http://localhost:8010/order/101 1、如何自定义异常结果
默认情况下发生限流、降级、授权拦截时都会抛出异常到调用方。如果要自定义异常时的返回结果需要实现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;charsetutf-8);response.setStatus(status);response.getWriter().println({\msg\: msg , \status\: status });}
}
2、规则持久化 Sentinel管理配置的三种模式 原始模式配置信息保存在内存服务重启则失效。pull模式保存在本地文件或者数据库定时去读取时效性比较差。push模式保存在nacos监听变更实时更新。 push模式管理配置
①、引入依赖
dependencygroupIdcom.alibaba.csp/groupIdartifactIdsentinel-datasource-nacos/artifactId
/dependency
②、修改order-service服务使其监听Nacos配置中心
spring:application:name: orderserviceprofiles:active: devcloud:sentinel:transport:dashboard: localhost:8080 #sentinel控制台地址web-context-unify: false #关闭context整合datasource:flow:nacos:serverAddr: localhost:80dataId: orderservice-flow-rulesgroupId: SENTINEL_GROUPruleType: FLOW #还可以是degrade、authority、param-flow
③、修改Sentinel-dashboard源码修改前端页面
详细步骤参考网上文档。