PageSourceSearch

https://fengjx.com/sentinel-dashboard-apollo/

html fengjx.com collected 2026-09-25 22:31:50 UTC 61,644 bytes, 127 lines download raw bytes

1<!DOCTYPE html>
2<html lang="zh-CN">
3  <head>
4    <meta charset="utf-8">
5    <meta name="viewport" content="width=device-width,initial-scale=1">
6    <title>不改一行源码,实现 sentinel-dashboard 所有配置支持 apollo 持久化 | 铁匠</title>
7    <meta name="generator" content="VuePress 1.9.9">
8    <link rel="icon" href="/avatar.jpg">
9    <meta name="description" content="不改一行源码,让 sentinel-dashboard 所有配置支持 apollo 持久化">
10    <meta name="apple-mobile-web-app-capable" content="yes">
11    <meta name="apple-mobile-web-app-status-bar-style" content="black">
12    <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no">
13    
14    <link rel="preload" href="/assets/css/0.styles.b4b4d60e.css" as="style"><link rel="preload" href="/assets/js/app.4aaf6adf.js" as="script"><link rel="preload" href="/assets/js/2.1cbe77ec.js" as="script"><link rel="preload" href="/assets/js/4.f35e593d.js" as="script"><link rel="prefetch" href="/assets/js/10.4714af69.js"><link rel="prefetch" href="/assets/js/100.10735728.js"><link rel="prefetch" href="/assets/js/101.437574fb.js"><link rel="prefetch" href="/assets/js/102.886d99a9.js"><link rel="prefetch" href="/assets/js/103.256af495.js"><link rel="prefetch" href="/assets/js/104.c4b5ac12.js"><link rel="prefetch" href="/assets/js/105.605c76c6.js"><link rel="prefetch" href="/assets/js/106.a2aba0ad.js"><link rel="prefetch" href="/assets/js/107.dd301d06.js"><link rel="prefetch" href="/assets/js/108.3e618ee3.js"><link rel="prefetch" href="/assets/js/109.d0ef70f5.js"><link rel="prefetch" href="/assets/js/11.75b9a3e9.js">
14<link rel="prefetch" href="/assets/js/110.02b46436.js"><link rel="prefetch" href="/assets/js/111.69b98dad.js"><link rel="prefetch" href="/assets/js/112.14ba1c22.js"><link rel="prefetch" href="/assets/js/113.99232540.js"><link rel="prefetch" href="/assets/js/114.69aa74e2.js"><link rel="prefetch" href="/assets/js/12.7bbd1e4b.js"><link rel="prefetch" href="/assets/js/13.89edc50b.js"><link rel="prefetch" href="/assets/js/14.6f271807.js"><link rel="prefetch" href="/assets/js/15.e17996e6.js"><link rel="prefetch" href="/assets/js/16.892da53c.js"><link rel="prefetch" href="/assets/js/17.cd22c0ff.js"><link rel="prefetch" href="/assets/js/18.ad0acd10.js"><link rel="prefetch" href="/assets/js/19.8ccb0a4a.js"><link rel="prefetch" href="/assets/js/20.41af1e75.js"><link rel="prefetch" href="/assets/js/21.7de074d1.js"><link rel="prefetch" href="/assets/js/22.7ebfaaf0.js"><link rel="prefetch" href="/assets/js/23.7abdf865.js"><link rel="prefetch" href="/assets/js/24.8927cad4.js"><link rel="prefetch" href="/assets/js/25.1bfa5a29.js"><link rel="prefetch" href="/assets/js/26.0ff2a38c.js"><link rel="prefetch" href="/assets/js/27.a0030182.js"><link rel="prefetch" href="/assets/js/28.4d63a6d6.js"><link rel="prefetch" href="/assets/js/29.d4a39b32.js"><link rel="prefetch" href="/assets/js/3.4d86779a.js"><link rel="prefetch" href="/assets/js/30.2cefed39.js"><link rel="prefetch" href="/assets/js/31.b7440d40.js"><link rel="prefetch" href="/assets/js/32.e27e45de.js"><link rel="prefetch" href="/assets/js/33.3045888a.js"><link rel="prefetch" href="/assets/js/34.d7197105.js"><link rel="prefetch" href="/assets/js/35.ffb3832a.js"><link rel="prefetch" href="/assets/js/36.445b5b3f.js"><link rel="prefetch" href="/assets/js/37.4e27fb14.js"><link rel="prefetch" href="/assets/js/38.7253f1f7.js"><link rel="prefetch" href="/assets/js/39.0fddff84.js"><link rel="prefetch" href="/assets/js/40.d46aa001.js"><link rel="prefetch" href="/assets/js/41.0dbc86ae.js"><link rel="prefetch" href="/assets/js/42.06c834cb.js"><link rel="prefetch" href="/assets/js/43.744a8585.js"><link rel="prefetch" href="/assets/js/44.472c8b80.js"><link rel="prefetch" href="/assets/js/45.b15443a1.js"><link rel="prefetch" href="/assets/js/46.59e86dd7.js"><link rel="prefetch" href="/assets/js/47.3e61e857.js"><link rel="prefetch" href="/assets/js/48.d7bba2dc.js"><link rel="prefetch" href="/assets/js/49.2ffc3755.js"><link rel="prefetch" href="/assets/js/5.f49c84d0.js"><link rel="prefetch" href="/assets/js/50.34fc1d02.js"><link rel="prefetch" href="/assets/js/51.7b8535c1.js"><link rel="prefetch" href="/assets/js/52.b7d758da.js"><link rel="prefetch" href="/assets/js/53.080d0cad.js"><link rel="prefetch" href="/assets/js/54.934c0f26.js"><link rel="prefetch" href="/assets/js/55.ff305b9a.js"><link rel="prefetch" href="/assets/js/56.368e0e31.js"><link rel="prefetch" href="/assets/js/57.73bf8734.js"><link rel="prefetch" href="/assets/js/58.9df64e2b.js"><link rel="prefetch" href="/assets/js/59.a3a6256a.js"><link rel="prefetch" href="/assets/js/6.aea057c4.js"><link rel="prefetch" href="/assets/js/60.0676bff9.js"><link rel="prefetch" href="/assets/js/61.2275bd97.js"><link rel="prefetch" href="/assets/js/62.c1212903.js"><link rel="prefetch" href="/assets/js/63.0857caf2.js"><link rel="prefetch" href="/assets/js/64.27f29440.js"><link rel="prefetch" href="/assets/js/65.8e6d28ff.js"><link rel="prefetch" href="/assets/js/66.a5450fcb.js"><link rel="prefetch" href="/assets/js/67.6e521157.js"><link rel="prefetch" href="/assets/js/68.60a287b8.js"><link rel="prefetch" href="/assets/js/69.3f16344d.js"><link rel="prefetch" href="/assets/js/7.64d796f6.js"><link rel="prefetch" href="/assets/js/70.860a986b.js"><link rel="prefetch" href="/assets/js/71.7a9b24be.js"><link rel="prefetch" href="/assets/js/72.770bec22.js"><link rel="prefetch" href="/assets/js/73.468cb0f1.js"><link rel="prefetch" href="/assets/js/74.f7ba2c1f.js"><link rel="prefetch" href="/assets/js/75.d57cdc3d.js"><link rel="prefetch" href="/assets/js/76.d1ad8a1f.js"><link rel="prefetch" href="/assets/js/77.a3709ccb.js"><link rel="prefetch" href="/assets/js/78.7df81f81.js"><link rel="prefetch" href="/assets/js/79.ac117d2b.js"><link rel="prefetch" href="/assets/js/8.7ce93dbf.js"><link rel="prefetch" href="/assets/js/80.ed4af636.js"><link rel="prefetch" href="/assets/js/81.edc75d15.js"><link rel="prefetch" href="/assets/js/82.abda0414.js">
14<link rel="prefetch" href="/assets/js/83.b7bded87.js"><link rel="prefetch" href="/assets/js/84.ca98fdc7.js"><link rel="prefetch" href="/assets/js/85.432b78d9.js"><link rel="prefetch" href="/assets/js/86.7747f32a.js"><link rel="prefetch" href="/assets/js/87.8d3f36ec.js"><link rel="prefetch" href="/assets/js/88.2143a0c0.js"><link rel="prefetch" href="/assets/js/89.70448dbf.js"><link rel="prefetch" href="/assets/js/9.2d64845a.js"><link rel="prefetch" href="/assets/js/90.a888dff7.js"><link rel="prefetch" href="/assets/js/91.7ae92518.js"><link rel="prefetch" href="/assets/js/92.9d326543.js"><link rel="prefetch" href="/assets/js/93.16e582ff.js"><link rel="prefetch" href="/assets/js/94.ac10407c.js"><link rel="prefetch" href="/assets/js/95.3a62f76d.js"><link rel="prefetch" href="/assets/js/96.012466dd.js"><link rel="prefetch" href="/assets/js/97.7add8027.js"><link rel="prefetch" href="/assets/js/98.5df8df77.js"><link rel="prefetch" href="/assets/js/99.7e18b041.js">
15    <link rel="stylesheet" href="/assets/css/0.styles.b4b4d60e.css">
16  </head>
17  <body class="theme-mode-light">
18    <div id="app" data-server-rendered="true"><div class="theme-container sidebar-open have-rightmenu"><header class="navbar blur"><div title="目录" class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/" class="home-link router-link-active"><img src="/avatar.jpg" alt="铁匠" class="logo"> <span class="site-name can-hide">铁匠</span></a> <div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><a href="/" class="nav-link">首页</a></div><div class="nav-item"><a href="/go/" class="nav-link">golang</a></div><div class="nav-item"><a href="/java/" class="nav-link">java</a></div><div class="nav-item"><a href="/architect/" class="nav-link">架构</a></div><div class="nav-item"><a href="/alg/lru-cache/" class="nav-link">常用算法</a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="书单" class="dropdown-title"><!----> <span class="title" style="display:;">书单</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/book/java/alibaba-java-manual/" class="nav-link">Java</a></li><li class="dropdown-item"><!----> <a href="/book/nginx/" class="nav-link">nginx</a></li><li class="dropdown-item"><!----> <a href="/book/sre/vbird-linux-basic-4/" class="nav-link">系统运维</a></li><li class="dropdown-item"><!----> <a href="/book/security/white-hat-web-security/" class="nav-link">系统安全</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="数据库&amp;缓存" class="dropdown-title"><!----> <span class="title" style="display:;">数据库&amp;缓存</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/pages/8f6be4/" class="nav-link">mysql</a></li><li class="dropdown-item"><!----> <a href="/pages/7d45f8/" class="nav-link">redis</a></li></ul></div></div><div class="nav-item"><a href="/categories/?category=%E5%8F%82%E8%80%83%E6%96%87%E6%A1%A3&amp;.html#" class="nav-link">参考文档</a></div><div class="nav-item"><a href="/about/" class="nav-link">关于</a></div><div class="nav-item"><a href="/awesome/" class="nav-link">收藏</a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="索引" class="dropdown-title"><a href="/archives/" class="link-title">索引</a> <span class="title" style="display:none;">索引</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/categories/" class="nav-link">分类</a></li><li class="dropdown-item"><!----> <a href="/tags/" class="nav-link">标签</a></li><li class="dropdown-item"><!----> <a href="/archives/" class="nav-link">
18归档</a></li></ul></div></div> <a href="https://github.com/fengjx" target="_blank" rel="noopener noreferrer" class="repo-link">
19    GitHub
20    <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></nav></div></header> <div class="sidebar-mask"></div> <div class="sidebar-hover-trigger"></div> <aside class="sidebar" style="display:none;"><div class="blogger"><img src="/avatar.jpg"> <div class="blogger-info"><h3>铁匠</h3> <span>不予评判的专注当下</span></div></div> <nav class="nav-links"><div class="nav-item"><a href="/" class="nav-link">首页</a></div><div class="nav-item"><a href="/go/" class="nav-link">golang</a></div><div class="nav-item"><a href="/java/" class="nav-link">java</a></div><div class="nav-item"><a href="/architect/" class="nav-link">架构</a></div><div class="nav-item"><a href="/alg/lru-cache/" class="nav-link">常用算法</a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="书单" class="dropdown-title"><!----> <span class="title" style="display:;">书单</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/book/java/alibaba-java-manual/" class="nav-link">Java</a></li><li class="dropdown-item"><!----> <a href="/book/nginx/" class="nav-link">nginx</a></li><li class="dropdown-item"><!----> <a href="/book/sre/vbird-linux-basic-4/" class="nav-link">系统运维</a></li><li class="dropdown-item"><!----> <a href="/book/security/white-hat-web-security/" class="nav-link">系统安全</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="数据库&amp;缓存" class="dropdown-title"><!----> <span class="title" style="display:;">数据库&amp;缓存</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/pages/8f6be4/" class="nav-link">mysql</a></li><li class="dropdown-item"><!----> <a href="/pages/7d45f8/" class="nav-link">redis</a></li></ul></div></div><div class="nav-item"><a href="/categories/?category=%E5%8F%82%E8%80%83%E6%96%87%E6%A1%A3&amp;.html#" class="nav-link">参考文档</a></div><div class="nav-item"><a href="/about/" class="nav-link">关于</a></div><div class="nav-item"><a href="/awesome/" class="nav-link">收藏</a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="索引" class="dropdown-title"><a href="/archives/" class="link-title">索引</a> <span class="title" style="display:none;">索引</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/categories/" class="nav-link">分类</a></li><li class="dropdown-item"><!----> <a href="/tags/" class="nav-link">标签</a></li><li class="dropdown-item"><!----> <a href="/archives/" class="nav-link">归档</a></li></ul></div></div> <a href="https://github.com/fengjx" target="_blank" rel="noopener noreferrer" class="repo-link">
21    GitHub
22    <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></nav>  <ul class="sidebar-links"><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>概览</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>设计模式</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>性能优化</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>分布式</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>网关</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading open"><span>流量治理</span> <span class="arrow down"></span></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/sentinel-dashboard-apollo/" aria-current="page" class="active sidebar-link">不改一行源码,实现 sentinel-dashboard 所有配置支持 apollo 持久化</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header level2"><a href="/sentinel-dashboard-apollo/#sentinel-dashboard-apollo-定制版" class="sidebar-link">sentinel-dashboard apollo 定制版</a></li><li class="sidebar-sub-header level2"><a href="/sentinel-dashboard-apollo/#sentinel-dashboard-为什么需要定制" class="sidebar-link">sentinel-dashboard 为什么需要定制</a></li><li class="sidebar-sub-header level2"><a href="/sentinel-dashboard-apollo/#方案选型" class="sidebar-link">方案选型</a></li><li class="sidebar-sub-header level2"><a href="/sentinel-dashboard-apollo/#源码分析" class="sidebar-link">源码分析</a></li><li class="sidebar-sub-header level2"><a href="/sentinel-dashboard-apollo/#改造实现" class="sidebar-link">改造实现</a></li><li class="sidebar-sub-header level2"><a href="/sentinel-dashboard-apollo/#改造后的效果" class="sidebar-link">改造后的效果</a></li><li class="sidebar-sub-header level2"><a href="/sentinel-dashboard-apollo/#升级-版本维护" class="sidebar-link">升级&amp;版本维护</a></li><li class="sidebar-sub-header level2"><a href="/sentinel-dashboard-apollo/#相关文档" class="sidebar-link">相关文档</a></li></ul></li><li><a href="/sentinel-dashboard-apollo-wiki/" class="sidebar-link">sentinel-dashboard-apollo 使用</a></li></ul></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>数据治理</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>
22云原生</span> <span class="arrow right"></span></p> <!----></section></li></ul> </aside> <div><main class="page"><div class="theme-vdoing-wrapper "><div class="articleInfo-wrap" data-v-06225672><div class="articleInfo" data-v-06225672><ul class="breadcrumbs" data-v-06225672><li data-v-06225672><a href="/" title="首页" class="iconfont icon-home router-link-active" data-v-06225672></a></li> <li data-v-06225672><a href="/categories/?category=%E6%9E%B6%E6%9E%84" title="分类" data-v-06225672>架构</a></li><li data-v-06225672><a href="/categories/?category=%E6%B5%81%E9%87%8F%E6%B2%BB%E7%90%86" title="分类" data-v-06225672>流量治理</a></li></ul> <div class="info" data-v-06225672><div title="作者" class="author iconfont icon-touxiang" data-v-06225672><a href="https://github.com/xugaoyi" target="_blank" title="作者" class="beLink" data-v-06225672>xugaoyi</a></div> <div title="创建时间" class="date iconfont icon-riqi" data-v-06225672><a href="javascript:;" data-v-06225672>2022-07-30</a></div> <!----></div></div></div> <!----> <div class="content-wrapper"><div class="right-menu-wrapper"><div class="right-menu-margin"><div class="right-menu-title">目录</div> <div class="right-menu-content"></div></div></div> <h1><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAAAXNSR0IArs4c6QAABKFJREFUSA3tVl1oFVcQnrMbrak3QUgkya1akpJYcrUtIqW1JvFBE9LiQ5v6JmJpolbMg32rVrhgoYK0QiMY6i9Y6EMaW5D+xFJaTYItIuK2Kr3+BJNwkxBj05sQY3b3nM6cs2dv9t7NT/vQJw/sndk5M/PNzJkzewGerP+pAmy+ON8lLzUJgA8ZYxYIYZmGYRnctDaWvJJAmTtfP1pvXsBCCPP8QFcCaRkZYACgDZFO4stNIcBCajEOlmmC9XpJ9bAGCaPaPmzPl32dvLSVu3BWCTQs0XQQ6g0DYgwLIoAZbBCdW/i+781o1VVlm/410mw4h06Y7bIPHNyWDyL4FHkX03Q8SrzNhZTZriieckWt7cL6MM85YcLpsi/7O9/iXFT6MswI0DmmpkSaJ0qLxFIm3+i1THHB3zmBH3PYx9CcykcLOeQVVa7QtdxTgQgEleX2AjHYfwA+2ddV77ruGoJUbhGDI09YSNXyMpUt5ylOzxgbUmtOp7NmbNt8v3arjTBfYELmLUV+M+nSawNNAUqpT3ClJWg5I3BLT+cGW/DXNGCa6tx1aakCGEigArTn4TDIPdrXXYKCZNrHLMCOEPvHBlLQ99s9eHB7EB6NTki73CVPQ2F5MSx/uRQixfmq7rK0wYD8w8E905bnPDfwoWs/rfv93NWN/ZfvwsLIU7A09gxECyISeGJkHAau98L97tuw7NXnoPyNF8FcYGLGKsOs0mN3OEyec9esGW/ZEl945dTP34wlR2FZVQWU1q0Cw8Tr7p+hgLLNL0FPxx/Q35mA8aEUrH6nCgwEl0tn7wUiZYJnNRh6DK4UH/k0lfyrsBKdPVv/AriGIQcEDQZ65LBAGe2Rzui9Ybjz7XUppz1/uKBbyVPGkN3ZAeC6hr0x7Nr38N5+EqkoOm17xpoqR9ohQF55ERSvr4Dkr3chNfC3DMzGJlNBElW8w9nsGQvhNGIzDkXzCg8cLK951xHsFBlTJspJNi3ZFIMF2AeDV3q8DNOB+YHi6QTrChDIWDBRi5U5f+ZMfJLu3ccrqxtdxk4SKH336LFxSmkqefwU5T8fhdSdQf9IVKD6aNiwI/hnmcAZ91isYMJIaCUCx9W098+LgruikeTqzqqxKPUwqJyCPJiyemVVZBOijDGjD38Os0jOiSPL1z3SPjXNANbiNPXAdzTfukjjuknNBbyz3nwgTd3AVFqUJ5hpHlq9MveLnWwttUfoygBmvVjuikxND3znrhsELnZk7k+OjIGxeNEkomyLVta0xxn+HZhjBc4YZ/AFjHjz9u3xRZl2BN4aq9nFwWh16IrQ1aHHEd3j1+4/dB9OtH4e29A2H1DyHQRmOSfQZ1Fy7MHBTGB6J/Djq6p3OxyO2cB+4Car7v/o3GXgfAkj23+x9ID1Teoamo/SXcbvSf2PX7Vc8DdCmE1vN9di+32P9/5YR3vLnhCVGUWBjEkr3yh4H8v9CzmsbdhzOKzsJKM90iFdaTMjRPhGVsakRvOaRidljo6H6G7j+ctrJpsP+4COhDIl0La2+FS4+5mlocBaXY5QnGZysIBYoeSsl5qQzrSj/cgNrfuEzlWBfwA+EjrZyWUvpAAAAABJRU5ErkJggg==">不改一行源码,实现 sentinel-dashboard 所有配置支持 apollo 持久化<!----></h1>  <div class="theme-vdoing-content content__default"><h2 id="sentinel-dashboard-apollo-定制版"><a href="#sentinel-dashboard-apollo-定制版" class="header-anchor">#</a> sentinel-dashboard apollo 定制版</h2> <p>sentinel-dashboard-apollo 是从官方 <a href="https://github.com/alibaba/Sentinel" target="_blank" rel="noopener noreferrer">Sentinel<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a> fork 的 dashboard 定制版,支持所有配置持久化到 apollo。</p> <ul><li>github:<a href="https://github.com/fengjx/Sentinel" target="_blank" rel="noopener noreferrer">https://github.com/fengjx/Sentinel<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound">
22<path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li> <li>gitee:<a href="https://gitee.com/fengjx/Sentinel" target="_blank" rel="noopener noreferrer">https://gitee.com/fengjx/Sentinel<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li> <li>使用文档:<a href="http://blog.fengjx.com/sentinel-dashboard-apollo-wiki" target="_blank" rel="noopener noreferrer">http://blog.fengjx.com/sentinel-dashboard-apollo-wiki<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li> <li>spring-boot(cloud) 整合 demo: <a href="https://github.com/fengjx/sentinel-dashboard-demo" target="_blank" rel="noopener noreferrer">https://github.com/fengjx/sentinel-dashboard-demo<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul> <h2 id="sentinel-dashboard-为什么需要定制"><a href="#sentinel-dashboard-为什么需要定制" class="header-anchor">#</a> sentinel-dashboard 为什么需要定制</h2> <p><a href="https://github.com/alibaba/Sentinel" target="_blank" rel="noopener noreferrer">Sentinel<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a> 是阿里巴巴开源的流量治理组件。功能非常齐全,包括了:请求过滤、降级、限流、流量监控等功能。如果对 sentinel 还不是很了解可以查看官方文档:<a href="https://sentinelguard.io/zh-cn/docs/basic-api-resource-rule.html" target="_blank" rel="noopener noreferrer">https://sentinelguard.io/zh-cn/docs/basic-api-resource-rule.html<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></p> <p>虽然 sentinel 的设计非常优秀,基本上满足了流量治理的所有需求,但是 sentinel-dashboard(管理后台)的配置都是存储在内存,在服务重启后就会丢失。所以 sentinel 目前是不具备在生产环境上使用的。即使 sentinel 客户端是支持了从 apollo、consul、etcd、eureka、nacos、redis、spring-cloud-config、zookeeper 读取配置,但是如果不使用 dashboard,直接手动修改配置的话,官网也没有提供详细的参数配置文档,想知道哪些参数可配置,需要自己查看源码,使用上非常不友好。</p> <p>而这个问题早在 2020 年就有人提出来了(github issue) dashboard 配置持久化功能,但是官方至今(2
22022-07)依然没有实现这个功能。</p> <div class="custom-block tip"><p class="custom-block-title">issue</p> <p><a href="https://github.com/alibaba/Sentinel/issues/1759" target="_blank" rel="noopener noreferrer">https://github.com/alibaba/Sentinel/issues/1759<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></p> <p><a href="https://github.com/alibaba/Sentinel/issues/2179" target="_blank" rel="noopener noreferrer">https://github.com/alibaba/Sentinel/issues/2179<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></p></div> <p>值得一提的是,阿里云的商业版 sentinel-dashboard 是有这个功能的。并且在 test 代码中可以看到有对应持久化实现的。所以这很明显官方并不想在开源ç‰
22ˆå®žçŽ°è¿™ä¸ªåŠŸèƒ½ï¼Œéœ€è¦æˆ‘ä»¬è‡ªå·±åŽ»å®žçŽ°ã€‚è¿™å…¶ä¸­çš„åŽŸç”±å·²ç»éžå¸¸æ˜Žæ˜¾äº†ã€‚</p> <img width="50%" src="/assets/img/01.sentinel-dashboard-test.df10197e.png"> <p><img src="/assets/img/01.sentinel-dashboard-aliyun.9ec6549f.jpg" alt=""></p> <h2 id="方案选型"><a href="#方案选型" class="header-anchor">#</a> 方案选型</h2> <p>目前已经实现的组件中,sentinel 客户端已经支持:</p> <ul><li>apollo</li> <li>consul</li> <li>etcd</li> <li>eureka</li> <li>nacos</li> <li>redis</li> <li>spring-cloud-config</li> <li>zookeeper</li></ul> <img width="50%" src="/assets/img/01.sentinel-datasource.7a9d76aa.png"> <p>以最小化改动原则,我们可以从上面其中一个作为持久化存储方案,否则就需要自己再开发一套客户端同步数据组件。</p> <p>这里我选择 apollo,理由是:apollo 作为配置中心,有丰富的配置功能,与其他方案如 nacos 都要完善和稳定许多。而其他如 redis、zookeeper 在数据排查方面都不是太方便。</p> <h2 id="源码分析"><a href="#源码分析" class="header-anchor">#</a> 源码分析</h2> <p>sentinel-dashboard 的源码结构非常简单。后端使用 spring-boot,前端使用 angular1。</p> <p>我们打开浏览器抓包工具,在界面上操作增删改查对应配置,就可以知道对应的接口是多少,然后通过接口路径找到对应的 Controller,继续往下跟踪就可以知道完整的处理流程了。</p> <p><img src="/assets/img/01.sentinel-dashboard-api.3919f314.png" alt=""></p> <p>例如:新增网关流控规则的接口是 <code>/gateway/flow/new.json</code></p> <p>通过分析不难发现,不管是什么配置,对应增删改查的接口路径都是类似的。</p> <img width="50%" src="/assets/img/01.sentinel-dashbaord-controller.75674b1e.png"> <p>sentinel 规则总共有 7 中类型,都实现了 <code>RuleEntity</code> 接口</p> <img width="50%" src="/assets/img/01.sentinel-dashboard-rule.f321ee60.png"> <p>我们需要实现的也是将这7种数据类型持久化到 apollo。</p> <p>从 sentinel 的架构设计上可以知道分为 sentinel 客户端(也就是我们的应用)和 sentinel-dashboard(管理后台)。</p> <p>通过分析 <code>FlowControllerV1</code> 源码,可以知道配置读写都是通过 <code>SentinelApiClient</code> 来完成的。</p> <ul><li><p>读数据:通过 <code>SentinelApiClient</code> 请求客户端,拉取配置,然后更新到内存</p> <p><img src="/assets/img/01.sentinel-dashboard-rule-fetch.22f18a09.png" alt=""></p></li> <li><p>写数据:先保存到内存,然后调用 <code>SentinelApiClient</code> 将请求同步到客户端</p> <p><img src="/assets/img/01.sentinel-dashboard-rule-save.d5c9d705.png" alt=""></p></li></ul> <h2 id="改造实现"><a href="#改造实现" class="header-anchor">#</a> 改造实现</h2> <p>对于在生产环境中使用 Sentinel,<a href="https://github.com/alibaba/Sentinel/wiki/%E5%9C%A8%E7%94%9F%E4%BA%A7%E7%8E%AF%E5%A2%83%E4%B8%AD%E4%BD%BF%E7%94%A8-Sentinel" target="_blank" rel="noopener noreferrer">官网文档<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>中给我们介绍了几种模式。通过上面源码分析的流程实现的就是原始模式,我们的改造方案是要实现推模式。</p> <p>对于改造方案,如果做过这方面调研的同学,找到的资料基本上都是只实现了流量控制规则持久化,而剩下其他 6 中规则并没有实现持久化,包括姚秋辰(姚半仙)老师在极客时间上的专栏《Spring Cloud 微服务项目实战》第 20 章节<a href="https://time.geekbang.org/column/article/482647" target="_blank" rel="noopener noreferrer">Sentinel 实战:如何接入 Nacos 实现规则持久化?<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound">
22<path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a> 中的方案也只是把<code>流控规则</code>配置做了持久化。大家可以自己搜索一下,这里不再赘述。</p> <p>以上方案都存在几个不足。</p> <ol><li>只实现了流控规则持久化</li> <li>需要修改源码(包括前端代码),不放面后续滚动升级</li> <li>如果 7 中类型数据都做持久化的,那需要修改的地方会比较多</li></ol> <p>通过上面源码分析可以知道,其实数据拉取和推送都是通过<code>SentinelApiClient</code> 的 fetchXXX(拉取数据)和 setXXX, modifyXXX(推送数据)方法来实现的,所以我们只要把对应的方法改成从 apollo 拉取数据和将数据推送到 apollo 上就可以了,</p> <p>因为 <code>SentinelApiClient</code> 没有定义接口,所以要在不改变源码的情况下改变它的默认行为,就要通过aop来实现了。</p> <p>下面是实现网关流控规则读写 apollo 的示例代码。</p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token annotation punctuation">@Aspect</span>
23<span class="token annotation punctuation">@Component</span>
24<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">SentinelApiClientAspect</span> <span class="token punctuation">{</span>
25
26    <span class="token keyword">private</span> <span class="token keyword">static</span> <span class="token keyword">final</span> <span class="token class-name">Logger</span> <span class="token constant">LOG</span> <span class="token operator">=</span> <span class="token class-name">LoggerFactory</span><span class="token punctuation">.</span><span class="token function">getLogger</span><span class="token punctuation">(</span><span class="token class-name">SentinelApiClientAspect</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
27
28    <span class="token annotation punctuation">@SuppressWarnings</span><span class="token punctuation">(</span><span class="token string">&quot;PMD.ThreadPoolCreationRule&quot;</span><span class="token punctuation">)</span>
29    <span class="token keyword">private</span> <span class="token keyword">static</span> <span class="token keyword">final</span> <span class="token class-name">ExecutorService</span> <span class="token constant">EXECUTOR</span> <span class="token operator">=</span> <span class="token class-name">Executors</span><span class="token punctuation">.</span><span class="token function">newSingleThreadExecutor</span><span class="token punctuation">(</span>
30            <span class="token keyword">new</span> <span class="token class-name">NamedThreadFactory</span><span class="token punctuation">(</span><span class="token string">&quot;sentinel-dashboard-api-aspect&quot;</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
31
32    <span class="token annotation punctuation">@Resource</span>
33    <span class="token keyword">private</span> <span class="token class-name">DynamicRuleStoreFactory</span> factory<span class="token punctuation">;</span>
34
35
36    <span class="token annotation punctuation">@Pointcut</span><span class="token punctuation">(</span><span class="token string">&quot;execution(public * com.alibaba.csp.sentinel.dashboard.client.SentinelApiClient.fetchGatewayFlowRules(..))&quot;</span><span class="token punctuation">)</span>
37    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">fetchGatewayFlowRulesPointcut</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
38    <span class="token punctuation">}</span>
39
40    <span class="token annotation punctuation">@Pointcut</span><span class="token punctuation">(</span><span class="token string">&quot;execution(public * com.alibaba.csp.sentinel.dashboard.client.SentinelApiClient.modifyGatewayFlowRules(..))&quot;</span><span class="token punctuation">)</span>
41    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">modifyGatewayFlowRulesPointcut</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
42    <span class="token punctuation">}</span>
43
44    <span class="token comment">/**
45     * 拉取网关流控规则配置
46     */</span>
47    <span class="token annotation punctuation">
47@Around</span><span class="token punctuation">(</span><span class="token string">&quot;fetchGatewayFlowRulesPointcut()&quot;</span><span class="token punctuation">)</span>
48    <span class="token keyword">public</span> <span class="token class-name">Object</span> <span class="token function">fetchGatewayFlowRules</span><span class="token punctuation">(</span><span class="token keyword">final</span> <span class="token class-name">ProceedingJoinPoint</span> pjp<span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">Throwable</span> <span class="token punctuation">{</span>
49        <span class="token keyword">return</span> <span class="token function">fetchRulesWithCompletableFuture</span><span class="token punctuation">(</span>pjp<span class="token punctuation">,</span> <span class="token class-name">RuleType</span><span class="token punctuation">.</span><span class="token constant">GW_FLOW</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
50    <span class="token punctuation">}</span>
51
52    <span class="token comment">/**
53     * 推送网关流控规则配置
54     */</span>
55    <span class="token annotation punctuation">@Around</span><span class="token punctuation">(</span><span class="token string">&quot;modifyGatewayFlowRulesPointcut()&quot;</span><span class="token punctuation">)</span>
56    <span class="token keyword">public</span> <span class="token class-name">Object</span> <span class="token function">modifyGatewayFlowRules</span><span class="token punctuation">(</span><span class="token keyword">final</span> <span class="token class-name">ProceedingJoinPoint</span> pjp<span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">Throwable</span> <span class="token punctuation">{</span>
57        <span class="token keyword">return</span> <span class="token function">publishRules</span><span class="token punctuation">(</span>pjp<span class="token punctuation">,</span> <span class="token class-name">RuleType</span><span class="token punctuation">.</span><span class="token constant">GW_FLOW</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
58    <span class="token punctuation">}</span>
59
60    <span class="token comment">// 中间省略了部分代码,完整代码可以从 github 查看</span>
61
62    <span class="token keyword">private</span> <span class="token class-name">Object</span> <span class="token function">fetchRules</span><span class="token punctuation">(</span><span class="token class-name">ProceedingJoinPoint</span> pjp<span class="token punctuation">,</span> <span class="token class-name">RuleType</span> ruleType<span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">Throwable</span> <span class="token punctuation">{</span>
63        <span class="token class-name">DynamicRuleStore</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token operator">?</span><span class="token punctuation">&gt;</span></span> dynamicRuleStore <span class="token operator">=</span> factory<span class="token punctuation">.</span><span class="token function">getDynamicRuleStoreByType</span><span class="token punctuation">(</span>ruleType<span class="token punctuation">)</span><span class="token punctuation">;</span>
64        <span class="token keyword">if</span> <span class="token punctuation">(</span>dynamicRuleStore <span class="token operator">==</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
65            <span class="token keyword">return</span> pjp<span class="token punctuation">.</span><span class="token function">proceed</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
66        <span class="token punctuation">}</span>
67        <span class="token class-name">Object</span><span class="token punctuation">[</span><span class="token punctuation">]</span> args <span class="token operator">=</span> pjp<span class="token punctuation">.</span><span class="token function">getArgs</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
68        <span class="token class-name">String</span> app <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token class-name">String</span><span class="token punctuation">)</span> args<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
69        <span class="token keyword">return</span> dynamicRuleStore<span class="token punctuation">.</span><span class="token function">getRules</span><span class="token punctuation">(</span>app<span class="token punctuation">)</span><span class="token punctuation">;</span>
70    <span class="token punctuation">}</span>
71
72    <span class="token keyword">private</span> <span class="token class-name">CompletableFuture</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">Object</span><span class="token punctuation">&gt;</span></span> <span class="token function">fetchRulesWithCompletableFuture</span><span class="token punctuation">(</span><span class="token class-name">ProceedingJoinPoint</span> pjp<span class="token punctuation">,</span> <span class="token class-name">RuleType</span> ruleType<span class="token punctuation">)</span> <span class="token punctuation">{</span>
73        <span class="token keyword">return</span> <span class="token class-name">CompletableFuture</span><span class="token punctuation">.</span><span class="token function">supplyAsync</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-&gt;</span> <span class="token punctuation">{</span>
74            <span class="token keyword">try</span> <span class="token punctuation">{</span>
75                <span class="token keyword">return</span> <span class="token function">fetchRules</span><span class="token punctuation">(</span>pjp<span class="token punctuation">,</span> ruleType<span class="token punctuation">)</span><span class="token punctuation">;</span>
76            <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token class-name">Throwable</span> e<span class="token punctuation">)</span> <span class="token punctuation">{</span>
77                <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">RuntimeException</span><span class="token punctuation">(</span><span class="token string">&quot;fetch rules error: &quot;</span> <span class="token operator">+</span> ruleType<span class="token punctuation">.</span><span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> e<span class="token punctuation">)</span><span class="token punctuation">;</span>
78            <span class="token punctuation">}</span>
79        <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token constant">EXECUTOR</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
80    <span class="token punctuation">}</span>
81
82
83    <span class="token annotation punctuation">@SuppressWarnings</span><span class="token punctuation">(</span><span class="token string">&quot;unchecked&quot;</span><span class="token punctuation">)</span>
84    <span class="token keyword">private</span> <span class="token keyword">boolean</span> <span class="token function">publishRules</span><span class="token punctuation">(</span><span class="token class-name">ProceedingJoinPoint</span> pjp<span class="token punctuation">,</span> <span class="token class-name">RuleType</span> ruleType<span class="token punctuation">)</span> <span class="token punctuation">{</span>
85        <span class="token class-name">DynamicRuleStore</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">RuleEntity</span><span class="token punctuation">&gt;</span></span> dynamicRuleStore <span class="token operator">=</span> factory<span class="token punctuation">.</span><span class="token function">getDynamicRuleStoreByType</span><span class="token punctuation">(</span>ruleType<span class="token punctuation">)</span><span class="token punctuation">;</span>
86        <span class="token class-name">Object</span><span class="token punctuation">[</span><span class="token punctuation">]</span> args <span class="token operator">=</span> pjp<span class="token punctuation">.</span><span class="token function">getArgs</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
87        <span class="token class-name">String</span> app <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token class-name">String</span><span class="token punctuation">)</span> args<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
88        <span class="token class-name">List</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">RuleEntity</span><span class="token punctuation">&gt;</span></span> rules <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token class-name">List</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">RuleEntity</span><span class="token punctuation">&gt;</span></span><span class="token punctuation">)</span> args<span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
89        <span class="token keyword">try</span> <span class="token punctuation">{</span>
90            dynamicRuleStore<span class="token punctuation">.</span><span class="token function">publish</span><span class="token punctuation">(</span>app<span class="token punctuation">,</span> rules<span class="token punctuation">)</span><span class="token punctuation">;</span>
91            <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
92        <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token class-name">Exception</span> e<span class="token punctuation">)</span> <span class="token punctuation">{</span>
93            <span class="token constant">LOG</span><span class="token punctuation">.</span><span class="token function">error</span><span class="token punctuation">(</span><span class="token string">&quot;publish rules error&quot;</span><span class="token punctuation">,</span> e<span class="token punctuation">)</span><span class="token punctuation">;</span>
94            <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
95        <span class="token punctuation">}</span>
96    <span class="token punctuation">}</span>
97
98    <span class="token keyword">private</span> <span class="token class-name">CompletableFuture</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">Void</span><span class="token punctuation">&gt;</span></span> <span class="token function">publishRulesWithCompletableFuture</span><span class="token punctuation">(</span><span class="token class-name">ProceedingJoinPoint</span> pjp<span class="token punctuation">,</span> <span class="token class-name">RuleType</span> ruleType<span class="token punctuation">)</span> <span class="token punctuation">{</span>
99        <span class="token keyword">return</span> <span class="token class-name">CompletableFuture</span><span class="token punctuation">.</span><span class="token function">runAsync</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-&gt;</span> <span class="token function">publishRules</span><span class="token punctuation">(</span>pjp<span class="token punctuation">,</span> ruleType<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token constant">EXECUTOR</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
100    <span class="token punctuation">}</span>
101<span class="token punctuation">}</span>
102</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br><span class="line-number">35</span><br><span class="line-number">36</span><br><span class="line-number">37</span><br><span class="line-number">38</span><br><span class="line-number">39</span><br><span class="line-number">40</span><br><span class="line-number">41</span><br><span class="line-number">42</span><br><span class="line-number">43</span><br><span class="line-number">44</span><br><span class="line-number">45</span><br><span class="line-number">46</span><br><span class="line-number">47</span><br><span class="line-number">48</span><br><span class="line-number">49</span><br><span class="line-number">50</span><br><span class="line-number">51</span><br><span class="line-number">52</span><br><span class="line-number">
10253</span><br><span class="line-number">54</span><br><span class="line-number">55</span><br><span class="line-number">56</span><br><span class="line-number">57</span><br><span class="line-number">58</span><br><span class="line-number">59</span><br><span class="line-number">60</span><br><span class="line-number">61</span><br><span class="line-number">62</span><br><span class="line-number">63</span><br><span class="line-number">64</span><br><span class="line-number">65</span><br><span class="line-number">66</span><br><span class="line-number">67</span><br><span class="line-number">68</span><br><span class="line-number">69</span><br><span class="line-number">70</span><br><span class="line-number">71</span><br><span class="line-number">72</span><br><span class="line-number">73</span><br><span class="line-number">74</span><br><span class="line-number">75</span><br><span class="line-number">76</span><br><span class="line-number">77</span><br><span class="line-number">78</span><br><span class="line-number">79</span><br><span class="line-number">80</span><br></div></div><p>对应 apollo 读写数据的代码在 test 包下已经有了,拿过来稍加改动就可以了</p> <img width="50%" src="/assets/img/01.sentinel-dashboard-test-apollo.0b8d9de3.png"> <p>完整的代码实现可以在 github 上查看:<a href="https://github.com/fengjx/Sentinel" target="_blank" rel="noopener noreferrer">https://github.com/fengjx/Sentinel<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>,整个改动没有修改一行源码,只是新增了一些类,方便后续升级不会引起代码冲突。</p> <h2 id="改造后的效果"><a href="#改造后的效果" class="header-anchor">#</a> 改造后的效果</h2> <p>dashboard 配置</p> <p><img src="/assets/img/01.sentinel-dashboard-demo.ad2abd62.png" alt=""></p> <p>apollo 配置</p> <p><img src="/assets/img/01.sentinel-dashboard-apollo-settings.f04f4413.png" alt=""></p> <h2 id="升级-版本维护"><a href="#升级-版本维护" class="header-anchor">#</a> 升级&amp;版本维护</h2> <p>本项目从 sentinel 官方 github 仓库 fork,只针对 dashboard 模块进行修改,保持与官方发布版本同步修改,版本对应关系</p> <table><thead><tr><th style="text-align:left;">Sentinel</th> <th style="text-align:left;">sentinel-dashboard-apollo</th> <th style="text-align:left;">说明</th></tr></thead> <tbody><tr><td style="text-align:left;">branch - master</td> <td style="text-align:left;">branch: dashboard/apollo/master</td> <td style="text-align:left;">保持最新版本与官方 master 同步</td></tr> <tr><td style="text-align:left;">tag - 1.8.4</td> <td style="text-align:left;">branch: dashboard/apollo/1.8.4</td> <td style="text-align:left;">从官方发布的 tag checkout 出来进行修改</td></tr> <tr><td style="text-align:left;">tag - 1.8.4</td> <td style="text-align:left;">tag: dashboard/apollo/v1.8.4</td> <td style="text-align:left;">修改完成后发布tag</td></tr></tbody></table> <h2 id="相关文档"><a href="#相关文档" class="header-anchor">#</a> 相关文档</h2> <ul><li><a href="https://github.com/alibaba/Sentinel/wiki/%E6%8E%A7%E5%88%B6%E5%8F%B0" target="_blank" rel="noopener noreferrer">Sentinel 控制台<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li> <li><a href="https://github.com/alibaba/Sentinel/wiki/%E5%9C%A8%E7%94%9F%E4%BA%A7%E7%8E%AF%E5%A2%83%E4%B8%AD%E4%BD%BF%E7%94%A8-Sentinel" target="_blank" rel="noopener noreferrer">在生产环境中使用 Sentinel<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound">
102<path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul></div></div>  <div class="page-edit"><!----> <div class="tags"><a href="/tags/?tag=sentinel" title="标签">#sentinel</a><a href="/tags/?tag=%E6%B5%81%E9%87%8F%E6%B2%BB%E7%90%86" title="标签">#流量治理</a></div> <div class="last-updated"><span class="prefix">Last Updated:</span> <span class="time">2024/04/23, 01:30:37</span></div></div> <div class="page-nav-wapper"><div class="page-nav-centre-wrap"><a href="/pages/5bffac/" class="page-nav-centre page-nav-centre-prev"><div class="tooltip">openresty 测试框架 test::nginx 安装</div></a> <a href="/sentinel-dashboard-apollo-wiki/" class="page-nav-centre page-nav-centre-next"><div class="tooltip">sentinel-dashboard-apollo 使用</div></a></div> <div class="page-nav"><p class="inner"><span class="prev">
103        ←
104        <a href="/pages/5bffac/" class="prev">openresty 测试框架 test::nginx 安装</a></span> <span class="next"><a href="/sentinel-dashboard-apollo-wiki/">sentinel-dashboard-apollo 使用</a>→
105      </span></p></div></div></div> <div class="article-list"><div class="article-title"><a href="/archives/" class="iconfont icon-bi">最近更新</a></div> <div class="article-wrapper"><dl><dd>01</dd> <dt><a href="/pages/efb886/"><div>
106            go-kit学习指南 - 多协议支持
107            <!----></div></a> <span class="date">04-19</span></dt></dl><dl><dd>02</dd> <dt><a href="/pages/d6f092/"><div>
108            go-kit学习指南 - 中间件
109            <!----></div></a> <span class="date">04-19</span></dt></dl><dl><dd>03</dd> <dt><a href="/pages/a15528/"><div>
110            go-kit开发微服务 - 服务注册与发现
111            <!----></div></a> <span class="date">04-19</span></dt></dl> <dl><dd></dd> <dt><a href="/archives/" class="more">更多文章&gt;</a></dt></dl></div></div></main></div> <div class="footer"><div class="icons"><a href="/cdn-cgi/l/email-protection#1a7c7f747d70737b74627374282a2b285a7d777b737634797577" title="发邮件" target="_blank" class="iconfont icon-youjian"></a><a href="https://github.com/fengjx" title="GitHub" target="_blank" class="iconfont icon-github"></a><a href="https://music.163.com/#/playlist?id=40434004" title="听音乐" target="_blank" class="iconfont icon-erji"></a></div> 
112  Theme by
113  <a href="https://github.com/xugaoyi/vuepress-theme-vdoing" target="_blank" title="本站主题">Vdoing</a> 
114    | Copyright © 2016-2026
115    <span>铁匠 | <a href="http://beian.miit.gov.cn/" target="_blank">粤ICP备15021633号</a></span></div> <div class="buttons"><div title="返回顶部" class="button blur go-to-top iconfont icon-fanhuidingbu" style="display:none;"></div> <div title="去评论" class="button blur go-to-comment iconfont icon-pinglun" style="display:none;"></div> <div title="主题模式" class="button blur theme-mode-but iconfont icon-zhuti"><ul class="select-box" style="display:none;"><li class="iconfont icon-zidong">
116          跟随系统
117        </li><li class="iconfont icon-rijianmoshi">
118          浅色模式
119        </li><li class="iconfont icon-yejianmoshi">
120          深色模式
121        </li><li class="iconfont icon-yuedu">
122          阅读模式
123        </li></ul></div></div> <!----> <!----> <!----></div><div class="global-ui"><div></div></div></div>
vendor: 113 bytes, lines 123-124
123
124    <script data-cfasync="false" src="/cdn-cgi/scripts/5c5dd728/cloudflare-static/email-decode.min.js"></script>
124<script src="/assets/js/app.4aaf6adf.js" defer></script>
124<script src="/assets/js/2.1cbe77ec.js" defer></script>
124<script src="/assets/js/4.f35e593d.js" defer></script>
124
125  
125<script type="module" src="https://static.cloudflareinsights.com/beacon.min.js/v31edd6df95cf4e85bb4c19e7a9bdbcba1788362987495" integrity="sha512-iIg7k2xntmwu6/uSb5tpc/hySgZc4eoL31yB29W6tJFo2akwjPWcEqnCEdJvGexCL0KEQwVYv5BlowfhVz26hg==" data-cf-beacon='{"version":"2024.11.0","token":"3ec8d64138d2471e8f8c2e453ba7e3c5","r":1,"spa":2}' crossorigin="anonymous"></script>
125
126</body>
127</html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.