[트러블슈팅]Tomcat 서버는 정상인데 웹사이트 접속이 안 될 때 확인한 것들

웹 서비스를 운영하다 보면 Tomcat 프로세스는 정상적으로 실행 중인데 웹사이트에 접속되지 않는 상황이 발생할 수 있습니다.

브라우저에서 사이트에 접속하면 화면이 계속 로딩되거나 연결이 끊기고, Tomcat을 재시작해도 문제가 해결되지 않는 경우도 있습니다.

이런 상황에서 무작정 서버를 재시작하기보다 요청이 어느 구간까지 정상적으로 전달되고 있는지 순서대로 확인하는 것이 중요합니다.

이번 글에서는 제가 실제로 웹 서비스를 운영하면서 경험했던 장애 사례를 바탕으로 Tomcat 서버는 실행 중이지만 웹사이트에 접속되지 않을 때 확인해야 할 사항을 정리해 보겠습니다.

1. Tomcat 프로세스가 실행 중인지 확인하기

가장 먼저 Tomcat 프로세스가 실제로 실행 중인지 확인합니다.

Linux 서버에서는 다음 명령어를 사용할 수 있습니다.

ps -ef | grep tomcat

Tomcat이 실행 중이라면 Java 프로세스와 함께 catalina.base, catalina.home 등의 실행 옵션을 확인할 수 있습니다.

서버에 여러 개의 Tomcat 인스턴스가 실행되고 있다면 다음 명령어를 사용하는 것도 좋습니다.

ps -ef | grep java

이때 확인해야 할 항목은 다음과 같습니다.

  • Tomcat 프로세스가 존재하는지
  • 프로세스 ID(PID)가 무엇인지
  • 어떤 경로의 Tomcat이 실행되고 있는지
  • 동일한 Tomcat이 중복 실행되고 있지는 않은지

ps -ef | grep tomcat 실행 결과에 grep tomcat 프로세스만 표시된다면 실제 Tomcat 프로세스는 실행되고 있지 않을 가능성이 있습니다.

2. Tomcat 포트가 LISTEN 상태인지 확인하기

Tomcat 프로세스가 실행 중이라고 해서 반드시 정상적으로 요청을 처리하고 있는 것은 아닙니다.

다음으로 Tomcat 포트가 정상적으로 열려 있는지 확인합니다.

ss -lntp

특정 포트만 확인하려면 다음과 같이 사용할 수 있습니다.

ss -lntp | grep 8080

구형 Linux 환경에서는 netstat 명령어를 사용할 수도 있습니다.

netstat -lntp | grep 8080

정상적으로 실행 중이라면 해당 포트가 LISTEN 상태로 표시됩니다.

Tomcat 프로세스는 존재하지만 포트가 열려 있지 않다면 Tomcat 시작 과정에서 오류가 발생했을 가능성이 있으므로 로그를 확인해야 합니다.

3. 서버 내부에서 직접 접속해 보기

포트가 정상적으로 열려 있다면 서버 내부에서 Tomcat으로 직접 요청을 보내봅니다.

curl -v http://127.0.0.1:8080/

서비스의 Context Path가 있다면 실제 서비스 주소를 입력합니다.

curl -v http://127.0.0.1:8080/service/

서버 내부에서는 정상적으로 응답하지만 외부 PC에서는 접속되지 않는다면 Tomcat 자체보다는 다른 구간에 문제가 있을 가능성이 높습니다.

예를 들어 다음과 같은 부분을 확인할 수 있습니다.

  • Linux 방화벽
  • 클라우드 보안 그룹
  • Load Balancer
  • Nginx 또는 Apache
  • WAF(Web Application Firewall)
  • 네트워크 보안장비

반대로 서버 내부의 curl 요청도 응답하지 않는다면 Tomcat 애플리케이션 또는 DB 연결 등의 문제를 확인해야 합니다.

