Part.1 에서 싱크를 걸었기 때문에 유저가 많이 몰릴경우 속도가 많이 느려진다.
그래서 Lock 영역에서 막는 것은 Redis로 처리하고 db insert 처리는 thread 로 처리한다.
import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;
import org.redisson.api.RBucket;
import org.redisson.api.RTransaction;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import lombok.RequiredArgsConstructor;
@Service
@RequiredArgsConstructor
public class MemberServiceImpl implements MemberService
{
private final MyRedis myRedis;
private final AsyncService asyncService;
@Override
public boolean temp() {
String lock = "lock_key"; // 해당 키에만 lock을 걸고 싶으면 value를 key로
boolean ret = false;
try {
if (myRedis.tryLock(lock, TimeUnit.SECONDS, 5L, 10L)) {
int num = Integer.parseInt((String) myRedis.getValue("key")));
if(num >= 1000)
{
ret = false;
}
myRedis.setValue("key",++num);
Temp temp = new Temp();
asyncService.asyncInsertTemp(temp);
}
} catch (Exception e) {
e.getStackTrace();
ret = false;
} finally {
if (myRedis.canUnlock(lock)) {
myRedis.unlock(lock);
}
}
return ret;
}
}
public interface AsyncServiceTemp {
public void asyncInsertTemp(Temp temp);
}
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import lombok.RequiredArgsConstructor;
@Service
@RequiredArgsConstructor
@Transactional
public class AsyncServiceImpl implements AsyncService {
private final TempRepository tempRepository;
@Override
public void asyncInsertTemp(Temp temp) {
tempRepository.saveAndFlush(temp);
}
}
Config 추가. Thread 개수는 ec2 spec에 맞춰서 설정. (DB pool 갯수에도 영향이 갑니다)
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurerSupport;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
@Configuration
@EnableAsync
public class AsyncConfig extends AsyncConfigurerSupport {
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(100);
executor.setMaxPoolSize(200);
executor.setQueueCapacity(2000);
executor.setThreadNamePrefix("lesserafim-db-async");
executor.initialize();
return executor;
}
}
'개발 > Spring' 카테고리의 다른 글
Spring boot Data JPA Hikari Master/Slave (Write,Read Only) 사용하기. (0) | 2022.04.06 |
---|---|
Spring boot&React Cookie 설정 SameSite Cookie 변경된 크롬 80 쿠키 정책 (0) | 2022.04.06 |
Spring @RequestParam @RequestBody @ModelAttribute 차이 (0) | 2022.03.20 |
Part.1 Spring boot 갯수 제한 이벤트 구현(Redis 이용) Redisson, Transaction, Sync(lock) 유저가 많이 몰릴때. (0) | 2022.03.19 |
Spring boot NHN Cloud api-alimtalk 2.2 사용하기 (0) | 2022.03.19 |