20개의 스레드를 실행시켰지만 13개의 스레드만 실행된 상태. 그후 위의 NoHttpResponseException에러 발생
스레드의 수가 많아질수록 락을 얻지 못하는 경우가 더 많아질 수 있습니다. 따라서 더 긴 대기 시간이 필요할 수 있습니다.
tryLock() 메소드의 파라미터 중 두 번째 파라미터인 waitTime이 대기 시간을 결정합니다. 락이 얻어지지 않았을 때 대기하는 시간을 늘리면 더 많은 스레드가 락을 얻을 수 있으나, 대기 시간을 너무 길게 늘리면 다른 스레드가 락을 얻을 때까지 오랜 시간이 걸릴 수 있으므로 적절한 값을 찾아야 합니다.
waitTime이 짧아야 하는 경우:
waitTime이 길어야 하는 경우:
waitTime이 현재 5초로 설정되어 있지만 락을 획득하는 스레드의 처리 시간이 길어 5초의 대기시간으로는 충분하지 않아 10초로 바꾸니 정상적으로 20개의 스레드 모두 실행됐지만 근본적인 해결방안은 아닐것 같다는 생각이 듭니다.
지금은 20개의 스레드로 테스트해서 10초면 충분하지만, 100개의 스레드가 동시에 접근했을시에는 또 에러가 발생하게 되어 waitTime을 늘려줘야 하는 상황이 발생하게 됩니다.
waitTime이 끝나게 되면 CustomException을 통해 종료되게 되는데 그렇게 종료되면 해당 스레드가 무한 대기 상태에 빠지게 되어 waitTime이 끝나면 Letucce의 스핀락 형태로 만들어 줘서 계속 락 획득 요청을 하게 만들었습니다. 하지만 스핀락 형태로 구현하다보니 로직의 실행시간이 오래 걸리게 되어 다시한번 다른 방법을 고민하게 되었습니다. → 더 알아보니 RedissonClient
의 getLock메서드 내부에서 스핀락 알고리즘을 이미 구현하고 있었습니다. 스핀락에 스핀락을 걸고있는 이상한 상황이었습니다
10초의 대기시간(redisson timewait)이 지난 스레드들은 예외 처리로 인해 종료되게 되고, 해당 스레드들은 서버에서 응답을 클라이언트로 못보내는 현상이 발견되었습니다. → 10초 지난 스레드들은 예외처리하게 되는데 이때 throw new CustomException(ErrorType.FAILED_TO_ACQUIRE_LOCK)
의 에러 코드가 100번으로 잘못 작성돼 있음을 확인했습니다. → 100번을 응답으로 보내게 되면 100번 응답의 의미인 Continue에따라 계속 데이터를 대기하게 되며, 정해진 시간 뒤 서버와의 연결이 끊깁니다.
그동안 클라이언트가 응답을 받지 못했던 이유가 에러 코드 100번을 보냈기 때문이었습니다. Trace를 확인해봐도 다른 RuntimeException과 똑같이 에러를 반환하기 때문에 이상한점을 못찾고 오히려 이상한 점이 없길래 코드문제라는 생각이 들어 발견할 수 있었습니다.