4. Tomcat 로그 확인하기

Tomcat 장애를 확인할 때 로그는 매우 중요한 단서가 됩니다.

일반적으로 다음 경로에서 로그를 확인할 수 있습니다.

$CATALINA_HOME/logs/

실시간으로 로그를 확인하려면 다음 명령어를 사용할 수 있습니다.

tail -f catalina.out

최근 로그만 확인하려면 다음과 같이 사용할 수 있습니다.

tail -1000 catalina.out

특정 오류를 검색할 수도 있습니다.

grep -i "error" catalina.out
grep -i "exception" catalina.out

애플리케이션에서 별도의 로그 파일을 사용하고 있다면 catalina.out뿐만 아니라 실제 서비스 로그도 함께 확인해야 합니다.

제가 경험했던 장애 상황에서는 웹사이트에 접속되지 않았지만 애플리케이션 로그에는 새로운 요청이 전혀 기록되지 않았습니다.

이런 경우 브라우저의 요청이 Tomcat까지 전달되지 않고 있을 가능성을 생각해 볼 수 있습니다.

5. Tomcat 재시작으로 해결되는 문제인지 확인하기

웹사이트에 접속되지 않으면 가장 먼저 Tomcat을 재시작하는 경우가 많습니다.

재시작으로 일시적으로 문제가 해결된다면 다음과 같은 원인을 의심할 수 있습니다.

  • 메모리 부족
  • Full GC 증가
  • Thread Pool 고갈
  • DB Connection Pool 고갈
  • 애플리케이션 Deadlock
  • 외부 API 응답 지연

하지만 Tomcat을 재시작했는데도 동일하게 접속되지 않는다면 Tomcat 외부 구간도 확인해야 합니다.

특히 여러 PC에서 동일하게 접속되지 않고 Tomcat 로그에도 요청이 기록되지 않는다면 네트워크나 보안장비 문제일 가능성이 있습니다.

6. DB Connection Pool 상태 확인하기

Tomcat은 실행 중이지만 웹 요청이 계속 대기 상태에 빠진다면 DB Connection Pool 문제도 확인할 필요가 있습니다.

Spring 애플리케이션에서 HikariCP 등의 Connection Pool을 사용하고 있다면 DB 연결을 모두 사용하여 새로운 요청이 Connection을 얻지 못하고 대기하고 있을 수 있습니다.

이 경우 Thread Dump를 확인하는 방법이 있습니다.

먼저 Tomcat의 PID를 확인합니다.

ps -ef | grep tomcat

이후 jstack 명령어를 이용하여 Thread Dump를 생성합니다.

jstack PID > /tmp/jstack.txt

HikariCP 관련 Thread를 확인합니다.

grep -A5 "Hikari" /tmp/jstack.txt

DB Connection을 기다리는 Thread를 확인할 수도 있습니다.

grep -A5 "getConnection" /tmp/jstack.txt

WAITING 상태의 Thread를 확인하려면 다음 명령어를 사용합니다.

grep "WAITING" /tmp/jstack.txt | head -50

만약 다음과 같은 오류가 발생한다면,

jstack: command not found

현재 서버에 JRE만 설치되어 있거나 JDK의 bin 경로가 PATH 환경변수에 등록되어 있지 않을 가능성이 있습니다.

이 경우 실행 중인 Java 경로를 확인한 후 해당 JDK에 포함된 jstack을 직접 실행할 수 있습니다.

7. Tomcat까지 요청이 도착하는지 확인하기

장애 원인을 찾을 때 중요한 기준 중 하나는 요청이 어느 구간까지 도착하는지 확인하는 것입니다.

일반적인 웹 서비스 요청 흐름은 다음과 같습니다.

  사용자 브라우저
        ↓
       DNS
        ↓
 방화벽 / 보안장비
        ↓
  Load Balancer
        ↓
  Nginx / Apache
        ↓
      Tomcat
        ↓
   Application
        ↓
    Database

