Sentinel-Dashboard 与 apollo 规则的相互同步
一、為什么需要改造 Sentinel:
????????Sentinel-Dashboard 控制臺是流量控制、熔斷降級規(guī)則統(tǒng)一配置和管理的入口,它為用戶提供了機(jī)器自發(fā)現(xiàn)、簇點鏈路自發(fā)現(xiàn)、監(jiān)控、規(guī)則配置等功能。在 Sentinel 控制臺上,我們可以配置規(guī)則并實時查看流量控制效果。在前面我們也介紹了 sentinel-dashboard 的搭建部署、springcloud 集成 sentinel 進(jìn)行流控熔斷以及 將?Sentinel 規(guī)則持久化到 apollo 配置中心 等一系列操作,這一篇文章我們就介紹下如何對 Sentinel 進(jìn)行改造,使其更加符合生產(chǎn)環(huán)境的要求。
??? ??? ?那為什么需要對 Sentinel 進(jìn)行改造呢?主要是因為所有規(guī)則都只能通過 Nacos 界面或 Apollo 界面來完成修改才能得到持久化存儲,而在 Sentinel Dashboard 中修改限流規(guī)則雖然可以生效,但是不會被持久化到配置中心。而在這兩個配置中心里存儲的數(shù)據(jù)是一個 Json 格式,當(dāng)存儲的規(guī)則越來越多,對該 Json 配置的可讀性與可維護(hù)性會變的越來越差。
?????????那么如何改造呢?要回答這個問題,我們需要先了解下 Sentinel 的規(guī)則管理方式。
1、Sentinel 的規(guī)則管理方式:
????????Sentinel 提供了兩種修改規(guī)則的方式,第一種是通過 API 編碼直接修改(loadRules),但編碼的方式一般用于測試和演示;第二種是通過 DataSource 適配不同數(shù)據(jù)源進(jìn)行修改,生產(chǎn)環(huán)境一般使用該方式來動態(tài)管理規(guī)則,Sentinel 中動態(tài)規(guī)則源的管理共有三種模式:
(1)原生模式:Sentinel Dashboard 通過 API 將規(guī)則推送至 Sentinel Client 并直接更新到 Sentinel Client 的內(nèi)存中,因為規(guī)則存儲在內(nèi)存中,只要項目重啟就丟失了,所以不建議用于生產(chǎn)環(huán)境
(2)pull 模式:即拉模式, Sentinel Client 主動向某個規(guī)則管理中心定期輪詢拉取規(guī)則,所以不能保證實時性,如果拉取過于頻繁可能會導(dǎo)致性能問題。下圖以本地文件數(shù)據(jù)源為例,推送過程如下圖所示:
(3)push 模式:即推模式,由規(guī)則中心統(tǒng)一推送, Sentinel Client 通過注冊監(jiān)聽器的方式時刻監(jiān)聽變化,比如使用 Nacos、Apollo、ZooKeeper 等配置中心,這種方式有更好的實時性和一致性保證。生產(chǎn)環(huán)境下推薦采用 push 模式的數(shù)據(jù)源,push 推送的操作應(yīng)該由 Sentinel dashboard 和 Config Center Dashboard 控制臺統(tǒng)一進(jìn)行管理和推送,不應(yīng)該經(jīng) Sentinel Client 推送至配置中心,Sentinel Client 僅負(fù)責(zé)獲取配置中心推送的配置并更新到本地,因此推送規(guī)則正確做法應(yīng)該是:配置中心控制臺/Sentinel 控制臺 → 配置中心 → Sentinel 客戶端。
2、Sentinel 的改造內(nèi)容:
2.1、改造前后的數(shù)據(jù)流程圖:
????????了解完 Sentinel 的規(guī)則管理方式后,我們肯定能明白在生產(chǎn)環(huán)境使用 Sentinel 時,需要將原生的規(guī)則管理模式改造 push 模式的原因了,Sentinel 改造前后的數(shù)據(jù)流向圖如下所示:
- 藍(lán)色箭頭 代表了限流規(guī)則由配置中心發(fā)起修改的更新路徑
- 橙色箭頭代表了限流規(guī)則由 Sentinel Dashboard 發(fā)起修改的更新路徑
- 綠色箭頭為公共公共部分,即:不論從配置中心修改,還是從 Sentinel Dashboard 修改都會觸發(fā)的操作。
????????從圖中可以很明顯的看到,在沒有整合配置中心來存儲規(guī)則前,Sentinel Dashboard 與業(yè)務(wù)服務(wù)之間是可以互通獲取最新限流規(guī)則的。在整合配置中心后但未對 Sentinel-dashboard 改造前,配置中心的修改都可以實時的刷新到業(yè)務(wù)服務(wù),再而被 Sentinel Dashboard 讀取到,但是 Sentinel dashboard 對于這些規(guī)則的更新到達(dá)各個業(yè)務(wù)服務(wù)之后,并沒有一個機(jī)制將規(guī)則同步到配置中心。但在改造后,從上圖的兩處修改起點看,所有涉及的部分都能獲取到一致的限流規(guī)則了。
2.2、核心改造點:
由上圖我們可知,我們需要改造的內(nèi)容如下:
(1)Sentinel dashboard 控制臺:
- ① Sentinel dashboard 控制臺將規(guī)則寫入到 apollo/nacos 配置中心進(jìn)行持久化
- ② Sentinel dashboard 能實時更新 apollo/nacos 控制臺所修改的規(guī)則
(2)Sentinel Client:
- ① Sentinel Client 實時更新 apollo/nacos 配置中心所修改的規(guī)則
二、Sentinel 的改造:
文章該部分以 apollo 作為配置中心介紹如何對 Sentinel 進(jìn)行改造,基于 Nacos 的改造方式推薦參考下面文章:
https://www.freesion.com/article/30571440125/
https://www.imooc.com/article/289464
https://github.com/tanjiancheng/alibaba-sentinel-dashboard-nacos
1、Sentinel dashboard 的改造:
????????本文是基于 sentinel-dashboard 1.7.2 版本進(jìn)行改造的,需要先下載官方源碼到本地進(jìn)行改造:https://github.com/alibaba/Sentinel/tree/release-1.7/sentinel-dashboard
1.1、添加 apollo 依賴與配置:
????????sentinel-dashboard 整合 apollo 進(jìn)行規(guī)則的持久化配置,主要方式是通過 apollo 開放平臺的授權(quán)方式進(jìn)行寫入與讀取,所以需要在 pom.xml 文件引入以下依賴:
<dependency><groupId>com.ctrip.framework.apollo</groupId><artifactId>apollo-openapi</artifactId><version>1.7.0</version><scope>compile</scope></dependency>????????引入之后,在 sentinel-dashboard 的配置文件添加 apollo 的配置,下列各配置參數(shù)的獲取方式文章第2部分會介紹:
# apollo的中配置的appId app.id=sentinel-rules # 如果apollo配置中心控制臺的訪問地址 apollo.meta=http://portal.xxx.net # token獲取方法下文會介紹 apollo.token=ccc082b44f06f2ae9552bf67a710f36c36e6b777 # apollo的登錄用戶 apollo.user=apollo # apollo的集群名稱 沒有的話請使用default apollo.clusterName=default # apollo的命名空間 默認(rèn)使用application,但考慮到該空間需要給所有項目共同使用,因此單獨創(chuàng)建了一個公共空間 apollo.namespaceName=EDU001.sentinel-rules????????接下來,我們按照下面兩步核心步驟進(jìn)行改造:
(1)第一步:添加與實現(xiàn)所有規(guī)則的 Provider 與 Publisher 的配置拉取與推送接口,改由從 apollo 中獲取規(guī)則信息,并將添加與修改的規(guī)則保存到 apollo
(2)第二步:在 Controller 層中引入改造過后的 Provider 與 Publisher 接口,由改造后的 Provider 與 Publisher 接口負(fù)責(zé)處理 sentinel-dashboard 看板發(fā)起的操作
1.2、規(guī)則在 Apollo 的編碼與存儲配置:
(1)sentinel 規(guī)則在 apollo 的編碼配置:
package com.alibaba.csp.sentinel.dashboard.rule.apollo;import com.alibaba.csp.sentinel.dashboard.datasource.entity.gateway.ApiDefinitionEntity; import com.alibaba.csp.sentinel.dashboard.datasource.entity.gateway.GatewayFlowRuleEntity; import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.AuthorityRuleEntity; import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.DegradeRuleEntity; import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.FlowRuleEntity; import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.ParamFlowRuleEntity; import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.SystemRuleEntity; import com.alibaba.csp.sentinel.dashboard.domain.cluster.request.ClusterAppAssignMap; import com.alibaba.csp.sentinel.datasource.Converter; import com.alibaba.fastjson.JSON; import com.ctrip.framework.apollo.openapi.client.ApolloOpenApiClient; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;import java.util.List;@Configuration public class ApolloConfig {@Value("${apollo.meta}")private String portalUrl;@Value("${apollo.token}")private String token;/*** 流控規(guī)則編碼*/@Beanpublic Converter<List<FlowRuleEntity>, String> flowRuleEntityEncoder() {return JSON::toJSONString;}/*** 流控規(guī)則解碼*/@Beanpublic Converter<String, List<FlowRuleEntity>> flowRuleEntityDecoder() {return s -> JSON.parseArray(s, FlowRuleEntity.class);}/*** 降級規(guī)則編碼*/@Beanpublic Converter<List<DegradeRuleEntity>, String> degradeRuleEntityEncoder() {return JSON::toJSONString;}/*** 降級規(guī)則解碼*/@Beanpublic Converter<String, List<DegradeRuleEntity>> degradeRuleEntityDecoder() {return s -> JSON.parseArray(s, DegradeRuleEntity.class);}/*** 授權(quán)規(guī)則編碼*/@Beanpublic Converter<List<AuthorityRuleEntity>, String> authorityRuleEntityEncoder() {return JSON::toJSONString;}/*** 授權(quán)規(guī)則解碼*/@Beanpublic Converter<String, List<AuthorityRuleEntity>> authorityRuleEntityDecoder() {return s -> JSON.parseArray(s, AuthorityRuleEntity.class);}/*** 系統(tǒng)規(guī)則編碼*/@Beanpublic Converter<List<SystemRuleEntity>, String> systemRuleEntityEncoder() {return JSON::toJSONString;}/*** 系統(tǒng)規(guī)則解碼*/@Beanpublic Converter<String, List<SystemRuleEntity>> systemRuleEntityDecoder() {return s -> JSON.parseArray(s, SystemRuleEntity.class);}/*** 熱點規(guī)則編碼*/@Beanpublic Converter<List<ParamFlowRuleEntity>, String> paramFlowRuleEntityEncoder() {return JSON::toJSONString;}/*** 熱點規(guī)則解碼*/@Beanpublic Converter<String, List<ParamFlowRuleEntity>> paramFlowRuleEntityDecoder() {return s -> JSON.parseArray(s, ParamFlowRuleEntity.class);}/*** 集群流控規(guī)則編碼*/@Beanpublic Converter<List<ClusterAppAssignMap>, String> clusterGroupEntityEncoder() {return JSON::toJSONString;}/*** 集群流控規(guī)則解碼*/@Beanpublic Converter<String, List<ClusterAppAssignMap>> clusterGroupEntityDecoder() {return s -> JSON.parseArray(s, ClusterAppAssignMap.class);}/*** API管理分組編碼*/@Beanpublic Converter<List<ApiDefinitionEntity>, String> apiDefinitionEntityEncoder() {return JSON::toJSONString;}/*** API管理分組解碼*/@Beanpublic Converter<String, List<ApiDefinitionEntity>> apiDefinitionEntityDecoder() {return s -> JSON.parseArray(s, ApiDefinitionEntity.class);}/*** 網(wǎng)關(guān)流控規(guī)則編碼*/@Beanpublic Converter<List<GatewayFlowRuleEntity>, String> gatewayFlowRuleEntityEncoder() {return JSON::toJSONString;}/*** 網(wǎng)關(guān)流控規(guī)則解碼*/@Beanpublic Converter<String, List<GatewayFlowRuleEntity>> gatewayFlowRuleEntityDecoder() {return s -> JSON.parseArray(s, GatewayFlowRuleEntity.class);}@Beanpublic ApolloOpenApiClient apolloOpenApiClient() {ApolloOpenApiClient client = ApolloOpenApiClient.newBuilder().withPortalUrl(portalUrl).withToken(token).build();return client;} }(2)sentinel 規(guī)則在 Apollo 中存儲的 key 值的前/后綴:
package com.alibaba.csp.sentinel.dashboard.rule.apollo;public final class ApolloConfigUtil {/*** 網(wǎng)關(guān)-api分組id*/public static final String GATEWAY_API_GROUP_DATA_ID_POSTFIX = "gw-api-group-rules";/*** 網(wǎng)關(guān)-流控規(guī)則id*/public static final String GATEWAY_FLOW_DATA_ID_POSTFIX = "gw-flow-rules";/*** 流控規(guī)則id*/public static final String FLOW_DATA_ID_POSTFIX = "flow-rules";/*** 降級規(guī)則id*/public static final String DEGRADE_DATA_ID_POSTFIX = "degrade-rules";/*** 熱點規(guī)則id*/public static final String PARAM_FLOW_DATA_ID_POSTFIX = "param-flow-rules";/*** 系統(tǒng)規(guī)則id*/public static final String SYSTEM_DATA_ID_POSTFIX = "system-rules";/*** 授權(quán)規(guī)則id*/public static final String AUTHORITY_DATA_ID_POSTFIX = "authority-rules";/*** 集群流控id*/public static final String CLUSTER_GROUP_DATA_ID_POSTFIX = "cluster-group-rules";private ApolloConfigUtil(){}public static String getGatewayFlowDataId(String appName){return String.format("%s-%s", appName, GATEWAY_FLOW_DATA_ID_POSTFIX);}public static String getGatewayApiGroupDataId(String appName){return String.format("%s-%s", appName, GATEWAY_API_GROUP_DATA_ID_POSTFIX);}public static String getClusterGroupDataId(String appName){return String.format("%s-%s", appName, CLUSTER_GROUP_DATA_ID_POSTFIX);}public static String getFlowDataId(String appName){return String.format("%s-%s", appName, FLOW_DATA_ID_POSTFIX);}public static String getDegradeDataId(String appName){return String.format("%s-%s", appName, DEGRADE_DATA_ID_POSTFIX);}public static String getParamFlowDataId(String appName){return String.format("%s-%s", appName, PARAM_FLOW_DATA_ID_POSTFIX);}public static String getSystemDataId(String appName){return String.format("%s-%s", appName, SYSTEM_DATA_ID_POSTFIX);}public static String getAuthorityDataId(String appName){return String.format("%s-%s", appName, AUTHORITY_DATA_ID_POSTFIX);} }1.3、新增 Provider 與 Publisher:
????????Sentinel Dashboard 從 1.4.0 版本開始就抽取出了接口用于向遠(yuǎn)程配置中心推送規(guī)則以及拉取規(guī)則:DynamicRuleProvider 拉取規(guī)則、DynamicRulePublisher 推送規(guī)則,所以,只需要通過這兩個接口,實現(xiàn)對配置中心中存儲規(guī)則的讀寫,就能實現(xiàn) Sentinel Dashboard 中修改規(guī)則與配置中心存儲同步的效果。
????????這里僅提供對流控規(guī)則的修改案例,其他規(guī)則類型(流控/降級/熱點/系統(tǒng)/授權(quán))的修改基本與流控相同,就不重復(fù)介紹:
(1)新增 Provider,從 Apollo 配置中心查詢持久化的規(guī)則:
@Component("flowRuleApolloProvider") public class FlowRuleApolloProvider implements DynamicRuleProvider<List<FlowRuleEntity>> {@Autowiredprivate ApolloOpenApiClient apolloOpenApiClient;@Autowiredprivate Converter<String, List<FlowRuleEntity>> converter;@Value("${app.id}")private String appId;@Value("${spring.profiles.active}")private String env;@Value("${apollo.clusterName}")private String clusterName;@Value("${apollo.namespaceName}")private String namespaceName;@Overridepublic List<FlowRuleEntity> getRules(String appName){String flowDataId = ApolloConfigUtil.getFlowDataId(appName);OpenNamespaceDTO openNamespaceDTO = apolloOpenApiClient.getNamespace(appId, env, clusterName, namespaceName);String rules = openNamespaceDTO.getItems().stream().filter(p -> p.getKey().equals(flowDataId)).map(OpenItemDTO::getValue).findFirst().orElse("");if (StringUtil.isEmpty(rules)) {return new ArrayList<>();}return converter.convert(rules);} }(2)新增 Publisher,將流控規(guī)則持久化到 Apollo 配置中心里面:
@Component("flowRuleApolloPublisher") public class FlowRuleApolloPublisher implements DynamicRulePublisher<List<FlowRuleEntity>> {@Autowiredprivate ApolloOpenApiClient apolloOpenApiClient;@Autowiredprivate Converter<List<FlowRuleEntity>, String> converter;@Value("${app.id}")private String appId;@Value("${spring.profiles.active}")private String env;@Value("${apollo.user}")private String user;@Value("${apollo.clusterName}")private String clusterName;@Value("${apollo.namespaceName}")private String namespaceName;@Overridepublic void publish(String app, List<FlowRuleEntity> rules){AssertUtil.notEmpty(app, "app name cannot be empty");if (rules == null) {return;}filterField(rules);// Increase the configurationString flowDataId = ApolloConfigUtil.getFlowDataId(app);OpenItemDTO openItemDTO = new OpenItemDTO();openItemDTO.setKey(flowDataId);openItemDTO.setValue(converter.convert(rules));openItemDTO.setComment("Program auto-join");openItemDTO.setDataChangeCreatedBy(user);apolloOpenApiClient.createOrUpdateItem(appId, env, clusterName, namespaceName, openItemDTO);// Release configurationNamespaceReleaseDTO namespaceReleaseDTO = new NamespaceReleaseDTO();namespaceReleaseDTO.setEmergencyPublish(true);namespaceReleaseDTO.setReleaseComment("Modify or add configurations");namespaceReleaseDTO.setReleasedBy(user);namespaceReleaseDTO.setReleaseTitle("Modify or add configurations");apolloOpenApiClient.publishNamespace(appId, env, clusterName, namespaceName, namespaceReleaseDTO);}/*** 過濾不必要的字段*/private void filterField(List<FlowRuleEntity> rules) {// 對不必要的信息進(jìn)行過濾for (FlowRuleEntity rule : rules) {rule.setGmtCreate(null);rule.setGmtModified(null);}} }(3)在 Controller 中引入 Provider 和 Publisher:
@Autowired@Qualifier("flowRuleApolloProvider")private DynamicRuleProvider<List<FlowRuleEntity>> ruleProvider;@Autowired@Qualifier("flowRuleApolloPublisher")private DynamicRulePublisher<List<FlowRuleEntity>> rulePublisher;(4)修改 controller 的查詢接口,改由從 apollo 中查詢 sentinel 的規(guī)則:
/*** 查詢流控配置,用于展示在sentinel-dashboard上 */ @GetMapping("/rules") @AuthAction(PrivilegeType.READ_RULE) public Result<List<FlowRuleEntity>> apiQueryMachineRules(@RequestParam String app, @RequestParam String ip, @RequestParam Integer port) {if (StringUtil.isEmpty(app)){return Result.ofFail(-1, "app can't be null or empty");}if (StringUtil.isEmpty(ip)){return Result.ofFail(-1, "ip can't be null or empty");}if (port == null){return Result.ofFail(-1, "port can't be null");}try {List<FlowRuleEntity> rules = ruleProvider.getRules(app);if (rules != null && !rules.isEmpty()){for (FlowRuleEntity entity : rules){entity.setApp(app);if (entity.getClusterConfig() != null && entity.getClusterConfig().getFlowId() != null){entity.setId(entity.getClusterConfig().getFlowId());}}}repository.saveAll(rules);return Result.ofSuccess(rules);}catch (Throwable throwable){logger.error("Error when querying flow rules", throwable);return Result.ofThrowable(-1, throwable);} }(5)修改 controller 的新增或修改接口,每次新增或修改都同步到 Apollo 中:
/*** 發(fā)布限流配置*/ private CompletableFuture<Void> publishRules(String app, String ip, Integer port) {List<FlowRuleEntity> rules = repository.findAllByMachine(MachineInfo.of(app, ip, port));try {rulePublisher.publish(app, rules);} catch (Exception e) {e.printStackTrace();}return sentinelApiClient.setFlowRuleOfMachineAsync(app, ip, port, rules); }2、配置 sentinel-dashboard 的 Apollo 空間:
2.1、創(chuàng)建 sentinel-dashboard 項目的 apollo 應(yīng)用:
?2.2、創(chuàng)建一個用于存放 sentinel-dashboard 規(guī)則的公共 namespace 空間:
????????進(jìn)入應(yīng)用后,點擊 "添加Namespace",創(chuàng)建一個具體存儲 Sentinel 各種限流、熔斷降級等規(guī)則的 Apollo 存儲空間,這里需要注意的是所創(chuàng)建的空間類型一定要是"public"公共空間,因為最終這些規(guī)則是需要具體的微服務(wù)應(yīng)用去獲取的,而在Apollo中應(yīng)用下只有公共Namecspace才能被其他應(yīng)用繼承。
2.3、創(chuàng)建基于該應(yīng)用的開放授權(quán)信息token:
(1)點擊控制臺右上角的管理員工具 -> 開放平臺授權(quán)管理
?(2)第三方應(yīng)用ID=AppId,第三方應(yīng)用名稱=請隨意填寫,項目負(fù)責(zé)人=配置文件中的apollo.user,第一次請點擊創(chuàng)建, 如果右上角提示已經(jīng)存在,則點擊查詢
?(3)授權(quán)類型請選擇app:
????????最終生成的Token信息將作為 sentinel-dashboard 與 Apollo 接口對接的重要憑證被配置。至此,通過上面幾個步驟,就完成了 sentinel-dashboard 項目的改造,接下來將介紹其他項目如何與改造后的 sentinel-dashboard 進(jìn)行集成并打通
3、spring boot 集成 sentinel 并持久化規(guī)則到 apollo 中:
此部分以 gateway-bbk 網(wǎng)關(guān)項目為例,如果非網(wǎng)關(guān)項目去掉網(wǎng)關(guān)相關(guān)配置
?3.1、引入依賴:
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId><version>2.2.6.RELEASE</version> </dependency> <!--apollo--> <dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-datasource-apollo</artifactId><version>1.5.2</version> </dependency>3.2、配置文件:
????????sentinel-dashboard 是將規(guī)則寫入它在 Apollo 所在應(yīng)用的公共空間下 sentinel-rules,因此其他微服務(wù)可以通過 Apollo 繼承并讀取到該公共空間的配置。只是我們在進(jìn)行 sentinel-dashboard的 改造將規(guī)則的寫入編成了一定的前/后綴標(biāo)識,所以 SpringCloud 微服務(wù)要想匹配到相應(yīng)的規(guī)則,也需要在自身服務(wù)的配置中約定讀取方式,具體以限流、熔斷這兩個規(guī)則為例進(jìn)行配置,如下的 flowRulesKey 所示:
# sentinel + apollo進(jìn)行規(guī)則持久化,RulesKey指定該規(guī)則在apollo中key的名稱,命名格式需與sentinel-dashboard配置的格式保持一致 sentinel.datasource.rules.apollo.namespace-name = EDU001.sentinel-rules # 從Apollo公共空間中EDU001.sentinel-rules讀取限流規(guī)則 spring.cloud.sentinel.datasource.flow.apollo.ruleType = flow spring.cloud.sentinel.datasource.flow.apollo.namespace-name = ${sentinel.datasource.rules.apollo.namespace-name} spring.cloud.sentinel.datasource.flow.apollo.flowRulesKey = ${spring.application.name}-${spring.cloud.sentinel.datasource.flow.apollo.ruleType}-rules # 從Apollo公共空間中EDU001.sentinel-rules讀取熔斷規(guī)則 spring.cloud.sentinel.datasource.degrade.apollo.ruleType = degrade spring.cloud.sentinel.datasource.degrade.apollo.namespace-name = ${sentinel.datasource.rules.apollo.namespace-name} spring.cloud.sentinel.datasource.degrade.apollo.flowRulesKey = ${spring.application.name}-${spring.cloud.sentinel.datasource.degrade.apollo.rule-ruleType}-rules # 從Apollo公共空間中EDU001.sentinel-rules讀取網(wǎng)關(guān)限流規(guī)則 spring.cloud.sentinel.datasource.gwFlow.apollo.ruleType = gw-flow spring.cloud.sentinel.datasource.gwFlow.apollo.namespace-name = ${sentinel.datasource.rules.apollo.namespace-name} spring.cloud.sentinel.datasource.gwFlow.apollo.flowRulesKey = ${spring.application.name}-${spring.cloud.sentinel.datasource.gwFlow.apollo.ruleType}-rules # 從Apollo公共空間中EDU001.sentinel-rules讀取網(wǎng)關(guān)API管理規(guī)則 spring.cloud.sentinel.datasource.gwApiGroup.apollo.ruleType = gw-api-group spring.cloud.sentinel.datasource.gwApiGroup.apollo.namespace-name = ${sentinel.datasource.rules.apollo.namespace-name} spring.cloud.sentinel.datasource.gwApiGroup.apollo.flowRulesKey = ${spring.application.name}-${spring.cloud.sentinel.datasource.gwApiGroup.apollo.ruleType}-rules# sentinel看板的地址 spring.cloud.sentinel.transport.dashboard = 112.74.98.151:80 # 開啟對sentinel看板的饑餓式加載 spring.cloud.sentinel.eager = true# 此項為該項目在配置中心的項目名 app.id=gateway-bbk # 加載的配置文件名,需引入 sentinel-dashboard 配置的公共空間 apollo.bootstrap.namespaces=application,EDU001.sentinel-rules apollo.bootstrap.enabled=true # 指定apollo的注冊地址: #本地開發(fā)環(huán)境 Local environment local.meta=http://47.112.238.105:8004 #開發(fā)聯(lián)調(diào)環(huán)境 Development environment dev.meta=http://172.18.227.113:8080 #功能驗收測試環(huán)境 Feature Acceptance Test environment fat.meta=http://172.18.227.115:8080 #生產(chǎn)環(huán)境 Production environment pro.meta=http://xxxx.xxx.net????????通過上述配置可以看出,我們是通過 Sentinel Client 依賴約定的配置方式,對各類規(guī)則通過命名規(guī)則進(jìn)行了匹配(這里Sentinel規(guī)則的命名規(guī)則可以結(jié)合實際的管理需求進(jìn)行約定,確保 sentinel-dashboard 寫入與微服務(wù)讀取匹配就行)!例如:如果從管理角度分類,可以加上{部門名稱}.sentinel-rules,這要求創(chuàng)建namespace公共空間時帶上部門名前綴。
4、集成測試:
4.1、新增規(guī)則:
????????在 sentinel-dashboard 控制臺中添加新的規(guī)則:
4.2、同步至Apollo中:
在 sentinel dashiboard 控制臺添加成功后,我們進(jìn)入 apollo 配置中心就可以看到新增的規(guī)則已經(jīng)持久化到配置中心了?
參考文章:https://zhuanlan.zhihu.com/p/64892865
總結(jié)
以上是生活随笔為你收集整理的Sentinel-Dashboard 与 apollo 规则的相互同步的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java IO篇:什么是 Reactor
- 下一篇: Sentinel 规则持久化到 apol