SpringBoot 사용 분산 잠금

종종 우리는 동기화를 스레드에 잠금 장치를 사용하여, 프로젝트의 동시성 보안 문제를 발생합니다. 그래서 우리는 상황에 따라 키워드 동기화 방법 또는 코드 블록을 사용하여 수정할 수 있습니다. 또한, 잠금의 더 유연, 제한 시간, 공정성과 다른 장점을 잠글 수 있습니다 동기화 된 키워드와 비교 달성하기 위해 잠금 후 자바 5를 사용할 수 있습니다. 그러나 동기화 된 키워드 및 범위는 동시에 데이터 액세스의 하나의 스레드 만, 우리는 중간층의 사용을 고려할 수 있음을 보장 할 수 없습니다, 배포를 배포하는 경우에만 현재 응용 프로그램을 잠금

다음으로, 분산에 대한 간략한 소개는 자신의 오픈 소스 사용 잠금

A. 가져 오기 종속성

<dependency>
    <groupId>cn.gjing</groupId>
    <artifactId>tools-redis</artifactId>
    <version>1.0.0</version>
</dependency>

II. 수업 노트를 표시 시작

/**
 * @author Gjing
 */
@SpringBootApplication
@EnableRedisLock
public class TestRedisApplication {
    public static void main(String[] args) {
        SpringApplication.run(TestRedisApplication.class, args);
    }
}

III. 특정 사용

매개 변수 정보

  • 키 잠금 키에 대응
  • 값 : 임의의 문자열
  • 초, 만료 시간을 잠금 : 만료
  • 제한 시간 : 밀리 초, 잠금 타임 아웃을 획득
  • 다시 시도 : 밀리 초, 잠금 간격을 재 취득

1. 주석 모드

  • @Lock (문자열 키, INT 시간 제한, INT 재시도 만료 INT)
/**
 * @author Gjing
 **/
@RestController
public class TestController {
    private static int num = 20;
    @GetMapping("/test1")
    @Lock(key = "test1")
    public void test1() {
        System.out.println("当前线程:" + Thread.currentThread().getName());
        if (num == 0) {
            System.out.println("卖完了");
            return;
        }
        num--;
        System.out.println("还剩余:" + num);
    }
}

압력 측정 AB의 결과
AB1

2. 수동 제어 모드

  • 사출 AbstractLock 의존성
    @Resource
    private AbstractLock abstractLock;
  • 그렇지 않은 경우는 null를 돌려, 성공적인 리턴 값의 잠금을 해제하기 위해 잠금을 획득 abstractLock.lock ()을, 가입 장소에서 잠 그려면

문자열 잠금 (문자열 키, 문자열 값, 만료 INT, INT 시간 제한, INT 재시도)

  • 장소는 null를 돌려 그렇지 않으면 abstractLock.release (), 성공적으로 키를 반환 잠금 해제 잠금의 현재 릴리스를 사용하여 발매 예정

문자열 릴리스 (문자열 키, 문자열 값)

  • 사용 사례
/**
 * @author Gjing
 **/
@RestController
public class LockController {

    @Resource
    private AbstractLock abstractLock;

    private static int num = 10;

    @GetMapping("/test2")
    public void test2() {
        String lock = null;
        try {
            lock = this.abstractLock.lock("testLock", RandomUtil.generateMixString(5), 20, 10000, 50);
            System.out.println("当前线程:" + Thread.currentThread().getName());
            if (num == 0) {
                System.out.println("卖完了");
                return;
            }
            num--;
            System.out.println("还剩余:" + num);
        } finally {
            this.abstractLock.release("testLock", lock);
        }
    }
}

AB 압력 측정 결과
AB2

주의! ! !

나쁜 결과를 초래 잠금을 공유하면서 그렇지 않으면 여러 방법을 생성합니다, 키를 대응하는 유일한 최고의 잠금, 수신 잠금 해제 값, 그렇지 않으면, 잠금을 해제하는 데 실패 피하기 위해 다른 잠금을 해제, 인수 값을 얻을 수있는 잠금해야합니다 사람들은 잠

3. 재 작성 예외 처리

당신이 AbstractLockTimeoutHandler 시간 제한 예외 처리 클래스를 상속 할 수있는 수익을 사용자 정의 할 경우, 잠금 타임 아웃, 기본적으로 시간 제한 예외 정보의 반환을 취득하기위한 요청 후

/**
 * @author Gjing
 **/
@Component
public class LockExceptionHandler extends AbstractLockTimeoutHandler {

    @Override
    public ResponseEntity timeoutAfter(TimeoutException e) {
        // TODO: 实现自定义处理的逻辑  
    }
}

4. 사용자 정의 구현 잠금

이 프로젝트는 당신이 당신의 자신의 잠금 장치를 사용하려는 경우, AbstartetLock 클래스를 상속 할 수있는 등, 잠금 조합을 구현 레디 스 루아 스크립트를 사용하여

/**
 * @author Gjing
 **/
public class DemoLock extends AbstractLock {
    @Override
    public String lock(String s, String s1, int i, int i1, int i2) {
        return null;
    }

    @Override
    public String release(String s, String s1) {
        return null;
    }
}

IV. 추천 용도

이 레디 스 감시 클러스터 상황에있는 경우 잠금 레디 스 센티넬 클러스터의 다른 별도의 독립 실행 형 레디 스를 사용하는 것이 좋습니다, 우리는 하나 이상의 레디 스를, 같은 주 두에서와 같은 그들 사이에 마스터 - 슬레이브 관계를 가지고 있습니다. 우리는 그 다음 주 라이브러리에 데이터를 쓸 라이브러리에 동기화 해당 명령을 설정합니다. 우리는 대응이 명령으로 잠금을 적용 할 때  setnx mykey myvalue 레디 스 센티넬 클러스터에서,이 명령은 먼저 중앙 도서관에 떨어졌다. 그런 다음 아래로 중앙 도서관을 생각하지만,이 데이터는 선거 기반 라이브러리의 라이브러리에서 라이브러리, 센티넬에서 동기화 할 수있는 충분한 시간이 아니다. 다른 클라이언트 실행하면이 시점에서, 우리의 새로운 중앙 도서관은이 시간에,이 데이터를있는 MyKey되지 않고  setnx mykey hisvalue , 성공적인 것, 즉 잠글 수 있습니다. 이것은이 시간에 두 개의 클라이언트가 잠금을 받았다가있는 것을 의미


환영 문제 및 버그, 댓글의 사용은, 나는 즉시 응답 업데이트됩니다

추천

출처yq.aliyun.com/articles/706641