이 구조에서 어느 구간에서 요청이 멈추는지 확인하면 장애 범위를 크게 줄일 수 있습니다.

예를 들어 Tomcat Access Log와 애플리케이션 로그에 요청이 전혀 없다면 Tomcat 내부 문제를 계속 조사하는 것은 효율적이지 않을 수 있습니다.

Tomcat 앞단의 Reverse Proxy, Load Balancer, 방화벽 및 보안장비 로그를 확인해야 합니다.

8. 실제 장애 원인은 보안장비의 IP 차단

제가 경험했던 장애도 처음에는 Tomcat 문제라고 생각했습니다.

Tomcat 프로세스는 정상적으로 실행되고 있었지만 브라우저에서 웹사이트에 접속하면 화면이 계속 로딩되었습니다.

Tomcat을 재시작해도 문제는 해결되지 않았습니다.

여러 PC에서 테스트해 보았지만 동일한 증상이 발생했고 애플리케이션 로그에도 새로운 요청이 기록되지 않았습니다.

Tomcat Thread 상태와 DB Connection 문제까지 확인했지만 특별한 이상을 발견하지 못했습니다.

이후 네트워크 및 보안 구간을 확인하는 과정에서 원인을 발견했습니다.

웹 서비스 앞단의 보안장비에서 특정 IP(회사 IP)를 SQL Injection 공격으로 탐지하여 차단하고 있었습니다.

그러하여 회사 내 모든 PC에서 접속이 안되는 것이었습니다. (모든 사용자들이 접속 안되는 줄 알고 식겁했습니다…ㅎ)

해당 IP의 차단을 해제한 후 웹사이트 접속은 즉시 정상화되었습니다.

이 경험을 통해 Tomcat 프로세스가 정상인데 웹사이트에 접속되지 않는 경우 애플리케이션 서버만 확인해서는 장애 원인을 찾기 어려울 수 있다는 점을 알 수 있었습니다.

Tomcat 접속 장애 점검 순서 정리

Tomcat 프로세스는 실행 중이지만 웹사이트에 접속되지 않는다면 저는 다음 순서로 확인하는 것을 추천합니다.

  1. Tomcat 프로세스 확인
  2. Tomcat LISTEN 포트 확인
  3. 서버 내부에서 curl 테스트
  4. Tomcat Access Log 확인
  5. 애플리케이션 로그 확인
  6. DB Connection Pool 및 Thread 상태 확인
  7. Nginx 또는 Load Balancer 확인
  8. 방화벽 및 WAF 등 보안장비 확인

핵심은 Tomcat을 반복해서 재시작하는 것이 아니라 사용자의 요청이 어느 구간까지 정상적으로 전달되고 있는지 확인하는 것입니다.

서버 내부에서 Tomcat이 정상적으로 응답하고 Tomcat 로그에 외부 요청이 기록되지 않는다면 애플리케이션보다 앞단의 네트워크 구간을 먼저 확인하는 것이 장애 원인을 찾는 데 도움이 될 수 있습니다.

마무리

Tomcat 프로세스가 실행 중이라는 사실만으로 웹 서비스가 정상적으로 동작한다고 판단하기는 어렵습니다.

웹 서비스는 DNS, 방화벽, 보안장비, Reverse Proxy, Tomcat, 애플리케이션, 데이터베이스 등 여러 구성 요소를 거쳐 동작하기 때문입니다.

장애가 발생했을 때 각 구간을 순서대로 확인하면 불필요한 서버 재시작을 줄이고 장애 원인을 보다 빠르게 찾을 수 있습니다.

이번 사례처럼 예상하지 못했던 보안장비의 오탐 차단이 원인일 수도 있으므로 Tomcat과 애플리케이션에서 특별한 이상을 발견하지 못했다면 네트워크 및 보안 구간도 함께 확인해 보시기 바랍니다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다