Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] 동기 부하테스트 코드 백업 #33

Merged
merged 3 commits into from
Sep 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/main/java/com/softeer/podoarrival/config/AsyncConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ public class AsyncConfig {
@Bean(name = "arrivalExecutor")
public Executor arrivalExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(20); // 초기 스레드 풀 크기
executor.setMaxPoolSize(100); // 최대 스레드 풀 크기
executor.setCorePoolSize(50); // 초기 스레드 풀 크기
executor.setMaxPoolSize(300); // 최대 스레드 풀 크기
executor.setQueueCapacity(300000); // 대기열 크기
executor.setThreadNamePrefix("Async-");
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); // reject시 처리정책 - 시간이 걸려도 처리
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@ public class ArrivalEventSyncController {
// @PostMapping("/application")
@Operation(summary = "선착순 응모용 Api")
public CommonResponse<ArrivalApplicationResponseDto> arrivalEventApplication(@Auth AuthInfo authInfo) {
return new CommonResponse<>(arrivalEventSyncService.applyEvent(authInfo));
return new CommonResponse<>(arrivalEventSyncService.applyEventWithRedis(authInfo));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,8 @@
import com.softeer.podoarrival.event.model.entity.ArrivalUser;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.Optional;

public interface ArrivalUserRepository extends JpaRepository<ArrivalUser, Long> {
Optional<ArrivalUser> findByPhoneNum(String phoneNum);
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.softeer.podoarrival.event.service;

import com.softeer.podoarrival.event.exception.EventClosedException;
import com.softeer.podoarrival.event.exception.ExistingUserException;
import com.softeer.podoarrival.event.model.dto.ArrivalApplicationResponseDto;
import com.softeer.podoarrival.event.model.entity.ArrivalUser;
Expand All @@ -14,8 +15,14 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

@Slf4j
@Service
Expand All @@ -29,9 +36,14 @@ public class ArrivalEventSyncService {
private boolean CHECK = false;

private final String ARRIVAL_SET = "arrivalset";
private static int MAX_ARRIVAL = 30000; // default
private static int MAX_ARRIVAL = 40000; // default
private static int count = 1;

public ArrivalApplicationResponseDto applyEvent(AuthInfo authInfo) {
private static AtomicInteger countAtomic = new AtomicInteger(1);
private static ConcurrentHashMap<String, Integer> hashMap = new ConcurrentHashMap<>();


public ArrivalApplicationResponseDto applyEventWithRedis(AuthInfo authInfo) {
String redisKey = LocalDate.now() + ARRIVAL_SET;

if(CHECK){
Expand Down Expand Up @@ -61,11 +73,71 @@ public ArrivalApplicationResponseDto applyEvent(AuthInfo authInfo) {
.build()
);
log.info("[당첨] 유저 전화번호 = {}, 등수 = {}", authInfo.getPhoneNum(), grade);
try {
Thread.sleep(15);
} catch (InterruptedException e) {
throw new RuntimeException(e);
// try {
// Thread.sleep(15);
// } catch (InterruptedException e) {
// throw new RuntimeException(e);
// }
return new ArrivalApplicationResponseDto(true, authInfo.getName(), authInfo.getPhoneNum(), grade);
} else {
CHECK = true;
return new ArrivalApplicationResponseDto(false, authInfo.getName(), authInfo.getPhoneNum(), grade);
}
}

@Transactional
public synchronized ArrivalApplicationResponseDto applyEventWithSynchronized(AuthInfo authInfo) {

if(CHECK){
return new ArrivalApplicationResponseDto(false, authInfo.getName(), authInfo.getPhoneNum(), -1);
}

Optional<ArrivalUser> findUser = arrivalUserRepository.findByPhoneNum(authInfo.getPhoneNum());

int grade = count++;
if(grade<=MAX_ARRIVAL) {
if(findUser.isEmpty()) {
arrivalUserRepository.save(
ArrivalUser.builder()
.name(authInfo.getName())
.phoneNum(authInfo.getPhoneNum())
.role(Role.ROLE_USER)
.arrivalRank(grade)
.build()
);
return new ArrivalApplicationResponseDto(true, authInfo.getName(), authInfo.getPhoneNum(), grade);
} else {
throw new ExistingUserException("이미 응모한 전화번호입니다.");
}
} else {
CHECK = true;
return new ArrivalApplicationResponseDto(false, authInfo.getName(), authInfo.getPhoneNum(), grade);
}
}

@Transactional
public ArrivalApplicationResponseDto applyEventWithJava(AuthInfo authInfo) {
if(CHECK){
return new ArrivalApplicationResponseDto(false, authInfo.getName(), authInfo.getPhoneNum(), -1);
}

//첫번째 응답
if(hashMap.containsKey(authInfo.getPhoneNum())){
throw new ExistingUserException("이미 응모한 전화번호입니다.");
}

int grade = countAtomic.getAndIncrement();
// 선착순 순위에 들었다면
if(grade <= MAX_ARRIVAL){
arrivalUserRepository.save(
ArrivalUser.builder()
.name(authInfo.getName())
.phoneNum(authInfo.getPhoneNum())
.role(Role.ROLE_USER)
.arrivalRank(grade)
.build()
);
log.info("전화번호 = {}", authInfo.getPhoneNum());
return new ArrivalApplicationResponseDto(true, authInfo.getName(), authInfo.getPhoneNum(), grade);
} else {
CHECK = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

import java.text.ParseException;
import java.util.Base64;
import java.util.Date;

@Component
public class TokenProvider {
Expand All @@ -38,7 +39,14 @@ public JWTClaimsSet validateTokenAndGetClaimsSet(String token) {
throw new InvalidTokenException("Token signature is invalid");
}

return signedJWT.getJWTClaimsSet();
JWTClaimsSet claimsSet = signedJWT.getJWTClaimsSet();
// expirationTime 검증
Date expirationTime = claimsSet.getExpirationTime();
if (expirationTime == null || expirationTime.before(new Date())) {
throw new InvalidTokenException("이미 만료된 토큰입니다.");
}

return claimsSet;

} catch (JOSEException | ParseException e) {
throw new InvalidTokenException("JWE Token Decoding Error - 토큰 검증과정에서 오류 발생");
Expand Down
Loading