유저가 로그인 상태이던, 비로그인 상태이던 모두 게시글 리스트를 볼 수 있도록 API를 수정했다.
처음에는 로그인의 경우와 비로그인의 경우 API를 각자 만드려고 했는데 코드 중복도 심할 것 같아 API에 조건을 추가해서 로그인/비로그인 상태를 체크했다.
API에서 로그인했는지의 여부는 3가지 경우로 확인할 수 있다. (참고)
Principal principal@AuthenticationPrincipal Member memberController 메서드 내부에서 로그인했는지를 확인해야 하기 때문에 첫번째 방법을 사용해서 로그인 여부를 체크해주었다.
비로그한 사용자는 SecurityContextHolder.getContext().getAuthentication().getPrincipal()의 값이 null일 줄 알았는데 디버깅해서 출력해보니 anonymousUser이었다.
찾아보니 비로그인한 사용자는 Authentication이 null 이 아니고 문자열의 "anonymousUser" 이 저장되어 있는 principal 과 ROLE_ANONYMOUS 권한 정보를 가지고 있는 객체라고 한다.
Object principalObj = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
if(principalObj == "anonymousUser"){
// 비로그인 상태인 경우
}
위와 같이 코드를 작성했고, 잘 구현되었다.
SecurityContextHolder.getContext().getAuthentication().getPrincipal() 대신에 @AuthenticationPrincipal에 @Nullable를 붙이는 게 더 깔끔할 것 같아서 수정했다.
public ResponseEntity getPrfPosts(@Nullable @AuthenticationPrincipal Member member,
@Positive @RequestParam(defaultValue = "1") int page,
@Positive @RequestParam(defaultValue = "10") int size,
@Positive @RequestParam(defaultValue = "1") int sorting){
if(member == null){ // 비로그인 시에
List<PrfPostDto.Response> result = customMapper.prfPostsToResponseDtos(allPrfPost);
return new ResponseEntity<>(new MultiResponseDto<PrfPostDto.Response>(result, pageInfo), HttpStatus.OK);
}
}

Principal principal을 두어, 로그인한 사용자의 정보를 가져온다.@AuthenticationPrincipal 애너테이션을 통해서 로그인한 사용자의 다양한 정보를 가져오게끔 구현한다.디버깅을 하는데 디버깅 속도도 느려지고 계속 Collecting data라는 문구가 뜨면서 데이터가 노출되지 않았다.
1000만건 되는 데이터들을 계속 불러와서 그런지 디버깅이 느려지고 제대로 되지 않았다.
우선 시도한 방법은 다음과 같다.
Enable alternative views for Collections classes and Enable toString() object view options을 disable하게 설정해뒀다.
Method breakpoints를 지우고, Setting을 수정해주니까 디버깅 속도가 확실히 나아졌다.
[참고]
jetbrains
jetbrains
stackoverflow - IntelliJ IDEA stucks at "collecting data" while debug
HikariPool-1 - Thread starvation or clock leap detected (housekeeper delta=1m6s443ms).
DB에 데이터를 1000만건을 넣은 상태에서 잘 돌아가던 코드를 돌리니 다음과 같은 에러가 떴다.
여러 블로그나 글들을 참고해봤는데 원인은 다음과 같다.
https://stackoverflow.com/questions/38703876/log-warning-thread-starvation-or-clock-leap-detected-housekeeper-delta-springh
https://github.com/brettwooldridge/HikariCP/issues/679
Mac 사용 시, 앱을 로컬로 실행하고 컴퓨터가 절전 모드로 전환되었기 때문에
https://sudo-minz.tistory.com/85
과도한 GC(가비지 컬렉션)으로 인해 가비지 컬렉션이 하우스키핑 스레드의 실행보다 더 오랜 시간 동안 실행되고 일부 메모리를 확보하려고 시도하는 경우
가상 컨테이너(VMWare, AWS 등)에서 실행 중일 수 있습니다. 가상 컨테이너는 어떤 이유로 시간 흐름의 환상을 유지하는 데 특히 열악합니다.
housekeeper 스레드에서 다른 일이 발생하기 때문에, housekeeper 스레드가 blocking 될 수 있다.
모든 CPU가 고정된 상태에서 서버가 너무 바빠서 스레드 고갈(Thread starvation)이 발생하여 housekeeper 스레드가 housekeeping 기간 동안 실행되지 않습니다.
응용 프로그램을 디버깅하고 한 중단점에서 두 번 이상의 관리 기간(60초) 이상 대기하는 경우에도 발생합니다.
여러 원인들이 존재하다보니, 하나하나 시도해보지 못했는데 갑자기 어느 순간 에러가 사라졌다.(도대체 왜??)
Mac 절전(잠자기) 모드도 영향을 미치는 것 같지만, 데이터 1000만건으로 인해 데이터베이스 쿼리가 느리거나 시스템 리소스(connection pool이나 CPU)가 부족해서 발생한 것 같다.