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

嵊州建设局网站线上营销怎么做

嵊州建设局网站,线上营销怎么做,网站积分系统方案,有哪些做数据比较好的网站熔断降级 概念 除了流量控制以外,对调用链路中不稳定的资源进行熔断降级也是保障高可用的重要措施之一。一个服务常常会调用其它模块,可能是一个远程服务、数据库、或者第三方 API 等。然而,被依赖的服务的稳定性是不能保证的。如果依赖的服…

熔断降级

概念

除了流量控制以外,对调用链路中不稳定的资源进行熔断降级也是保障高可用的重要措施之一。一个服务常常会调用其它模块,可能是一个远程服务、数据库、或者第三方 API 等。然而,被依赖的服务的稳定性是不能保证的。如果依赖的服务出现了不稳定的情况,导致请求的响应时间变长,那么调用服务的方法的响应时间也会变长,线程会堆积,最终可能会耗尽业务自身的线程池,甚至服务本身变得不可用。

现在的微服务架构都是分布式的,由非常多的服务组成。不同的服务之间相互调用,形成复杂的调用链路。链路中某一环不稳定,可能会层层级联,最终导致整个链路不可用。因此需要对不稳定的弱依赖服务调用进行熔断降级,暂时切断不稳定的调用,避免局部不稳定因素导致整体的雪崩。熔断降级通常在客户端(调用端)进行配置。

熔断可以类比成生活中的保险丝,一旦电流过载,保险丝就会断开。

Sentinel 熔断降级基于熔断器模式 (circuit breaker pattern) 实现。熔断器内部维护了一个熔断器的状态机,状态机的转换关系如下图所示:

在这里插入图片描述

熔断器有三种状态:

  • Closed 状态:也是初始状态,该状态下,熔断器会保持闭合,对资源的访问直接通过熔断器的检查。
  • Open 状态:断开状态,熔断器处于开启状态,对资源的访问会被切断。
  • Half-Open 状态:半开状态,该状态下除了探测流量,其余对资源的访问也会被切断。探测流量指熔断器处于半开状态时,会周期性的允许一定数目的探测请求通过,如果探测请求能够正常的返回,代表探测成功,此时熔断器会重置状态到 Closed 状态,结束熔断;如果探测失败,则回滚到 Open 状态。

熔断策略

Sentinel 提供了如下三种熔断策略。

  • 慢调用比例(SLOW_REQUEST_RATIO):选择慢调用比例作为阈值,需要设置允许的慢调用 RT(即最大的响应时间),如果请求的时间大于该阈值则被统计为慢调用。当单位统计时长(statIntervalMs)内请求的数量大于设置的最小请求数量,并且慢调用的比例大于阈值,则接下来的熔断时长(timeWindow)内请求自动被熔断。经过熔断时长后,熔断器进入探测恢复状态(Half-Open 状态),如果接下来的一个请求的响应时间小于设置的慢调用 RT 则结束熔断;如果大于则再次被熔断。慢调用比例的阈值范围为 [0.0, 1.0],代表 0% - 100%。
  • 异常比例(ERROR_RATIO):当单位统计时长(statIntervalMs)内请求数量大于设置的最小请求数量,并且异常比例大于阈值,则接下来的熔断时长(timeWindow)内请求自动被熔断。经过熔断时长后,熔断器进入探测恢复状态(Half-Open 状态),如果接下来的一个请求成功完成(没有错误)则结束熔断;否则再次被熔断。异常比例的阈值范围为 [0.0, 1.0] ,代表 0% - 100%。
  • 异常数(ERROR_COUNT):当单位统计时长(statIntervalMs)内的异常数量超过阈值之后,则接下来的熔断时长(timeWindow)内请求自动被熔断。经过熔断时长后,熔断器进入探测恢复状态(Half-Open 状态),如果接下来的一个请求成功完成(没有错误)则结束熔断;否则再次被熔断。

熔断降级规则

字段说明默认值
resource资源名,即规则作用的对象
grade熔断策略,支持慢调用比例/异常比例/异常数慢调用比例
count慢调用比例模式下对应慢调用RT(超过该值即为慢调用);异常比例/异常数模式下为对应的阈值
timeWindow熔断时长,单位为秒
minRequestAmount熔断触发的最小请求数,请求数小于该值时即使异常比例超过阈值也不会熔断(1.7.0 版本引入)5
statIntervalMs统计时长,单位为毫秒(1.8.0 版本引入)1000
slowRationThreshold慢调用比例阈值,仅慢调用比例模式有效(1.8.0 版本引入)

同一个资源可以同时有多个熔断降级规则。

实际操作

