sentinel-dashboard配置持久化到mysql

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ù)


image.png

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


image.png

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


image.png
image.png

發(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

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容