타임딜 이커머스 서비스의 동시성 처리 프로젝트
Feat branch : 기능 개발 브랜치
Dev branch : 로컬 환경, 개발 코드, 테스트, 병합 브랜치
Main branch : 배포 브랜치
- feat -> dev 로 개발 후 pull Request
- sonarcloud 기반 정적 코드 분석, 테스트 커버리지 확인
- dev 브랜치 병합 후 main 브랜치로 push, merge
- 회원가입
POST :/api/users
Request -> 201Created
{
"uesrname":String
"password":String
"role":Enum [USER, ADMIN]
}
- 로그인
POST :/api/auth/
Request -> 200OK
{
"username":String
"password":String
}
- 회원탈퇴
DELETE :/api/users
JSESSIONID:<Id>
- 회원조회
GET :/api/users
JSESSIONID:<Id>
Response 200OK
{
"username":String
"role":Enum [USER, ADMIN]
"createdAt":"yyyy-MM-ddTHH:mm:ss"
}
- 상품생성
POST :api/products
Reqeust -> 201Created
Session[role -> ADMIN]
{
"name":String
"description":String
"quantity":long
"price":long
"dealtime":"yyyy-MM-ddTHH:mm:ss"
}
- 상품상세
GET:api/products/<productId>
Response 200OK
{
"name":String
"description":String
"quantity":long
"price":long
"dealtime":"yyyy-MM-ddTHH:mm:ss"
"createdAt":"yyyy-MM-ddTHH:mm:ss"
"updatedAt":"yyyy-MM-ddTHH:mm:ss"
}
- 상품목록
GET:api/products
Response 200OK
[
{
"id":UUID
"name":String
"description":String
"quantity":long
"price":long
"dealtime":"yyyy-MM-ddTHH:mm:ss"
"createdAt":"yyyy-MM-ddTHH:mm:ss"
"updatedAt":"yyyy-MM-ddTHH:mm:ss"
}
]
- 상품수정
PATCH:api/products/<productId>
Request -> 200OK
Session[role -> ADMIN]
{
"name":String
"description":String
"quantity":long
"price":long
"dealtime":"yyyy-MM-ddTHH:mm:ss"
}
- 상품삭제
DELETE:api/products/<ProductId>
Session[role -> ADMIN] -> 200OK
- 주문생성
POST:api/orders/<productID>
JSESSIONID : <id> role:USER -> 201Created
- 유저의 주문목록
GET:api/orders
Response 200OK
[
{
"orderId":UUID
"productId":UUID
"productName":String
}
]
- 상품 주문유저목록
GET:api/orders/<productId>
Response 200OK
[
{
"orderId":UUID
"userId":UUID
"username":String
}
]
- 현재 synchronized 키워드를 이용한 동시성 처리가 되어있습니다. 이후에 Optimistic Lock, Pessimistic Lock, Redis를 이용한 Lock으로 각각 성능을 테스트 해볼 계획인데 ngrinder controller와 agent를 같은 서버에 두니 CPU에 무리가 가서 제대로된 테스트가 되지 않는것으로 예상됩니다. 서버 분리 이후 성능 측정 및 개선을 해나갈 것 같습니다.
-
- 멀티 스레드 환경에서 하나의 상품에 다수의 주문이 들어올때 DataBase에서 DeadLock이 발생 -> 원인 분석 -> Mysql DB Lock 때문인가? DataBase Isolation Level을 Read Committed로 변경하였음 -> 해결 안됨 -> 주문 로직에 상품 재고를 JPA 더티체킹으로 Query를 날리는 부분이 있었음 -> 주문 Insert문과 상품 update문이 충돌하며 DeadLock이 발생하는 것이었음 -> 재고 변경 후 save이후에 주문객체를 save함 -> 문제 해결
- ngrinder 서버 분리 (controller, agent)
- 동시성 처리 방법 변경 후 성능 테스트
- JPA Optimistic Lock 활용
- Redis Lock 활용
- 추가 구현