SpringBoot 의 사용 Redis 는 분포 식 잠 금(스톱워치 시스템)을 실현 합 니 다.
8473 단어 SpringBootRedis분산 식 자물쇠
Redis 의 공식 추천 Redisson 을 redis 의 분포 식 자물쇠 로 직접 사용 하 는 것 을 권장 합 니 다.
1.1 분포 식 자 물 쇠 를 왜 사용 하 는가
우리 가 응용 프로그램 을 개발 할 때 어떤 공유 변수 에 대해 다 중 스 레 드 동기 화 접근 이 필요 할 때 우리 가 배 운 자바 다 중 스 레 드 의 18 가지 무 예 를 사용 하여 처리 할 수 있 고 완벽 하 게 운행 할 수 있 으 며 bug 가 없습니다!
이것 은 단기 응용 프로그램 입 니 다.즉,모든 요청 이 현재 서버 의 JVM 내부 에 분 배 된 다음 에 운영 체제 의 스 레 드 로 매 핑 하여 처리 합 니 다!이 공유 변 수 는 이 JVM 내부 의 메모리 공간 일 뿐 입 니 다!
나중에 업무 가 발전 하려 면 군집 을 해 야 한다.하나의 응용 은 몇 대의 기계 에 배치 한 다음 에 부하 균형 을 이 루어 야 한다.대체적으로 다음 과 같다.
위의 그림 에서 볼 수 있 듯 이 변수 A 는 JVM 1,JVM 2,JVM 3 세 개의 JVM 메모리 에 존재 합 니 다.세 가지 요청 을 보 내 면서 이 변 수 를 동시에 조작 하 는 것 은 분명히 결과 가 틀 렸 다!동시에 보 내지 않 더 라 도 세 개의 요청 은 각각 세 개의 서로 다른 JVM 메모리 구역 의 데 이 터 를 조작 합 니 다.변수 A 간 에 공유 가 존재 하지 않 고 가시 성 이 없 으 며 처리 결과 도 잘못 되 었 습 니 다!
만약 우리 업무 에 이 장면 이 확실히 존재 한다 면 우 리 는 이 문 제 를 해결 하 는 방법 이 필요 하 다!
하나의 방법 이나 속성 이 높 은 동시 다발 상황 에서 같은 시간 에 같은 스 레 드 로 만 실 행 될 수 있 도록 전통 적 인 단일 응용 단일 기기 배치 의 경우 자바 동시 처리 와 관련 된 API(예 를 들 어 ReentrantLock 또는 Synchronized)를 사용 하여 상호 배척 통 제 를 할 수 있다.단일 컴퓨터 환경 에서 자바 에 서 는 병렬 처리 와 관련 된 API 를 많이 제공 합 니 다.그러나 업무 발전의 수요 에 따라 원 단일 기기 배치 시스템 이 분포 식 클 러 스 터 시스템 으로 진화 한 후에 분포 식 시스템 의 다 중 스 레 드,다 중 프로 세 스 가 서로 다른 기계 에 분포 되 기 때문에 원 단일 기기 배치 상황 에서 의 병행 제어 잠 금 전략 이 효력 을 잃 고 단순 한 자바 API 는 분포 식 잠 금 능력 을 제공 할 수 없다.이 문 제 를 해결 하기 위해 서 는 JVM 을 뛰 어 넘 는 상호 배척 체제 로 공유 자원 의 방문 을 통제 해 야 한다.이것 이 바로 분포 식 자물쇠 가 해결 해 야 할 문제 이다!
1.2 분포 식 자 물 쇠 는 어떤 조건 을 갖 추어 야 하 는가
분포 식 자물쇠 의 세 가지 실현 방식 을 분석 하기 전에 분포 식 자물쇠 가 어떤 조건 을 갖 춰 야 하 는 지 알 아 보 자.
1.분포 식 시스템 환경 에서 한 방법 은 같은 시간 에 한 기계 의 한 라인 에 만 실 행 될 수 있다.
2.높 은 사용 가능 한 자물쇠 획득 및 잠 금 해제;
3.고성능 의 잠 금 획득 과 잠 금 해제;
4.재 입 가능 한 특성 을 가진다.
5.잠 금 실효 체 제 를 갖 추고 잠 금 을 방지 합 니 다.
6.비 차단 잠 금 기능 이 있 습 니 다.즉,잠 금 을 가 져 오지 않 으 면 잠 금 을 가 져 오 는 데 실 패 했 습 니 다.
1.3 분포 식 자물쇠 의 세 가지 실현 방식
현재 거의 많은 대형 사이트 와 응용 은 분포 식 으로 배치 되 어 있 고 분포 식 장면 에서 의 데이터 일치 성 문 제 는 비교적 중요 한 화제 이다.분산 식 CAP 이론 은"어떤 분산 식 시스템 도 일치 성(Consistency),가용성(Availability),파 티 션 용 착 성(Partition tolerance)을 동시에 만족 시 키 지 못 하고 최대 두 가지 만 동시에 만족 시 킬 수 있다"고 말 했다.그래서 많은 시스템 이 디자인 초기 에 이 세 가 지 를 취사선택 해 야 한다.인터넷 분야 의 절대 다수의 장면 에서 강 한 일치 성 을 희생 하여 시스템 의 높 은 가용성 을 바 꿔 야 한다.시스템 은 흔히'최종 일치 성'만 확보 해 야 한다.이 최종 시간 이 사용자 가 받 아들 일 수 있 는 범위 안에 있 으 면 된다.
많은 장면 에서 우 리 는 데이터 의 최종 일치 성 을 확보 하기 위해 분포 식 사무,분포 식 자물쇠 등 많은 기술 방안 을 지원 해 야 한다.때때로 우 리 는 하나의 방법 이 같은 시간 내 에 같은 라인 에서 만 실 행 될 수 있다 는 것 을 보증 해 야 한다.
1.데이터 베 이 스 를 바탕 으로 분포 식 잠 금 을 실현 한다.
2.캐 시(Redis 등)를 기반 으로 분포 식 잠 금 을 실현 한다.
3.Zookeeper 를 바탕 으로 분포 식 잠 금 을 실현 합 니 다.
비록 이 세 가지 방안 이 있 지만 서로 다른 업 무 는 자신의 상황 에 따라 모델 링 을 해 야 한다.그들 사이 에 가장 좋 은 것 은 없고 더 적합 할 뿐이다!
2.Redis 분포 식 잠 금 실전 편
2.1 도입 의존
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-redis</artifactId>
<version>1.4.7.RELEASE</version>
</dependency>
2.2,설정 Redis 설정 정보
spring
redis:
port: 6379
host: 127.0.0.1
password:
database: 0
2.3,RedisConfig 속성 을 설정 합 니 다.FastJSON 을 사용 하여 대상 을 정렬 해 야 한다 면 제 가 앞에서 쓴 글 을 보 세 요.
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate initRedisTemplate(RedisConnectionFactory redisConnectionFactory) throws Exception {
RedisTemplate redisTemplate = new RedisTemplate();
redisTemplate.setConnectionFactory(redisConnectionFactory);
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(new JdkSerializationRedisSerializer());
redisTemplate.setDefaultSerializer(new StringRedisSerializer());
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
}
2.4 RedisLock 도구 클래스 쓰기
/**
* @Description // Redis
* Redis , Redisson
* @Date $ $
* @Author huangwb
**/
@Component
public class RedisLockCommon {
@Autowired
private StringRedisTemplate stringRedisTemplate;
/**
* Redis
*
* @param key
* @param value
* @return
*/
public Boolean tryLock(String key, String value) {
if (stringRedisTemplate.opsForValue().setIfAbsent(key, value)) {
return true;
}
String currentValue = stringRedisTemplate.opsForValue().get(key);
if (StringUtils.isNotEmpty(currentValue) && Long.valueOf(currentValue) < System.currentTimeMillis()) {
//
String oldValue = stringRedisTemplate.opsForValue().getAndSet(key, value);
if (StringUtils.isNotEmpty(oldValue) && oldValue.equals(currentValue)) {
return true;
}
}
return false;
}
/**
* Redis
*
* @param key
* @param value
*/
public void unlock(String key, String value) {
String currentValue = stringRedisTemplate.opsForValue().get(key);
try {
if (StringUtils.isNotEmpty(currentValue) && currentValue.equals(value)) {
stringRedisTemplate.opsForValue().getOperations().delete(key);
}
} catch (Exception e) {
}
}
}
2.5.재고 감소 작업
@Override
public boolean decrementProductStore(Long productId, Integer productQuantity) {
String key = "dec_store_lock_" + productId;
long time = System.currentTimeMillis();
try {
//
if (!redisLock.tryLock(key, String.valueOf(time))) {
return false;
}
ProductInfo productInfo = productInfoMapper.selectByPrimaryKey(productId);
//
if (productInfo.getProductStock() == 0) {
return false;
}
//
productInfo.setProductStock(productInfo.getProductStock() - 1);
productInfoMapper.updateByPrimaryKey(productInfo);
} catch (Exception e) {
e.printStackTrace();
return false;
} finally {
//
redisLock.unlock(key, String.valueOf(time));
}
return true;
}
2.6 테스트 인터페이스
@GetMapping("test")
public String createOrderTest() {
if (!productInfoService.decrementProductStore(1L, 1)) {
return " ";
}
OrderMaster orderMaster = new OrderMaster();
//
orderMaster.setOrderStatus(0);
//
orderMaster.setPayStatus(0);
orderMaster.setBuyerName(" ");
orderMaster.setBuyerAddress(" ");
orderMaster.setBuyerPhone("18692794847");
orderMaster.setOrderAmount(BigDecimal.ZERO);
orderMaster.setCreateTime(DateUtils.getCurrentDate());
orderMaster.setOrderId(UUID.randomUUID().toString().replaceAll("-", ""));
orderMasterService.insert(orderMaster);
}
2.7 아파 치 ab 로 http 인터페이스 테스트 가능구체 적 인 문장 은 이 문장 을 볼 수 있다https://www.jb51.net/article/177250.htm
마지막
SpringBoot 의 Redis 사용 에 관 한 분포 식 잠 금(스톱워치 시스템)에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 SpringBoot Redis 분포 식 잠 금 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 시기 바 랍 니 다.앞으로 많은 응원 부탁드립니다!
문장 개관 편 은https://blog.csdn.net/hxpjava1/article/details/81068355
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
【Java・SpringBoot・Thymeleaf】 에러 메세지를 구현(SpringBoot 어플리케이션 실천편 3)로그인하여 사용자 목록을 표시하는 응용 프로그램을 만들고, Spring에서의 개발에 대해 공부하겠습니다 🌟 마지막 데이터 바인딩에 계속 바인딩 실패 시 오류 메시지를 구현합니다. 마지막 기사🌟 src/main/res...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.