sentinel-dashboard支持mysql
sentinel-dashboard是ali開(kāi)源限流降級(jí)項(xiàng)目,默認(rèn)配置是保存再內(nèi)存中,添加的現(xiàn)在設(shè)置在站點(diǎn)重新啟動(dòng)后會(huì)消失,因?yàn)槲覀兛梢詫⑴渲帽4嫫饋?lái),可以使用配置中心,本文章中使用數(shù)據(jù)庫(kù)保存sentinel配置的設(shè)置,在站點(diǎn)啟動(dòng)時(shí),將配置主動(dòng)下發(fā)到站點(diǎn),并且根據(jù)appName來(lái)分組,同一個(gè)appName配置一次后,所有屬于該appName的服務(wù)器站點(diǎn)都會(huì)及時(shí)生效
首先我們看這個(gè)接口:RuleRepository<T, ID> 這個(gè)接口是所有規(guī)則實(shí)現(xiàn)的基礎(chǔ)接口,該接口中有常用的:save, delete,findById等等,我們需要在上層調(diào)用這些方法時(shí),訪問(wèn)數(shù)據(jù)庫(kù),將保存的內(nèi)容同步到數(shù)據(jù)庫(kù)中,當(dāng)sentinet-dashboard重新啟動(dòng)時(shí)再?gòu)臄?shù)據(jù)庫(kù)中讀取出來(lái)即可
配置文件添加讀寫(xiě)數(shù)據(jù)庫(kù)

添加配置文件類(lèi)

啟動(dòng)時(shí)讀取數(shù)據(jù)庫(kù)中的數(shù)據(jù),初始化到內(nèi)存中


發(fā)布規(guī)則基礎(chǔ)類(lèi):
@Component
public abstract class BaseDatabaseRulePublisher implements DynamicRulePublisher {
@Override
public void publish(String app, Object rules) throws Exception {
AssertUtil.notEmpty(app, "app name cannot be empty");
if (rules == null) {
return;
}
DatabaseRuleEnums dataId = getDataId();
saveRulesToDatabase(app, dataId, rules);
}
protected abstract DatabaseRuleEnums getDataId();
/**
* 存規(guī)則到db
*
* @param appName
* @param dataId
* @return
*/
protected void saveRulesToDatabase(String appName, DatabaseRuleEnums dataId, Object rules) {
SqlHelper.ExecSql("REPLACE INTO `cc_sentinel_rule`\n" +
"(`rule_id`,\n" +
"`rule_name`,\n" +
"`rule_type`,\n" +
"`app_name`,\n" +
"`content`)\n" +
"VALUES\n(" +
"\n?," +
"\n?," +
"\n?," +
"\n?," +
"\n?" +
");", null, dataId.getName(), dataId.getCode(), appName, JSON.toJSONString(rules));
}
}
獲取規(guī)則基礎(chǔ)類(lèi)
@Component
public abstract class BaseDatabaseRuleProvider implements DynamicRuleProvider {
@Override
public List getRules(String appName) throws Exception {
DatabaseRuleEnums flowDataId = getDataId();
String rules = getRulesFromDB(appName, flowDataId);
if (StringUtil.isEmpty(rules)) {
return new ArrayList<>();
}
return JSON.parseArray(rules, getRuleClazz());
}
/**
*
* @return
*/
protected abstract DatabaseRuleEnums getDataId();
/**
* 獲取流控規(guī)則對(duì)應(yīng)clazz,JSON轉(zhuǎn)換用
*
* @return
*/
protected abstract Class getRuleClazz();
/**
*
* @param appName
* @param dataId
* @return
*/
protected String getRulesFromDB(String appName, DatabaseRuleEnums dataId) {
DefaultTableModel resultSet = SqlHelper.getResultSet("SELECT `content` FROM `cc_sentinel_rule`\n" +
"WHERE `app_name`='" + appName + "' AND `rule_type`=" + dataId.getCode());
String content = null;
try {
content = resultSet.getValueAt(0, 0).toString();
} catch (Exception e) {
e.printStackTrace();
}
return content;
}
}
然后將需要的規(guī)則繼承基礎(chǔ)類(lèi),實(shí)現(xiàn)獲取枚舉操作即可
機(jī)器注冊(cè)的時(shí)候,下發(fā)配置到機(jī)器上即可
@Component
public class SimpleMachineDiscovery implements MachineDiscovery {
private final ConcurrentMap<String, AppInfo> apps = new ConcurrentHashMap<>();
@Autowired
private InMemoryRuleRepositoryAdapter<FlowRuleEntity> repository;
@Autowired
private ApplicationContext context;
@Autowired
private SentinelApiClient sentinelApiClient;
@Override
public long addMachine(MachineInfo machineInfo) {
AssertUtil.notNull(machineInfo, "machineInfo cannot be null");
AppInfo appInfo = apps.get(machineInfo.getApp());
boolean isFirst = false;
if (appInfo == null) {//首次注冊(cè),發(fā)送配置
appInfo = new AppInfo(machineInfo.getApp(), machineInfo.getAppType());
apps.put(machineInfo.getApp(), appInfo);
//回調(diào)推送配置
isFirst = true;
}
MachineInfo machine = appInfo.getMachine(machineInfo.getIp(), machineInfo.getPort()).orElse(null);
if (machine == null || !machine.isHealthy())//如果是從來(lái)沒(méi)有注冊(cè)過(guò),或者是重連
isFirst = true;
//添加新的機(jī)器信息
appInfo.addMachine(machineInfo);
if (isFirst)
sendRuleToMachine(machineInfo);
return 1;
}
//向機(jī)器發(fā)送配置
public void sendRuleToMachine(MachineInfo machineInfo) {
String[] beanNamesForType = context.getBeanNamesForType(InMemoryRuleRepositoryAdapter.class);
for (String beanName : beanNamesForType) {
((InMemoryRuleRepositoryAdapter) context.getBean(beanName)).publishMachineRules(machineInfo.getApp(), machineInfo.getIp(), machineInfo.getPort());
}
}
.......
}
gitee地址:https://gitee.com/lumiaomiao126/sentinel-dashboard-mysql.git