重復(fù)發(fā)消息工具

1、表設(shè)計

CREATE TABLE `b_log_access` (
  `fid` varchar(64) NOT NULL COMMENT '主鍵',
  `request_name` varchar(100) DEFAULT NULL COMMENT '請求名稱',
  `request_url` varchar(200) DEFAULT NULL COMMENT '請求地址',
  `request_parameter` longtext COMMENT '請求參數(shù)',
  `request_type` varchar(50) DEFAULT NULL COMMENT '請求模塊類型',
  `request_result` longtext COMMENT '請求返回結(jié)果',
  `request_appid` varchar(100) DEFAULT NULL COMMENT '請求應(yīng)用id',
  `request_key` varchar(100) DEFAULT NULL COMMENT '請求應(yīng)用key例如密碼等',
  `request_secret` varchar(1000) DEFAULT NULL COMMENT '請求參數(shù)密鑰',
  `request_id` varchar(200) DEFAULT NULL COMMENT '請求關(guān)鍵id例如訂單號等',
  `return_status` varchar(20) DEFAULT '200' COMMENT '請求返回狀態(tài)結(jié)果,默認:200成功',
  `is_repeat` int(2) DEFAULT '0' COMMENT '失敗是否重復(fù)請求安疗;0:否沧烈,1:是',
  `repeat_times` int(11) DEFAULT '0' COMMENT '針對請求失敗重復(fù)請求次數(shù)',
  `is_remove` int(2) DEFAULT '0' COMMENT '請求成功是否根據(jù)移除時間自動移除; 0:否;1:是',
  `remove_seconds` int(11) DEFAULT '10' COMMENT '根據(jù)最后更新時間自動移除時間晌纫,單位(s)',
  `create_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '創(chuàng)建時間',
  `last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新時間',
  `last_modifyer` varchar(64) DEFAULT 'N' COMMENT '記錄最后修改人 關(guān)聯(lián)b_user.fid',
  `creater` varchar(64) DEFAULT 'N' COMMENT '記錄創(chuàng)建人 關(guān)聯(lián)b_user.fid',
  `client_id` varchar(64) DEFAULT 'N' COMMENT '記錄所屬租戶 關(guān)聯(lián)b_client.fid',
  PRIMARY KEY (`fid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;

2、邏輯構(gòu)思

1永丝、 數(shù)據(jù)異步插入 b_log_access表 的方法缸匪;
2、每10s執(zhí)行(請求失敗重復(fù)請求类溢、請求成功超時的請求)
3凌蔬、查詢請求失敗的請求列表、查詢請求成功的請求列表
4闯冷、超時時間算法函數(shù)

3砂心、代碼

package cn.ivg.service.impl;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import cn.invengo.common.utils.FastJsonUtils;
import cn.ivg.cscm.log.model.entity.LogAccessWithBLOBs;
import cn.ivg.cscm.log.service.IRepLogAccessService;
import cn.ivg.framework.comp.idGen.IdGenUtil;
import cn.ivg.model.LogAccessEx;
import cn.ivg.service.ILogAccessService;
import cn.ivg.service.RepeatCallback;

@Service
public class LogAccessServiceImpl implements ILogAccessService, InitializingBean {
    static Logger log = LoggerFactory.getLogger(LogAccessServiceImpl.class);
    /**
     * 失敗重復(fù)執(zhí)行調(diào)用緩存類
     */
    private Map<String, RepeatCallback> callbackMap = new ConcurrentHashMap<>();
    /**
     * 請求日志調(diào)度守護線程
     */
    private Timer logAccessTimeSchedule = new Timer("Log_access_schedule");
    @Autowired
    private IRepLogAccessService repLogAccessService;
    @Autowired
    private Executor taskExecutor;
    @Autowired
    private IdGenUtil idGenUtil;

    @Override
    public void AsynRecordAccessLog(LogAccessEx record, boolean isprint) {
        // TODO Auto-generated method stub
        if (isprint) {
            log.info(FastJsonUtils.toJSONString(record));
        }
        taskExecutor.execute(new Runnable() {

            @Override
            public void run() {
                // TODO Auto-generated method stub
                record.setCreateDate(new Date());
                record.setFid(idGenUtil.getId());
                record.setLastUpdate(new Date());
                repLogAccessService.insertSelective(record);
            }
        });

    }

    @Override
    public void RegisterRepeatCallback(String requestType, RepeatCallback callback) {
        // TODO Auto-generated method stub
        if(Objects.isNull(callbackMap.get(requestType))){
            callbackMap.put(requestType, callback); 
        }
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        // 10秒執(zhí)行一次請求及移除
        logAccessTimeSchedule.schedule(new DealAccessLogTask(), 10 * 1000, 10 * 1000);
    }

    @Override
    public List<LogAccessWithBLOBs> repeatCallList() {
        // TODO Auto-generated method stub
        LogAccessWithBLOBs record = new LogAccessWithBLOBs();
        record.setIsRepeat(Constant.REPEAT_OK);
        record.setReturnStatus(Constant.STATUS_ERRO);
        return repLogAccessService.select(record);
    }

    @Override
    public List<LogAccessWithBLOBs> removeList() {
        // TODO Auto-generated method stub
        LogAccessWithBLOBs record = new LogAccessWithBLOBs();
        record.setIsRemove(Constant.REMOVE_OK);
        record.setReturnStatus(Constant.STATUS_OK);
        return repLogAccessService.select(record);
    }

    @Override
    public long diffNow(Date date) {
        // TODO Auto-generated method stub
        return System.currentTimeMillis() - date.getTime();
    }

    /**
     * 分類處理請求日志任務(wù)
     * 
     * @author tao.tang
     * @date 2019/01/23
     */
    class DealAccessLogTask extends TimerTask {

        @Override
        public void run() {
            try {
                // 失敗請求重復(fù)請求
                List<LogAccessWithBLOBs> repeatList = repeatCallList();
                for (LogAccessWithBLOBs repeat : repeatList) {
                    if (ObjectUtils.isEmpty(callbackMap.get(repeat.getRequestType()))) {
                        continue;
                    }
                    LogAccessEx repeatParam = new LogAccessEx();
                    BeanUtils.copyProperties(repeat, repeatParam);
                    //根據(jù)請求次數(shù)延長下一次重復(fù)調(diào)用時間
                    if (diffNow(repeatParam.getLastUpdate()) > repeatParam.getRepeatTimes() * Constant.REPEAT_BASE) {
                        repLogAccessService
                            .updateByPrimaryKeySelective(callbackMap.get(repeat.getRequestType()).excute(repeatParam));
                    }
                }
                // 處理已請求成功超時記錄
                List<LogAccessWithBLOBs> removeList = removeList();
                for (LogAccessWithBLOBs remove : removeList) {
                    //超時移除日志
                    if (diffNow(remove.getLastUpdate()) > remove.getRemoveSeconds() * 1000) {
                        repLogAccessService.deleteByPrimaryKey(remove.getFid());
                    }
                }
            } catch (Exception e) {
                log.error("定時器Log_access_schedule執(zhí)行異常", e);

            }
        }

    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市蛇耀,隨后出現(xiàn)的幾起案子辩诞,更是在濱河造成了極大的恐慌,老刑警劉巖纺涤,帶你破解...
    沈念sama閱讀 218,451評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件译暂,死亡現(xiàn)場離奇詭異抠忘,居然都是意外死亡,警方通過查閱死者的電腦和手機外永,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評論 3 394
  • 文/潘曉璐 我一進店門崎脉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人伯顶,你說我怎么就攤上這事囚灼。” “怎么了祭衩?”我有些...
    開封第一講書人閱讀 164,782評論 0 354
  • 文/不壞的土叔 我叫張陵灶体,是天一觀的道長。 經(jīng)常有香客問我掐暮,道長蝎抽,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,709評論 1 294
  • 正文 為了忘掉前任路克,我火速辦了婚禮樟结,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘衷戈。我一直安慰自己狭吼,他們只是感情好层坠,可當(dāng)我...
    茶點故事閱讀 67,733評論 6 392
  • 文/花漫 我一把揭開白布殖妇。 她就那樣靜靜地躺著,像睡著了一般破花。 火紅的嫁衣襯著肌膚如雪谦趣。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,578評論 1 305
  • 那天座每,我揣著相機與錄音前鹅,去河邊找鬼。 笑死峭梳,一個胖子當(dāng)著我的面吹牛舰绘,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播葱椭,決...
    沈念sama閱讀 40,320評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼捂寿,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了孵运?” 一聲冷哼從身側(cè)響起秦陋,我...
    開封第一講書人閱讀 39,241評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎治笨,沒想到半個月后驳概,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體赤嚼,經(jīng)...
    沈念sama閱讀 45,686評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,878評論 3 336
  • 正文 我和宋清朗相戀三年顺又,在試婚紗的時候發(fā)現(xiàn)自己被綠了更卒。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,992評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡待榔,死狀恐怖逞壁,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情锐锣,我是刑警寧澤腌闯,帶...
    沈念sama閱讀 35,715評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站雕憔,受9級特大地震影響姿骏,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜斤彼,卻給世界環(huán)境...
    茶點故事閱讀 41,336評論 3 330
  • 文/蒙蒙 一分瘦、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧琉苇,春花似錦嘲玫、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,912評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至穷蛹,卻和暖如春土陪,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背肴熏。 一陣腳步聲響...
    開封第一講書人閱讀 33,040評論 1 270
  • 我被黑心中介騙來泰國打工鬼雀, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蛙吏。 一個月前我還...
    沈念sama閱讀 48,173評論 3 370
  • 正文 我出身青樓源哩,卻偏偏與公主長得像,于是被迫代替她去往敵國和親鸦做。 傳聞我的和親對象是個殘疾皇子励烦,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,947評論 2 355

推薦閱讀更多精彩內(nèi)容