-
Notifications
You must be signed in to change notification settings - Fork 0
6주차_전가영
백승주 edited this page Mar 29, 2023
·
1 revision
Redisson을 이용한 Lock 방식에 timeout
이 상당수 발생하는 문제가 존재하였습니다.
재고를 관리하는 ItemOption값을 기준으로 lock을 거는데,
이 경우 redisson을 이용하면 각각의 optionId마다 lock을 여러번 걸어야하는 단점
이 존재하였습니다.
for (int i = 0; i < list.size(); i++) {
RLock lock = redissonClient.getLock(String.format("%d", list.get(i).itemOptionId()));
lockList.add(lock);
}
try {
boolean available = false;
for (RLock r : lockList) {
available = r.tryLock(10, 10, TimeUnit.SECONDS);
}
if (!available) {
System.out.println("redisson getLock timeout");
throw new IllegalArgumentException();
} else {
returnList = orderService.lockItemOptionList(list, order);
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally {
lockList.forEach(rLock -> rLock.unlock());
}
- Timeout 발생
재고관련 정보가 DB에 존재하기 때문에 application단이 아닌 DB에서 lock을 제어하는 비관락 적용에 대해 고민해보게 되었습니다.
쿼리를 불러올때 한방 쿼리로 불러오기 때문에 Lock을 걸때 Redisson과 달리 묶어서 한번의 lock
으로 관리할 수 있다는 장점이 존재하였습니다.
따라서 비관락을 사용 후, 성능을 비교해보기로 했습니다.
@Override
public List<ItemOption> findByItemIdListAndIdListWithLock(List<OrderItemDto> orderItemDtoList) {
return jpaQueryFactory.select(itemOption)
.from(itemOption)
.where(Expressions.list(item.id, itemOption.id).in(searchItemIdAndItemOptionIdIn(orderItemDtoList)))
.orderBy(item.id.asc(), itemOption.id.asc())
.setLockMode(LockModeType.PESSIMISTIC_WRITE)
.fetch();
}
@Lock(LockModeType.PESSIMISTIC_WRITE)
Optional<ItemOption> findByIdAndItemIdWithLock(Long itemOptionId, Long itemId);
같은 쓰레드의 수를 테스트 코드로 성능을 비교해 본 결과, redisson은 timeout이 발생
하는 반면,
비관락의 경우 시간도 단축되고 재고의 정합성도 일치하여 비관락이 더 뛰어난 성능을 보이는 것을 확인
하였습니다.
=> Redisson은 DB가 여러 개로 분산되어 있거나 lock을 걸려고 하는 주체가 redis에 올라가 있을 경우 적절하다고 판단
또한, ItemOption을 각각 불러오던 쿼리에서 한 번의 쿼리로 불러오게끔 개선하여 수행 시간을 줄였습니다.
-
쿼리 성능 개선 전(각각 쿼리)
-
쿼리 성능 개선 후(한방 쿼리)
- 다양한 케이스에 대한 추가 테스트 코드 작성
- nGrinder를 사용한 성능 부하테스트
---
- 기존 코드 리팩토링
- CD 파이프라인
-
dockerfile
작성 - gitlab
container registry
등록 - nginx
-
blue green
배포전략을 적용해 무중단 배포환경을 구축
-
-
- 동시성 제어
-
Redis
를 통한thread락
기능을 적용해 재고에 대한 동시성 제어 로직을 구현하고자 함
-
- 프론트엔드 구현
- 페이징을 활용한 메인 화면
- 내 정보 수정 화면
- 상품 상세 화면
- 상품 주문 화면
-
상품 조회
(카테고리별, 년별) 기능 추가적으로 구현 - 상품관련 CRUD 기능
테스트코드
추가 구현
🏷️ 설계 문서
📚 팀 컨벤션
- Issue 작성 가이드
- Merge Request 작성 가이드
- Git 브랜치 전략
- Commit 컨벤션
- 백엔드 코드 컨벤션
- 객체 및 메서드생성 규칙
- Ground Rule
- Request Response 규칙
🔧 Setting
✍ 스프린트 기록