mirror of
https://github.com/zhwei820/learn.lianglianglee.com.git
synced 2026-05-10 19:54:29 +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 class="current-tab" 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 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">
|
||||
@@ -477,9 +315,6 @@ function hide_canvas() {
|
||||
void login(String username,String password);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
</code></pre>
|
||||
|
||||
<p><strong>第二步:编写接口实现类</strong></p>
|
||||
@@ -495,9 +330,6 @@ function hide_canvas() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
</code></pre>
|
||||
|
||||
<p>现在我们不想搞那么麻烦,比如我们可以直接使用 Spring MVC 的拦截器实现用户鉴权,那么可以提供一个 SpringLoginService。</p>
|
||||
@@ -511,9 +343,6 @@ function hide_canvas() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
</code></pre>
|
||||
|
||||
<p><strong>第三步:通过配置使用 SpringLoginService 或 ShiroLoginService。</strong></p>
|
||||
@@ -527,9 +356,6 @@ function hide_canvas() {
|
||||
<p>文件:/resources/META-INF/services/接口名称,填写的内容为接口的实现类,多个实现类使用换行分开。</p>
|
||||
|
||||
<pre><code>com.wujiuye.spi.ShiroLoginService
|
||||
|
||||
|
||||
|
||||
</code></pre>
|
||||
|
||||
<p><strong>第四步:编写 main 方法测试使用 Java SPI 加载 LoginService。</strong></p>
|
||||
@@ -549,9 +375,6 @@ function hide_canvas() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
</code></pre>
|
||||
|
||||
<p>ServiceLoader(服务加载器)是 Java 提供的 SPI 机制的实现,调用 load 方法传入接口名就能获取到一个 ServiceLoader 实例,此时配置文件中注册的实现类是还没有加载到 JVM 的,只有通过 Iterator 遍历获取的时候,才会去加载实现类与实例化实现类。</p>
|
||||
@@ -567,9 +390,6 @@ function hide_canvas() {
|
||||
<p>com.alibaba.csp.sentinel.init.InitFunc 文件的默认配置如下:</p>
|
||||
|
||||
<pre><code class="language-txt"> com.alibaba.csp.sentinel.metric.extension.MetricCallbackInit
|
||||
|
||||
|
||||
|
||||
</code></pre>
|
||||
|
||||
<p>com.alibaba.csp.sentinel.slotchain.SlotChainBuilder 文件的默认配置如下:</p>
|
||||
@@ -577,9 +397,6 @@ function hide_canvas() {
|
||||
<pre><code class="language-java"> # Default slot chain builder
|
||||
|
||||
com.alibaba.csp.sentinel.slots.DefaultSlotChainBuilder
|
||||
|
||||
|
||||
|
||||
</code></pre>
|
||||
|
||||
<p>ServiceLoader 可加载接口配置文件中配置的所有实现类并且使用反射创建对象,但是否全部加载以及实例化还是由使用者自己决定。Sentinel 的 core 模块使用 Java SPI 机制加载 InitFunc 与 SlotChainBuilder 的实现上稍有不同,如果 InitFunc 接口的配置文件注册了多个实现类,那么这些注册的 InitFunc 实现类都会被 Sentinel 加载、实例化,且都会被使用,但 SlotChainBuilder 不同,如果注册多个实现类,Sentinel 只会加载和使用第一个。</p>
|
||||
@@ -625,9 +442,6 @@ function hide_canvas() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
</code></pre>
|
||||
|
||||
<p>Sentinel 加载 InitFunc 则不同,因为 Sentinel 允许存在多个初始化方法。InitFunc 可用于初始化配置限流、熔断规则,但在 Web 项目中我们基本不会使用它,更多的是通过监听 Spring 容器刷新完成事件再去初始化为 Sentinel 配置规则,如果使用动态数据源还可在监听到动态配置改变事件时重新加载规则,所以 InitFunc 我们基本使用不上。</p>
|
||||
@@ -635,9 +449,6 @@ function hide_canvas() {
|
||||
<p>Sentinel 使用 ServiceLoader 加载注册的 InitFunc 实现代码如下:</p>
|
||||
|
||||
<pre><code class="language-java">public final class InitExecutor {
|
||||
|
||||
|
||||
|
||||
public static void doInit() {
|
||||
|
||||
try {
|
||||
@@ -677,9 +488,6 @@ function hide_canvas() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
</code></pre>
|
||||
|
||||
<p>虽然 InitFunc 接口与 SlotChainBuilder 接口的配置文件在 sentinel-core 模块下,但我们不需要去修改 Sentinel 的源码,不需要修改 sentinel-core 模块下的接口配置文件,而只需要在当前项目的 /resource/META-INF/services 目录下创建一个与接口全名相同名称的配置文件,并在配置文件中添加接口的实现类即可。项目编译后不会覆盖 sentinel-core 模块下的相同名称的配置文件,而是将两个配置文件合并成一个配置文件。</p>
|
||||
@@ -691,9 +499,6 @@ function hide_canvas() {
|
||||
<p>Sentinel 默认使用的 SlotChainBuilder 是 DefaultSlotChainBuilder,其源码如下:</p>
|
||||
|
||||
<pre><code class="language-java">public class DefaultSlotChainBuilder implements SlotChainBuilder {
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
|
||||
public ProcessorSlotChain build() {
|
||||
@@ -719,13 +524,7 @@ function hide_canvas() {
|
||||
return chain;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
</code></pre>
|
||||
|
||||
<p>DefaultSlotChainBuilder 构造的 ProcessorSlotChain 注册了 NodeSelectorSlot、ClusterBuilderSlot、LogSlot、StatisticSlot、AuthoritySlot、SystemSlot、FlowSlot、DegradeSlot,但这些 ProcessorSlot 并非都是必须的,如果注册的这些 ProcessorSlot 有些我们用不到,那么我们可以自己实现一个 SlotChainBuilder,自己构造 ProcessorSlotChain。例如,我们可以将 LogSlot、AuthoritySlot、SystemSlot 去掉。</p>
|
||||
@@ -733,9 +532,6 @@ function hide_canvas() {
|
||||
<p>第一步,编写 MySlotChainBuilder,实现 SlotChainBuilder 接口,代码如下:</p>
|
||||
|
||||
<pre><code class="language-java">public class MySlotChainBuilder implements SlotChainBuilder {
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
|
||||
public ProcessorSlotChain build() {
|
||||
@@ -755,21 +551,12 @@ function hide_canvas() {
|
||||
return chain;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
</code></pre>
|
||||
|
||||
<p>第二步,在当前项目的 /resources/META-INF/services 目录下添加名为 com.alibaba.csp.sentinel.slotchain.SlotChainBuilder 的接口配置文件,并在配置文件中注册 MySlotChainBuilder。</p>
|
||||
|
||||
<pre><code class="language-txt">com.wujiuye.sck.provider.config.MySlotChainBuilder
|
||||
|
||||
|
||||
|
||||
</code></pre>
|
||||
|
||||
<p>在构造 ProcessorSlotChain 时,需注意 ProcessorSlot 的注册顺序,例如,NodeSelectorSlot 需作为 ClusterBuilderSlot 的前驱节点,ClusterBuilderSlot 需作为 StatisticSlot 的前驱节点,否则 Sentinel 运行会出现 bug。但你可以将 DegradeSlot 放在 FlowSlot 的前面,这就是我们上一篇说到的 ProcessorSlot 的排序。</p>
|
||||
@@ -797,9 +584,6 @@ function hide_canvas() {
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -807,9 +591,6 @@ function hide_canvas() {
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<a class="off-canvas-overlay" onclick="hide_canvas()"></a>
|
||||
|
||||
</div>
|
||||
@@ -825,17 +606,11 @@ function hide_canvas() {
|
||||
<script>
|
||||
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
|
||||
|
||||
|
||||
function gtag() {
|
||||
|
||||
dataLayer.push(arguments);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
gtag('js', new Date());
|
||||
|
||||
gtag('config', 'G-NPSEEVD756');
|
||||
@@ -861,9 +636,6 @@ function hide_canvas() {
|
||||
setCookie("lastPath", path)
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function setCookie(cname, cvalue) {
|
||||
|
||||
var d = new Date();
|
||||
@@ -875,9 +647,6 @@ function hide_canvas() {
|
||||
document.cookie = cname + "=" + cvalue + "; " + expires + ";path = /";
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function getCookie(cname) {
|
||||
|
||||
var name = cname + "=";
|
||||
@@ -895,12 +664,6 @@ function hide_canvas() {
|
||||
return "";
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
</html>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user