5주차발표_데모 - g-market/b-shop-backend GitHub Wiki

📈 진행률

📝 금주 수행 작업

📌 재고 관련 동시성 제어

1) 어떤 lock을 이용하여 제어할지

  • Synchronized
    • 서버가 2대 이상일 경우, 동시성 제어 불가능
  • Pessimistic Lock(비관적 락)
    • 실제로 데이터에 lock을 걸어 정합성을 맞추는 방식
    • deadlock 발생 가능성, db에 직접 lock 걸기 때문에 성능저하가 유발될 수 있다.
  • Optimistic Lock(낙관적 락)
    • version을 통해 정합성을 맞춘다.
    • rollback 이 필요한 경우 직접 로직 작성해야함.
  • Redisson
    • Pub-sub 기반으로 Lock 구현 제공
    • 스핀락 방식을 사용하지 않고, timeout 기능을 통한 deadlock 방지, 분산환경에서 적합.

2) 재고 관련 고려해야 하는 기능

  • 주문 시 재고 감소
  • 주문 취소 시 재고 증가
  • 관리자가 재고를 update

3) 구현 과정 중 고민점

  • 주문 생성 로직 @Transactional
@Transactional
public OrderCreateResponseDto createOrder(final Long memberId, final 
	OrderCreateRequestDto orderCreateRequestDto) {
	OrderMapper.INSTANCE.ordersCreateDtoToEntity(memberId, orderCreateRequestDto);
	...
	itemOption.decreaseStockQuantity(count);
	...
	order.createOrder(orderItemList);
	orderRepository.save(order);
}

=> Facade 패턴을 이용하여 상위 계층 구성

@Service
public class OrderLockFacade {
	...
	public OrderCreateResponseDto purchase(final Long memberId, final OrderCreateRequestDto orderCreateRequestDto) {
		Order order = orderService.createOrder(memberId, orderCreateRequestDto);
		//lock
		List<OrderItem> orderItemList = lockItemOptionList(orderCreateRequestDto.orderItemDtoList(), order);
		//lock finish
		OrderCreateResponseDto responseDto = orderService.saveOrder(order, orderItemList);
	
		return responseDto;
	}
}

=> Redisson을 사용한 lock 구현

public List<OrderItem> lockItemOption(List<OrderItemDto> list, Order order) {
	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 rlock : lockList) {
			available = rlock.tryLock(5, 5, 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());
	}
	return returnList;
}  

=> 개선해야할 점

  • timeout 시간
rlock.tryLock(5, 5, TimeUnit.SECONDS); // watiTime, leaseTime
  • Lock을 걸 때 최소한의 데이터로
  • DB IO 최소화

  • 장바구니

  • 모니터링(Sentry)

  • minIO 이미지 업로드

  • envers 적용(상품 트랜잭션 로그)

  • 카테고리별 조회 기능 구현

  • 카테고리 관리 기능 구현

고민했던 이슈 또는 개선 작업?

TODO

  • 기존 코드 리팩토링
  • CD 파이프라인
    • dockerfile 작성
    • gitlab container registry 등록
    • nginx
      • blue green 배포전략을 적용해 무중단 배포환경을 구축
  • 동시성 제어
    • Redis를 통한 thread락 기능을 적용해 재고에 대한 동시성 제어 로직을 구현하고자 함
  • 프론트엔드 구현
    • 백엔드 기능 구현이 끝나면 시작
⚠️ **GitHub.com Fallback** ⚠️