java程序定時(shí)任務(wù)做數(shù)據(jù)報(bào)警

1衷模、啟動(dòng)類注入線程

@Bean(value = "taskExecutor")
    public Executor taskExecutor() {
        ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
        scheduler.setPoolSize(20);
        scheduler.setThreadNamePrefix("task-");
        //用來設(shè)置線程池關(guān)閉的時(shí)候等待所有任務(wù)都完成再繼續(xù)銷毀其他的Bean薪寓,
        scheduler.setWaitForTasksToCompleteOnShutdown(true);
        //線程池對(duì)拒絕任務(wù)的處理策略:這里采用了CallerRunsPolicy策略粤咪,當(dāng)線程池沒有處理能力的時(shí)候幽纷,該策略會(huì)直接在 execute 方法的調(diào)用線程中運(yùn)行被拒絕的任務(wù);如果執(zhí)行程序已關(guān)閉书在,則會(huì)丟棄該任務(wù)
        scheduler.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        return scheduler;
    }

2、定時(shí)任務(wù)

private Map<Long, ReporterCheck> lastMap = new HashMap<>();
    private Map<Long, ScheduledFuture> futureMap = new ConcurrentHashMap<>();

    @Scheduled(cron = "0 0/5 * * * ?")
    public void dynamic() {
            ThreadPoolTaskScheduler threadPoolTaskScheduler = (ThreadPoolTaskScheduler) taskScheduler;

            //切換數(shù)據(jù)源
            DataBaseTypeEnum.changeDataBaseTypeEnum(DataBaseTypeEnum.REPORTER.getDesc());

            List<ReporterCheck> reporterChecks = reportCheckMapper.selectAll();
            Map<Long, ReporterCheck> currReport = new HashMap<>();

            //循環(huán)當(dāng)前報(bào)表任務(wù)
            reporterChecks.forEach(reporterCheck -> {
                Long rid = reporterCheck.getId();
                currReport.put(rid, reporterCheck);
                if (!lastMap.containsKey(rid)) {
                    //新增拆又,任務(wù)
                    ScheduledFuture<?> scheduledFuture = threadPoolTaskScheduler.schedule(new Task(rid),
                            new CronTrigger(reporterCheck.getCorn()));
                    futureMap.put(rid, scheduledFuture);
                }
            });

            //循環(huán)上次的報(bào)表任務(wù)
            for (Long key : lastMap.keySet()) {
                if (currReport.containsKey(key)
                        && !currReport.get(key).getCorn().equals(lastMap.get(key).getCorn())) {
                    //cron表達(dá)式有變動(dòng)儒旬,則更新
                    futureMap.get(key).cancel(false);

                    ScheduledFuture<?> scheduledFuture = threadPoolTaskScheduler.schedule(new Task(key),
                            new CronTrigger(currReport.get(key).getCorn()));
                    futureMap.put(key, scheduledFuture);

                } else if (!currReport.containsKey(key)) {
                    //刪除任務(wù)
                    futureMap.get(key).cancel(true);
                    futureMap.remove(key);
                }
            }
            //重新賦值上次任務(wù)列表
            lastMap = currReport;
    }

class Task implements Runnable {
        private Long id;

        public Task(Long id) {
            this.id = id;
        }

        @Override
        public void run() {
            try {
                logger.info("執(zhí)行任務(wù){(diào)}開始", id);
                reportCheckService.handleReport(id);
                logger.info("執(zhí)行任務(wù){(diào)}結(jié)束", id);
            } catch (Exception e) {
                logger.error("執(zhí)行報(bào)表任務(wù)ID=" + id + "異常", e.getMessage());
            }
        }
    }

3、邏輯執(zhí)行

public void handleReport(Long id) {
        //切換數(shù)據(jù)源
        DataBaseTypeEnum.changeDataBaseTypeEnum(DataBaseTypeEnum.REPORTER.getDesc());
        ReporterCheck reporterCheck = reporterCheckMapper.selectByPrimaryKey(id);
        //組件:ModuleType=1 sql:ModuleType=2
        if (reporterCheck.getModuleType().equals(1)) {
            //API
            Map<String, Object> map = (Map<String, Object>) produceIndicatorData(reporterCheck);
            if (!map.isEmpty()) {
                //SendMail
                sendService.sendMail(reporterCheck.getTopic(), reporterCheck.getContent() + ":\r\n" + formatPut(map), null, reporterCheck.getToUcid());
            }
        } else {
            //SQL params
            List<Map<String, Object>> res = getResultFromSQL(reporterCheck);
            List<Map<String, Object>> contentList = new ArrayList<>();
            Map<String, String> expectedMap = new HashMap<>();
            String[] expectArray = reporterCheck.getExpectRes().split(";");
            for (String item : expectArray) {
                String[] keyValue = item.split(":");
                if (keyValue.length == 2) {
                    expectedMap.put(keyValue[0], keyValue[1]);
                }
            }

            //沒有指定期望
            if (expectedMap.isEmpty()) {
                contentList.addAll(res);
            } else {
                boolean flag = false;
                for (Map<String, Object> item : res) {
                    for (String key : expectedMap.keySet()) {
                        if (item.get(key) == null || !expectedMap.get(key).equals(item.get(key).toString())) {
                            flag = true;
                            break;
                        }
                    }
                    if (flag) {
                        contentList.add(item);
                    }
                    flag = false;
                }
            }

            //求優(yōu)雅輸出

            System.out.println();

            if (!contentList.isEmpty()) {
                //SendMail
                sendService.sendMail(reporterCheck.getTopic(), reporterCheck.getContent() + ":\r\n" + formatPut(contentList), null, reporterCheck.getToUcid());
            }
        }
    }

