Heim > Java > javaLernprogramm > So verwenden und implementieren Sie die Funktion der verteilten Sperre Java-Redis-Redisson

So verwenden und implementieren Sie die Funktion der verteilten Sperre Java-Redis-Redisson

PHPz
Freigeben: 2023-05-14 21:55:04
nach vorne
828 Leute haben es durchsucht

Front-End

Wir haben die Java-Redis-Redisson-Konfiguration geändert, um die Verwendung von Sperren komfortabler zu gestalten

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RedissonLock {
    int lockTime() default 3; //加锁的时间默认3秒,  如果任务在3秒内执行完毕那么自动释放锁,如果任务3秒内没有执行完毕也会释放锁, 所以内容执行时间过长适当加大锁的时间
    String key() default "" ;  //唯一标识,如果没有那么默认为token->sessionId
    String doc() default "重复提交请求,请稍后再试";
    boolean repeatLock() default false; //可重复加锁直到加锁成功,默认为false不能重复加锁
    int repeatLockCount() default -1; //可重复加锁限制加锁的次数, 默认-1直到成功,设置10那么加锁10次都没成功就直接返回
    int lockWaitTimeMs() default 100; //重复加锁默认的阻塞时间100毫秒,可以自己定义
}
Nach dem Login kopieren

Funktionsnutzung Und Einführung

Unterstützt Konfigurationssperrzeit

Unterstützt Konfigurationssperrschlüssel (Anfragen für denselben Schlüssel werden gesperrt)

Unterstützt wiederholtes Sperren

  • Unterstützt die Anzahl wiederholter Sperren

  • Unterstützt die Intervall zwischen wiederholten Sperren

  • Durch die Kombination der oben genannten Funktionen können Idempotenz, verteiltes pessimistisches Sperren und Timeout-Verwerfen erreicht werden. Es wird nicht nur im Controller verwendet, sondern wird auch in allen Spring-basierten Containerverwaltungs-Beans unterstützt . Wenn es spezielle Szenarien gibt, können wir die Sperre jederzeit direkt aufheben

    import com.application.Result;
    import com.commonutils.NullUtils;
    import com.redis.utils.DistributedRedisLock;
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Pointcut;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Component;
    import org.springframework.util.Assert;
    import org.springframework.web.context.request.RequestContextHolder;
    import org.springframework.web.context.request.ServletRequestAttributes;
    import javax.servlet.http.HttpServletRequest;
    @Aspect
    @Component
    public class RepeatSubmitAspect {
        @Value("${spring.redis.redisson.tokenName}")
        private  String tokenName;
        @Autowired
        private DistributedRedisLock redisLock;
        @Pointcut("@annotation(noRepeatSubmit)")
        public void pointCut(RedissonLock noRepeatSubmit) {
        }
        public static HttpServletRequest getRequest() {
            ServletRequestAttributes ra= (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            return ra.getRequest();
        }
        @Around("pointCut(noRepeatSubmit)")
        public Object around(ProceedingJoinPoint pjp, RedissonLock noRepeatSubmit) throws Throwable {
            int lockSeconds = noRepeatSubmit.lockTime();
            String doc = noRepeatSubmit.doc();
            String keyName = noRepeatSubmit.key();
            boolean b = noRepeatSubmit.repeatLock();
            int repeatLockCount = noRepeatSubmit.repeatLockCount();
            int lockWaitTimeMs = noRepeatSubmit.lockWaitTimeMs();
            HttpServletRequest request = getRequest();
            Assert.notNull(request, "request can not null");
            //如果没有唯一表示那么就使用token或者sessionID来唯一表示
            if(!NullUtils.notEmpty(keyName)){
                String token = request.getHeader(tokenName);
                if(NullUtils.notEmpty(token)){
                    keyName=token;
                }else{
                    //使用sessionID (注意保证分布式session共享)
                    keyName = request.getSession().getId();
                }
                System.out.println("tokenName:"+keyName);
            }
            String path = request.getServletPath();
            String key = getKey(keyName, path);
            //加锁
            boolean isSuccess = redisLock.acquire(key, lockSeconds,b,repeatLockCount,lockWaitTimeMs);
            if (isSuccess) {
                // 获取锁成功
                Object result;
                try {
                    // 执行
                    result = pjp.proceed();
                } finally {
                    // 解锁
                    redisLock.release(key);
                }
                return result;
            } else {
                // 获取锁失败,认为是重复提交的请求
                return Result.Error(doc);
            }
        }
        private String getKey(String token, String path) {
            return token + path;
        }
    }
    Nach dem Login kopieren
    Überprüfungsmethode: Verwenden Sie Jmeter-Multithreading-10000-Anfragen Bei der Verwendung von jmeter müssen wir manuell einen Schlüssel hinzufügen oder einen Token verwenden, um den Effekt zu überprüfen, da die Sitzungs-ID jedes Mal anders ist

    Das obige ist der detaillierte Inhalt vonSo verwenden und implementieren Sie die Funktion der verteilten Sperre Java-Redis-Redisson. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Aktuelle Ausgaben
Kann Java als Backend des Webs verwendet werden?
Aus 1970-01-01 08:00:00
0
0
0
Installieren Sie JAVA
Aus 1970-01-01 08:00:00
0
0
0
Java kann nicht installiert werden
Aus 1970-01-01 08:00:00
0
0
0
Ist das in der Java-Sprache?
Aus 1970-01-01 08:00:00
0
0
0
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage