sentinel-dashboard支持mysql
sentinel-dashboard是ali开源限流降级项目,默认配置是保存再内存中,添加的现在设置在站点重新启动后会消失,因为我们可以将配置保存起来,可以使用配置中心,本文章中使用数据库保存sentinel配置的设置,在站点启动时,将配置主动下发到站点,并且根据appName来分组,同一个appName配置一次后,所有属于该appName的服务器站点都会及时生效
首先我们看这个接口:RuleRepository<T, ID> 这个接口是所有规则实现的基础接口,该接口中有常用的:save, delete,findById等等,我们需要在上层调用这些方法时,访问数据库,将保存的内容同步到数据库中,当sentinet-dashboard重新启动时再从数据库中读取出来即可
配置文件添加读写数据库
添加配置文件类
启动时读取数据库中的数据,初始化到内存中
发布规则基础类:
@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();
/**
* 存规则到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));
}
}
获取规则基础类
@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();
/**
* 获取流控规则对应clazz,JSON转换用
*
* @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;
}
}
然后将需要的规则继承基础类,实现获取枚举操作即可
机器注册的时候,下发配置到机器上即可
@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) {//首次注册,发送配置
appInfo = new AppInfo(machineInfo.getApp(), machineInfo.getAppType());
apps.put(machineInfo.getApp(), appInfo);
//回调推送配置
isFirst = true;
}
MachineInfo machine = appInfo.getMachine(machineInfo.getIp(), machineInfo.getPort()).orElse(null);
if (machine == null || !machine.isHealthy())//如果是从来没有注册过,或者是重连
isFirst = true;
//添加新的机器信息
appInfo.addMachine(machineInfo);
if (isFirst)
sendRuleToMachine(machineInfo);
return 1;
}
//向机器发送配置
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