在 Nacos 的控制台中的配置管理/配置列表中,在 public 的命名空间中创建一个如下配置:

dataId:spring-cloud-demo-consumer-sentinel-degrade

group:DEFAULT

[{"resource": "/hello/say","limitApp": "default","grade": 0,"count": 200,"timeWindow": 10,"statIntervalMs": 1000,"slowRatioThreshold": 0.6   }
]

如果 1 秒内,请求数量至少达到 200,并且(请求的响应时间超过 200 毫秒即为慢调用)慢调用的比例达到 60%,则进行熔断,熔断时长为 10 秒。


对应的客户端的配置文件如下:

spring:application:name: spring-cloud-demo-consumercloud:nacos:discovery:server-addr: 10.211.55.11:8848,10.211.55.12:8848,10.211.55.13:8848enabled: truesentinel:transport:dashboard: 127.0.0.1:9000eager: truedatasource:degrade-nacos-datasource:nacos:server-addr: 10.211.55.11:8848,10.211.55.12:8848,10.211.55.13:8848group-id: DEFAULT_GROUPnamespace: publicdata-id: ${spring.application.name}-sentinel-degradedata-type: jsonrule-type: degradeusername: nacospassword: nacos

DegradeSlot

负责熔断降级规则的判断。

@Spi(order = Constants.ORDER_DEGRADE_SLOT)
public class DegradeSlot extends AbstractLinkedProcessorSlot<DefaultNode> {@Overridepublic void entry(Context context, ResourceWrapper resourceWrapper, DefaultNode node, int count,boolean prioritized, Object... args) throws Throwable {// 校验熔断降级规则performChecking(context, resourceWrapper);fireEntry(context, resourceWrapper, node, count, prioritized, args);}void performChecking(Context context, ResourceWrapper r) throws BlockException {// 由DegradeRuleManager负责加载所有的断路器List<CircuitBreaker> circuitBreakers = DegradeRuleManager.getCircuitBreakers(r.getName());// 如果断路器列表为空,则直接返回if (circuitBreakers == null || circuitBreakers.isEmpty()) {return;}// 遍历断路器列表,只要有一个断路器判定请求不通过,则抛出DegradeException异常for (CircuitBreaker cb : circuitBreakers) {if (!cb.tryPass(context)) {throw new DegradeException(cb.getRule().getLimitApp(), cb.getRule());}}}@Overridepublic void exit(Context context, ResourceWrapper r, int count, Object... args) {Entry curEntry = context.getCurEntry();// 如果调用过程中存在BlockException异常,则直接返回if (curEntry.getBlockError() != null) {fireExit(context, r, count, args);return;}// 由DegradeRuleManager负责加载所有的断路器List<CircuitBreaker> circuitBreakers = DegradeRuleManager.getCircuitBreakers(r.getName());// 如果断路器列表为空,则直接返回if (circuitBreakers == null || circuitBreakers.isEmpty()) {fireExit(context, r, count, args);return;}// 如果调用过程中不存在BlockException异常if (curEntry.getBlockError() == null) {// 遍历断路器列表,触发每个断路器的onRequestComplete方法的回调for (CircuitBreaker circuitBreaker : circuitBreakers) {circuitBreaker.onRequestComplete(context);}}fireExit(context, r, count, args);}
}

接下来看下断路器如何判断请求是否通过的。

AbstractCircuitBreaker

AbstractCircuitBreaker(DegradeRule rule, EventObserverRegistry observerRegistry) {AssertUtil.notNull(observerRegistry, "observerRegistry cannot be null");if (!DegradeRuleManager.isValidRule(rule)) {throw new IllegalArgumentException("Invalid DegradeRule: " + rule);}this.observerRegistry = observerRegistry;this.rule = rule;this.recoveryTimeoutMs = rule.getTimeWindow() * 1000;
}

接下来看下 tryPass 方法的处理逻辑。

@Override
public boolean tryPass(Context context) {// 如果断路器的状态是CLOSED,则返回true,表示请求通过if (currentState.get() == State.CLOSED) {return true;}// 如果断路器的状态是OPENif (currentState.get() == State.OPEN) {// 判断是否到了熔断结束时间,如果到了则尝试将断路器的状态从OPEN变为HALF-OPENreturn retryTimeoutArrived() && fromOpenToHalfOpen(context);}// 剩余情况,返回false,表示请求不通过return false;
}

retryTimeoutArrived 方法

判断是否到了熔断结束时间

protected boolean retryTimeoutArrived() {// 判断当前时间 >= 下一次的熔断结束时间return TimeUtil.currentTimeMillis() >= nextRetryTimestamp;
}

fromOpenToHalfOpen 方法

尝试将断路器的状态从OPEN变为HALF-OPEN

protected boolean fromOpenToHalfOpen(Context context) {// 尝试将断路器的状态从OPEN更新为HALF_OPENif (currentState.compareAndSet(State.OPEN, State.HALF_OPEN)) {// 触发所有CircuitBreakerStateChangeObserver的onStateChange方法回调notifyObservers(State.OPEN, State.HALF_OPEN, null);Entry entry = context.getCurEntry();entry.whenTerminate(new BiConsumer<Context, Entry>() {@Overridepublic void accept(Context context, Entry entry) {// 如果调用过程中存在BlockException异常if (entry.getBlockError() != null) {// 将断路器的状态从HALF_OPEN更新为OPENcurrentState.compareAndSet(State.HALF_OPEN, State.OPEN);// 触发所有CircuitBreakerStateChangeObserver的onStateChange方法回调notifyObservers(State.HALF_OPEN, State.OPEN, 1.0d);}}});return true;}return false;
}

接下来重点看下 AbstractCircuitBreaker 的子类对于 onRequestComplete 方法的具体实现。

ResponseTimeCircuitBreaker

关注响应时间的断路器实现

public ResponseTimeCircuitBreaker(DegradeRule rule) {// 统计时长由熔断降级规则的statIntervalMs参数指定,默认1000,即1秒this(rule, new SlowRequestLeapArray(1, rule.getStatIntervalMs()));
}ResponseTimeCircuitBreaker(DegradeRule rule, LeapArray<SlowRequestCounter> stat) {super(rule);AssertUtil.isTrue(rule.getGrade() == RuleConstant.DEGRADE_GRADE_RT, "rule metric type should be RT");AssertUtil.notNull(stat, "stat cannot be null");this.maxAllowedRt = Math.round(rule.getCount());this.maxSlowRequestRatio = rule.getSlowRatioThreshold();this.minRequestAmount = rule.getMinRequestAmount();this.slidingCounter = stat;
}

看下 ResponseTimeCircuitBreaker 对于 onRequestComplete 方法的具体实现。

@Override
public void onRequestComplete(Context context) {SlowRequestCounter counter = slidingCounter.currentWindow().value();Entry entry = context.getCurEntry();if (entry == null) {return;}long completeTime = entry.getCompleteTimestamp();if (completeTime <= 0) {completeTime = TimeUtil.currentTimeMillis();}long rt = completeTime - entry.getCreateTimestamp();// 如果响应时间超过了阈值(对应熔断降级规则中的count参数)if (rt > maxAllowedRt) {// 慢请求数指标加一counter.slowCount.add(1);}// 总请求数指标加一counter.totalCount.add(1);handleStateChangeWhenThresholdExceeded(rt);
}

接下来看下 handleStateChangeWhenThresholdExceeded 方法的处理逻辑。

private void handleStateChangeWhenThresholdExceeded(long rt) {// 如果断路器的状态是OPEN,则直接返回if (currentState.get() == State.OPEN) {return;}// 如果断路器的状态是HALF_OPENif (currentState.get() == State.HALF_OPEN) {// 如果请求的响应时间超过了阈值if (rt > maxAllowedRt) {// 将断路器的状态更新为OPEN,然后更新下一次的熔断结束时间fromHalfOpenToOpen(1.0d);} else {// 将断路器的状态更新为CLOSED,然后重置慢请求数、总请求数指标fromHalfOpenToClose();}return;}List<SlowRequestCounter> counters = slidingCounter.values();long slowCount = 0;long totalCount = 0;// 累加慢请求数、总请求数for (SlowRequestCounter counter : counters) {slowCount += counter.slowCount.sum();totalCount += counter.totalCount.sum();}// 如果总请求数 < 熔断降级规则中的minRequestAmount参数,则直接返回if (totalCount < minRequestAmount) {return;}// 计算慢调用比例double currentRatio = slowCount * 1.0d / totalCount;// 如果慢调用比例 > 熔断降级队则中的slowRatioThreshold参数值(默认1)if (currentRatio > maxSlowRequestRatio) {// 将断路器的状态更新为OPEN,然后更新下一次的熔断结束时间transformToOpen(currentRatio);}// 如果当前的慢调用比例达到了100%if (Double.compare(currentRatio, maxSlowRequestRatio) == 0 &&Double.compare(maxSlowRequestRatio, SLOW_REQUEST_RATIO_MAX_VALUE) == 0) {// 将断路器的状态更新为OPEN,然后更新下一次的熔断结束时间transformToOpen(currentRatio);}
}

ExceptionCircuitBreaker

关注异常比例、异常数的断路器实现

public ExceptionCircuitBreaker(DegradeRule rule) {// 统计时长由熔断降级规则的statIntervalMs参数指定,默认1000,即1秒this(rule, new SimpleErrorCounterLeapArray(1, rule.getStatIntervalMs()));
}ExceptionCircuitBreaker(DegradeRule rule, LeapArray<SimpleErrorCounter> stat) {super(rule);this.strategy = rule.getGrade();boolean modeOk = strategy == DEGRADE_GRADE_EXCEPTION_RATIO || strategy == DEGRADE_GRADE_EXCEPTION_COUNT;AssertUtil.isTrue(modeOk, "rule strategy should be error-ratio or error-count");AssertUtil.notNull(stat, "stat cannot be null");this.minRequestAmount = rule.getMinRequestAmount();this.threshold = rule.getCount();this.stat = stat;
}

看下 ExceptionCircuitBreaker 对于 onRequestComplete 方法的具体实现。

@Override
public void onRequestComplete(Context context) {Entry entry = context.getCurEntry();if (entry == null) {return;}Throwable error = entry.getError();SimpleErrorCounter counter = stat.currentWindow().value();if (error != null) {// 对异常请求数指标加一counter.getErrorCount().add(1);}// 对总请求数指标加一counter.getTotalCount().add(1);handleStateChangeWhenThresholdExceeded(error);
}

接下来看下 handleStateChangeWhenThresholdExceeded 方法的处理逻辑。

private void handleStateChangeWhenThresholdExceeded(Throwable error) {// 如果断路器的状态是OPEN,则直接返回if (currentState.get() == State.OPEN) {return;}// 如果断路器的状态是HALF_OPENif (currentState.get() == State.HALF_OPEN) {if (error == null) {// 将断路器的状态更新为CLOSED,然后重置慢请求数、总请求数指标fromHalfOpenToClose();} else {// 将断路器的状态更新为OPEN,然后更新下一次的熔断结束时间fromHalfOpenToOpen(1.0d);}// 直接返回return;}List<SimpleErrorCounter> counters = stat.values();long errCount = 0;long totalCount = 0;// 累加错误请求数、总请求数for (SimpleErrorCounter counter : counters) {errCount += counter.errorCount.sum();totalCount += counter.totalCount.sum();}// 如果总请求数 < 熔断降级规则中的minRequestAmount参数,则直接返回if (totalCount < minRequestAmount) {return;}double curCount = errCount;// 如果策略是统计异常数比例,则将异常数比例转化成错误请求数if (strategy == DEGRADE_GRADE_EXCEPTION_RATIO) {curCount = errCount * 1.0d / totalCount;}// 如果错误请求数 > 阈值if (curCount > threshold) {// 将断路器的状态更新为OPEN,然后更新下一次的熔断结束时间transformToOpen(curCount);}
}
http://www.mnyf.cn/news/39401.html

相关文章:

  • 微信公众号做的网站网络营销模式包括哪些
  • 网站建设明薇通网络售后好户外广告
  • spring boot 做网站2022年新闻摘抄十条
  • 做国厂家的网站免费外链生成器
  • 日本做a的漫画图片视频在线观看网站seo技术顾问阿亮
  • 政府网站建设的基本流程如何建立独立网站
  • seo做的比较好的网站的几个特征推广app的软文案例
  • 行政助手网站开发2022年最新新闻播报稿件
  • 湖南网红网站建设有限公司seo排名的方法
  • 印度做爰免费网站视频宁波网络推广软件
  • 网站系统维护阿里域名购买网站
  • 网站开发建设收费标准郑州seo使用教程
  • 怎么做一考试网站网上全网推广
  • 长沙网站优化诊断哪些网站可以免费推广
  • 中国icp备案的有多少企业网站手机建网站软件
  • wordpress在哪里改首页关键词标题整站优化系统厂家
  • 荔湾区网站建设刷排名的软件是什么
  • 北京建设委官方网站手机网页链接制作
  • 网站域名价格网店seo排名优化
  • 高校校园网站建设苏州关键词排名系统
  • 做网站需要多少固定带宽网站收录检测
  • 网站被重定向跳转如何用手机创建网站
  • 中国社会科学院网站优化培训学校
  • 国家网站标题颜色搭配中小企业网站
  • 天河网站建设推广360社区app
  • 永久3e38cos无风险seo怎么优化关键词排名培训
  • 做网站建设需要做哪些工作门户网站制作
  • 佛山定制网站建设外链seo
  • 扬州高端网站建设百度词条搜索排行
  • 网站建设研究背景数字化营销