91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何用AOP注解方式實現redis分布式搶占鎖

發布時間:2021-07-06 10:26:01 來源:億速云 閱讀:336 作者:chen 欄目:大數據

本篇內容主要講解“如何用AOP注解方式實現redis分布式搶占鎖”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“如何用AOP注解方式實現redis分布式搶占鎖”吧!

摘要

很多項目中都會有一些需要做定時跑批的任務需求,大多數是通過spring注解的方式實現的,但是到了生產環境,多節點的部署可能會造成定時任務的多節點同時觸發而可能會出現臟數據。之前的處理方案是通過在字典里配置指定生產節點處理定時任務。雖然此方法也能實現需求,但總覺得很low,所以自己就通過JAVA的AOP方式利用redis實現了一套分布式搶占鎖,通過注解的方式解決生產環境多節點部署帶來的定時任務觸發。

廢話不多說,直接上代碼--> 1、先自定義一個注解

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @author v_liuwen
 * @date 2018/12/27
 */
@Target({ElementType.METHOD,ElementType.TYPE}) // 作用到類,方法,接口上等
@Retention(RetentionPolicy.RUNTIME) // 在運行時可以獲取
public @interface RedisLock {
}

2、再新建一個切面類

import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import top.qrainly.bj_demo.job.springtask.scheduleJob.utils.RedisLockUtils;

/**
 * @author v_liuwen
 * @date 2018/12/27
 */
@Aspect
@Component
public class RedisLockAspect {

    private static Logger logger = LoggerFactory.getLogger(RedisLockAspect.class);

    /**
     * 切面 加有 RedisLock 的 service 方法
     */
    @Pointcut("@annotation(redisLock)")
    private void cutMethod(RedisLock redisLock) {
    }

    @Before("cutMethod(redisLock)")
    public void doAccessCheck(JoinPoint point,RedisLock redisLock) throws NoSuchMethodException {
        logger.info("********************************【Before】開始進入AOP切入**************************************");
    }

    @After("cutMethod(redisLock)")
    public void after(JoinPoint point,RedisLock redisLock) {
        logger.info("********************************【after】AOP切入完成**************************************");
    }

    @AfterThrowing("cutMethod(redisLock)")
    public void doAfterThrow(RedisLock redisLock) {
        logger.info("AfterThrowing...");
    }


    @Around("cutMethod(redisLock)")
    public void around(ProceedingJoinPoint point,RedisLock redisLock){
        String name = point.getSignature().getName();
        Class<?> classTarget = point.getTarget().getClass();
        System.out.println("--------------------------------------->>>AOP切入 方法名:"+name+"<<<-----------------------------------------------------");
        System.out.println("--------------------------------------->>>AOP切入 類名:"+classTarget.getSimpleName()+"<<<-----------------------------------------------------");
        //獲取redis鎖
        Boolean lock = RedisLockUtils.acquireRedisLock(StringUtils.join(classTarget.getSimpleName(),name), 5);
        if(lock){
            try {
                point.proceed();
            } catch (Throwable throwable) {
               logger.error("AOP 代理執行失敗");
            }
        }
    }


}

3、在需求做定時任務的方法上添加自定義注解@RedisLock

/**
     * 測試批處理
     */
    @Override
    @RedisLock
    public void syncTest() {
        try{
            //獲取所有需要同步狀態的付款單據
            List<String> allNeedSyncStatusForPayment = batchDAO.getAllNeedSyncStatusForPayment();
            SimpleDateFormat sdf = new SimpleDateFormat();
            System.out.println("*****************************************"+sdf.format(new Date())+"開始***********************************************");
            System.out.println(JSON.toJSONString(allNeedSyncStatusForPayment));
            System.out.println("*****************************************"+sdf.format(new Date())+"結束***********************************************");
        }catch (Exception e){
            logger.error(e.getMessage());
        }
    }

4、注意事項: 4.1 注解不要放在service層 反射代理會繞過spring注解

補充RedisLockUtils

/**
 * @author v_liuwen
 * @date 2018/12/26
 */
public class RedisLockUtils {

    /**
     * 日志打印
     */
    private static Logger logger = LoggerFactory.getLogger(RedisLockUtils.class);

    private static Jedis jedis;

    /**
     * 獲取jedis
     *
     * @return
     */
    public static Jedis getJedis() {
        Jedis jedis = SpringContextHolder.getBean(JedisUtils.class).getResource();
        return jedis;

    }
    /**
     * 釋放jedis
     *
     * @return
     */
    public static void releaseJedis(Jedis jedis) {
        jedis.close();
    }

    /**
     * 搶占執行權 鎖
     * @param lockName
     * @param lockExpire
     * @return
     */
    public static Boolean acquireRedisLock(String lockName,int lockExpire){
        Jedis jedis = getJedis();
        String identifier = UUID.randomUUID().toString();
        String lockKey = lockName;
        try{
            if (jedis.setnx(lockKey, identifier) == 1) {
                logger.info("Get lock {} success:{}.",lockName,identifier);
                jedis.expire(lockKey,lockExpire);
                if (jedis.ttl(lockKey) == -1) {
                    jedis.expire(lockKey, lockExpire);
                }
                return true;
            }
            return false;
        }catch (Exception e){
            logger.error(e.getMessage());
            return false;
        }finally {
            if(jedis !=null){
                releaseJedis(jedis);
            }
        }
    }
}

到此,相信大家對“如何用AOP注解方式實現redis分布式搶占鎖”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

伊金霍洛旗| 西盟| 静乐县| 普洱| 庄河市| 齐河县| 鄂尔多斯市| 华蓥市| 西乌| 华坪县| 原平市| 临澧县| 靖远县| 托里县| 武穴市| 措勤县| 乌鲁木齐县| 南通市| 平南县| 璧山县| 札达县| 运城市| 乌拉特中旗| 陈巴尔虎旗| 麟游县| 拉孜县| 任丘市| 北票市| 剑河县| 仙桃市| 卢氏县| 讷河市| 武定县| 离岛区| 日土县| 常山县| 伊宁县| 当涂县| 崇明县| 万盛区| 土默特右旗|