mirror of
https://github.com/zhwei820/learn.lianglianglee.com.git
synced 2025-10-18 07:53:45 +08:00
u
This commit is contained in:
@@ -25,13 +25,7 @@
|
||||
<meta name="generator" content="Hexo 4.2.0">
|
||||
|
||||
</head>
|
||||
|
||||
|
||||
|
||||
<body>
|
||||
|
||||
|
||||
|
||||
<div class="book-container">
|
||||
|
||||
<div class="book-sidebar">
|
||||
@@ -55,289 +49,148 @@
|
||||
<li><a href="/" class="current-tab">首页</a></li>
|
||||
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
<ul class="uncollapsible">
|
||||
|
||||
<li><a href="../">上一级</a></li>
|
||||
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
<ul class="uncollapsible">
|
||||
|
||||
<li>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a href="/专栏/深入理解 Sentinel(完)/01 开篇词:一次服务雪崩问题排查经历.md.html">01 开篇词:一次服务雪崩问题排查经历.md.html</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a href="/专栏/深入理解 Sentinel(完)/02 为什么需要服务降级以及常见的几种降级方式.md.html">02 为什么需要服务降级以及常见的几种降级方式.md.html</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a href="/专栏/深入理解 Sentinel(完)/03 为什么选择 Sentinel,Sentinel 与 Hystrix 的对比.md.html">03 为什么选择 Sentinel,Sentinel 与 Hystrix 的对比.md.html</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a href="/专栏/深入理解 Sentinel(完)/04 Sentinel 基于滑动窗口的实时指标数据统计.md.html">04 Sentinel 基于滑动窗口的实时指标数据统计.md.html</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a href="/专栏/深入理解 Sentinel(完)/05 Sentinel 的一些概念与核心类介绍.md.html">05 Sentinel 的一些概念与核心类介绍.md.html</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a href="/专栏/深入理解 Sentinel(完)/06 Sentinel 中的责任链模式与 Sentinel 的整体工作流程.md.html">06 Sentinel 中的责任链模式与 Sentinel 的整体工作流程.md.html</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a href="/专栏/深入理解 Sentinel(完)/07 Java SPI 及 SPI 在 Sentinel 中的应用.md.html">07 Java SPI 及 SPI 在 Sentinel 中的应用.md.html</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a href="/专栏/深入理解 Sentinel(完)/08 资源指标数据统计的实现全解析(上).md.html">08 资源指标数据统计的实现全解析(上).md.html</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a href="/专栏/深入理解 Sentinel(完)/09 资源指标数据统计的实现全解析(下).md.html">09 资源指标数据统计的实现全解析(下).md.html</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a href="/专栏/深入理解 Sentinel(完)/10 限流降级与流量效果控制器(上).md.html">10 限流降级与流量效果控制器(上).md.html</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a href="/专栏/深入理解 Sentinel(完)/11 限流降级与流量效果控制器(中).md.html">11 限流降级与流量效果控制器(中).md.html</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a href="/专栏/深入理解 Sentinel(完)/12 限流降级与流量效果控制器(下).md.html">12 限流降级与流量效果控制器(下).md.html</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a href="/专栏/深入理解 Sentinel(完)/13 熔断降级与系统自适应限流.md.html">13 熔断降级与系统自适应限流.md.html</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a href="/专栏/深入理解 Sentinel(完)/14 黑白名单限流与热点参数限流.md.html">14 黑白名单限流与热点参数限流.md.html</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
|
||||
|
||||
<a class="current-tab" href="/专栏/深入理解 Sentinel(完)/15 自定义 ProcessorSlot 实现开关降级.md.html">15 自定义 ProcessorSlot 实现开关降级.md.html</a>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a href="/专栏/深入理解 Sentinel(完)/16 Sentinel 动态数据源:规则动态配置.md.html">16 Sentinel 动态数据源:规则动态配置.md.html</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a href="/专栏/深入理解 Sentinel(完)/17 Sentinel 主流框架适配.md.html">17 Sentinel 主流框架适配.md.html</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a href="/专栏/深入理解 Sentinel(完)/18 Sentinel 集群限流的实现(上).md.html">18 Sentinel 集群限流的实现(上).md.html</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a href="/专栏/深入理解 Sentinel(完)/19 Sentinel 集群限流的实现(下).md.html">19 Sentinel 集群限流的实现(下).md.html</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a href="/专栏/深入理解 Sentinel(完)/20 结束语:Sentinel 对应用的性能影响如何?.md.html">20 结束语:Sentinel 对应用的性能影响如何?.md.html</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a href="/专栏/深入理解 Sentinel(完)/21 番外篇:Sentinel 1.8.0 熔断降级新特性解读.md.html">21 番外篇:Sentinel 1.8.0 熔断降级新特性解读.md.html</a>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="sidebar-toggle" onclick="sidebar_toggle()" onmouseover="add_inner()" onmouseleave="remove_inner()">
|
||||
|
||||
<div class="sidebar-toggle-inner"></div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<script>
|
||||
|
||||
function add_inner() {
|
||||
@@ -347,9 +200,6 @@
|
||||
inner.classList.add('show')
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function remove_inner() {
|
||||
|
||||
let inner = document.querySelector('.sidebar-toggle-inner')
|
||||
@@ -357,9 +207,6 @@
|
||||
inner.classList.remove('show')
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function sidebar_toggle() {
|
||||
|
||||
let sidebar_toggle = document.querySelector('.sidebar-toggle')
|
||||
@@ -389,9 +236,6 @@
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function open_sidebar() {
|
||||
|
||||
let sidebar = document.querySelector('.book-sidebar')
|
||||
@@ -415,13 +259,7 @@ function hide_canvas() {
|
||||
overlay.classList.remove('show')
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
<div class="off-canvas-content">
|
||||
|
||||
<div class="columns">
|
||||
@@ -481,9 +319,6 @@ public @interface SwitchDegrade {
|
||||
String key() default "";
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
</code></pre>
|
||||
|
||||
<p>提示:如果是应用在实际项目中,建议为 @SwitchDegrade 注解添加一个前缀属性,限制同一个应用下的开关 key 都是有同一个前缀,避免多个应用之间的缓存 key 冲突。</p>
|
||||
@@ -501,9 +336,6 @@ public class SwitchDegradeAspect {
|
||||
public void degradePointCut() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
||||
* 拦截请求判断是否开启开关降级
|
||||
@@ -531,9 +363,6 @@ public class SwitchDegradeAspect {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
</code></pre>
|
||||
|
||||
<p>如代码所示,SwitchDegradeAspect 拦截目标方法的执行,先从方法上的 @SwitchDegrade 注解获取开关的缓存 key,根据 key 从 redis 读取当前开关的状态,如果 key 存在且 value 为 true,则抛出一个开关降级异常。</p>
|
||||
@@ -549,9 +378,6 @@ public class SwitchDegradeAspect {
|
||||
return new BaseResponse(ResultCode.SERVICE_DEGRADE, ex.getMessage());
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
</code></pre>
|
||||
|
||||
<p>提示:如果是整合 OpenFeign 使用,且配置了 Fallback,则全局异常可以不配置。</p>
|
||||
@@ -575,9 +401,6 @@ public class DemoController {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
</code></pre>
|
||||
|
||||
<p>这种方式虽然能满足需求,但也有一个缺点,就是必须要在方法上添加 @SwitchDegrade 注解,配置不够灵活,但也不失为一个好方法。</p>
|
||||
@@ -627,9 +450,6 @@ public class SwitchRule {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
</code></pre>
|
||||
|
||||
<p>灵活,不仅仅只是去掉注解的使用,更需要可以灵活指定开关控制某些资源,因此,配置开关控制的资源应支持这几种情况:指定该开关只控制哪些资源、除了某些资源外其它都受控制、控制全部。所以,SwitchRule 的资源配置与 Sentinel 的熔断降级、限流降级规则配置不一样,SwitchRule 支持三种资源配置方式:</p>
|
||||
@@ -663,9 +483,6 @@ public class SwitchRule {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
</code></pre>
|
||||
|
||||
<p>SwitchRuleManager 提供两个接口:</p>
|
||||
@@ -681,9 +498,6 @@ public class SwitchRule {
|
||||
<p>同样地,在 Sentinel 中,一般会将检查规则是否达到触发降级的阈值由 XxxRuleChecker 完成,即 Xxx 规则检查员,所以我们定义的开关降级规则检查员命名为 SwitchRuleChecker,由 SwitchRuleChecker 检查开关是否打开,如果开关打开则触发开关降级。SwitchRuleChecker 的代码实现如下:</p>
|
||||
|
||||
<pre><code class="language-java">public class SwitchRuleChecker {
|
||||
|
||||
|
||||
|
||||
public static void checkSwitch(ResourceWrapper resource, Context context) throws SwitchException {
|
||||
|
||||
Set<SwitchRule> switchRuleSet = SwitchRuleManager.getRules();
|
||||
@@ -733,13 +547,7 @@ public class SwitchRule {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
</code></pre>
|
||||
|
||||
<p>如代码所示,SwitchRuleChecker 从 SwitchRuleManager 获取配置的开关降级规则,遍历开关降级规则,如果开关打开,且匹配到当前资源名称被该开关控制,则抛出 SwitchException。</p>
|
||||
@@ -753,9 +561,6 @@ public class SwitchRule {
|
||||
<p>最后,还需要自定义实现开关降级功能的切入点 SwitchSlot。SwitchSlot 继承 AbstractLinkedProcessorSlot,在 entry 方法中调用 SwitchRuleChecker#checkSwitch 方法检查当前资源是否已经降级。SwitchSlot 的代码实现如下:</p>
|
||||
|
||||
<pre><code class="language-java">public class SwitchSlot extends AbstractLinkedProcessorSlot<Object> {
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
|
||||
public void entry(Context context, ResourceWrapper resourceWrapper, Object param, int count, boolean prioritized, Object... args) throws Throwable {
|
||||
@@ -765,9 +570,6 @@ public class SwitchRule {
|
||||
fireEntry(context, resourceWrapper, param, count, prioritized, args);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
|
||||
public void exit(Context context, ResourceWrapper resourceWrapper, int count, Object... args) {
|
||||
@@ -775,13 +577,7 @@ public class SwitchRule {
|
||||
fireExit(context, resourceWrapper, count, args);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
</code></pre>
|
||||
|
||||
<p>自定义 ProcessorSlotChain 构建器 MySlotChainBuilder,将自定义的 SwitchSlot 添加到 ProcessorSlot 链表的末尾。当然,可以添加到任何位置,因为 SwitchSlot 没有用到指标数据,SwitchSlot 放置何处都不会影响到 Sentinel 的正常工作。</p>
|
||||
@@ -803,9 +599,6 @@ public class SwitchRule {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
</code></pre>
|
||||
|
||||
<p>MySlotChainBuilder 继承 DefaultSlotChainBuilder 只是为了使用 DefaultSlotChainBuilder#build 方法,简化 ProcessorSlotChain 的构造步骤,只需要在 DefaultSlotChainBuilder 构造的链表尾部添加一个 SwitchSlot 即可。</p>
|
||||
@@ -815,9 +608,6 @@ public class SwitchRule {
|
||||
<p>在当前项目的 resources 资源目录的 META-INF/service 目录下创建一个名为“com.alibaba.csp.sentinel.slotchain.SlotChainBuilder”的文件,在该文件中配置 MySlotChainBuilder 类的全名,例如:</p>
|
||||
|
||||
<pre><code class="language-txt">com.wujiuye.demo.common.sentinel.MySlotChainBuilder
|
||||
|
||||
|
||||
|
||||
</code></pre>
|
||||
|
||||
<p>现在,您可以在 MySlotChainBuilder#build 方法中添加断点,然后启动项目,正常情况下程序会在该断点停下。但由于我们并未配置开关降级规则,所以还看不到效果。</p>
|
||||
@@ -827,9 +617,6 @@ public class SwitchRule {
|
||||
<pre><code class="language-java">@Configuration
|
||||
|
||||
public class SentinelRuleConfiguration{
|
||||
|
||||
|
||||
|
||||
static {
|
||||
|
||||
Set<SwitchRule> rules = new HashSet<>();
|
||||
@@ -857,9 +644,6 @@ public class SentinelRuleConfiguration{
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
</code></pre>
|
||||
|
||||
<p>上面代码配置了一个开关降级规则,该降级规则只控制接口(资源)<code>"/v1/test/demo"</code>,SwitchRule.status 控制开关是否打开,测试这里就不演示了。当然,这种配置方式只适用于本地测试,实际项目中我们可通过动态配置实现,这将在后面介绍 Sentinel 动态数据源时再介绍如何实现。</p>
|
||||
@@ -885,9 +669,6 @@ public class SentinelRuleConfiguration{
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -895,9 +676,6 @@ public class SentinelRuleConfiguration{
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<a class="off-canvas-overlay" onclick="hide_canvas()"></a>
|
||||
|
||||
</div>
|
||||
@@ -913,17 +691,11 @@ public class SentinelRuleConfiguration{
|
||||
<script>
|
||||
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
|
||||
|
||||
|
||||
function gtag() {
|
||||
|
||||
dataLayer.push(arguments);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
gtag('js', new Date());
|
||||
|
||||
gtag('config', 'G-NPSEEVD756');
|
||||
@@ -949,9 +721,6 @@ public class SentinelRuleConfiguration{
|
||||
setCookie("lastPath", path)
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function setCookie(cname, cvalue) {
|
||||
|
||||
var d = new Date();
|
||||
@@ -963,9 +732,6 @@ public class SentinelRuleConfiguration{
|
||||
document.cookie = cname + "=" + cvalue + "; " + expires + ";path = /";
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function getCookie(cname) {
|
||||
|
||||
var name = cname + "=";
|
||||
@@ -983,12 +749,6 @@ public class SentinelRuleConfiguration{
|
||||
return "";
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
</html>
|
||||
|
||||
|
Reference in New Issue
Block a user