private List<Map<String, Object>> getResultFromSQL(ReporterCheck reporterCheck) {
        log.info("topic:{}", reporterCheck.getTopic());
        //切換數(shù)據(jù)源
        DataBaseTypeEnum.changeDataBaseTypeEnum(reporterCheck.getDataSource());
        List<Map<String, Object>> res = reporterCheckMapper.querySql(reporterCheck.getModule());
        return res;
    }

private String formatPut(Object contentList) {
        String content = JSONObject.toJSONString(contentList);
        ObjectMapper mapper = new ObjectMapper();
        Object obj = null;
        try {
            obj = mapper.readValue(content, Object.class);
            return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
        } catch (IOException e) {
            log.info("內(nèi)容輸出格式化失斕濉:{}", e.getMessage());
        }
        return "";
    }

public Object produceIndicatorData(ReporterCheck reporterCheck) {
        String[] api = reporterCheck.getModule().split("#");
        try {
            String className = SpringUtil.decapitalize(api[0].substring(api[0].lastIndexOf(".") + 1, api[0].length()));

            Object obj = SpringUtil.getBean(className);

            Class clazz = obj.getClass();

            Method method = clazz.getDeclaredMethod(api[1], ReporterCheck.class, Map.class);

            Map<String, Object> map = new HashMap<>();
            String[] params = reporterCheck.getParams().split(";");
            for (String item : params) {
                String[] keyValue = item.split(":");
                if (keyValue.length == 2) {
                    map.put(keyValue[0], keyValue[1]);
                }
            }

            return method.invoke(obj, reporterCheck, map);

        } catch (NoSuchMethodException e) {
            log.info("獲取指定方式失斦辉础:{}", e.getMessage());
        } catch (IllegalAccessException e) {
            log.info("反射調(diào)用方法參數(shù)錯(cuò)誤:{}", e.getMessage());
        } catch (InvocationTargetException e) {
            log.info("反射調(diào)用方法InvocationTargetException錯(cuò)誤:{}", e);
        }
        return null;
    }
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市竖般,隨后出現(xiàn)的幾起案子甚垦,更是在濱河造成了極大的恐慌,老刑警劉巖涣雕,帶你破解...
    沈念sama閱讀 218,525評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件艰亮,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡挣郭,警方通過查閱死者的電腦和手機(jī)迄埃,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,203評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來兑障,“玉大人侄非,你說我怎么就攤上這事钮糖≡梦觯” “怎么了?”我有些...
    開封第一講書人閱讀 164,862評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)烹骨。 經(jīng)常有香客問我,道長(zhǎng)所禀,這世上最難降的妖魔是什么界斜? 我笑而不...
    開封第一講書人閱讀 58,728評(píng)論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮眯搭,結(jié)果婚禮上窥翩,老公的妹妹穿的比我還像新娘。我一直安慰自己鳞仙,他們只是感情好寇蚊,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,743評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著棍好,像睡著了一般仗岸。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上借笙,一...
    開封第一講書人閱讀 51,590評(píng)論 1 305
  • 那天扒怖,我揣著相機(jī)與錄音,去河邊找鬼业稼。 笑死盗痒,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的低散。 我是一名探鬼主播俯邓,決...
    沈念sama閱讀 40,330評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼熔号!你這毒婦竟也來了稽鞭?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,244評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤引镊,失蹤者是張志新(化名)和其女友劉穎川慌,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體祠乃,經(jīng)...
    沈念sama閱讀 45,693評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡梦重,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,885評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了亮瓷。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片琴拧。...
    茶點(diǎn)故事閱讀 40,001評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖嘱支,靈堂內(nèi)的尸體忽然破棺而出蚓胸,到底是詐尸還是另有隱情挣饥,我是刑警寧澤,帶...
    沈念sama閱讀 35,723評(píng)論 5 346
  • 正文 年R本政府宣布沛膳,位于F島的核電站扔枫,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏锹安。R本人自食惡果不足惜短荐,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,343評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望叹哭。 院中可真熱鬧忍宋,春花似錦、人聲如沸风罩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,919評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽超升。三九已至入宦,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間室琢,已是汗流浹背云石。 一陣腳步聲響...
    開封第一講書人閱讀 33,042評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留研乒,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,191評(píng)論 3 370
  • 正文 我出身青樓淋硝,卻偏偏與公主長(zhǎng)得像雹熬,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子谣膳,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,955評(píng)論 2 355