문제 상황

프로젝트 환경을 새로 설정하면서 원본 서버의 설정을 대상 서버로 복제하는 작업을 진행했습니다. 원본 서버는 Tomcat에서 SSL(443번 포트)이 활성화된 상태로 잘 동작하고 있었기 때문에, 대상 서버에서도 동일한 설정을 적용했습니다.

그러나, Tomcat을 시작하자마자 아래와 같은 에러가 발생했습니다

 

Caused by: java.net.BindException: 주소가 이미 사용 중입니다
	at sun.nio.ch.Net.bind0(Native Method)
	...

Tomcat의 로그를 확인해보니, 443번 포트가 이미 사용 중이라는 내용이었습니다. 하지만 원본 서버에서는 이런 문제가 없었기 때문에 한참 헤매게 되었습니다.

 

원인 분석

대상 서버를 자세히 살펴보니, **Apache HTTP 서버(httpd)**가 설치되어 있었습니다.

Apache HTTP 서버는 기본적으로 80번(HTTP) 포트443번(HTTPS) 포트를 사용합니다. Tomcat에서도 443번 포트를 사용하려고 설정되어 있었기 때문에, 두 서버가 충돌하면서 포트 사용 문제가 발생한 것입니다.

결국 대상 서버에 HTTP 서버가 설치된 사실을 몰랐던 것이 문제의 원인이었습니다.

 

해결 방법

이 문제를 해결하기 위해 아래 단계를 거쳤습니다:

 

포트 충돌 확인 먼저, 대상 서버에서 443번 포트를 누가 사용 중인지 확인했습니다

sudo lsof -i :443


COMMAND   PID    USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
httpd    1234    root   10u  IPv4  12345      0t0  TCP *:https (LISTEN)

 

 

  • 해결 방안 선택
    • Apache HTTP 서버를 비활성화 또는 제거
    • Tomcat의 SSL 포트를 변경
    • Apache를 리버스 프록시로 설정하여 Tomcat과 연동
    이번 환경에서는 HTTP 서버가 불필요했기 때문에, Apache HTTP 서버를 중지하는 방법을 선택했습니다.

 

  • Apache HTTP 서버 중지
sudo systemctl stop httpd
sudo systemctl disable httpd

 

교훈

  1. 환경 확인의 중요성
    새로운 서버 환경에서는 **기본적으로 설치된 서비스(예: HTTP 서버)**가 무엇인지 먼저 확인해야 합니다. 특히, 잘 알려진 포트(80, 443 등)는 다른 서비스가 사용하고 있을 가능성이 높습니다.
  2. 효율적인 디버깅 방법
    포트 충돌 문제를 해결하기 위해서는 다음 명령어를 적극적으로 활용하면 좋습니다:
    • netstat -tuln → 현재 사용 중인 포트 확인
    • lsof -i :<port> → 특정 포트를 점유하고 있는 프로세스 확인
  3. 원본 서버와 대상 서버의 차이점 확인
    원본 서버에서 아무 문제가 없더라도, 대상 서버의 환경이 다를 수 있다는 점을 항상 염두에 두어야 합니다.

 

마무리

이번 경험은 단순한 포트 충돌이었지만, 대상 서버 환경을 제대로 이해하지 않고 설정을 복제하려다 발생한 문제였습니다. 다음부터는 환경 구성 전에 기본 설정을 꼼꼼히 확인하고, 효율적인 디버깅 과정을 통해 시간을 절약할 수 있을 것 같습니다.

비슷한 문제를 겪고 계신 분들께 도움이 되었길 바랍니다! 

 

문제 상황

최근 Tomcat에서 애플리케이션을 실행하던 중, JVM 메모리 관련 에러로 인해 애플리케이션이 정상적으로 작동하지 않는 문제가 발생했습니다. 아래는 당시 발생한 에러 메시지입니다:

 

NOTE: Picked up JDK_JAVA_OPTIONS:  --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED
OpenJDK 64-Bit Server VM warning: INFO: os::commit_memory(0x0000000600000000, 8589934592, 0) failed; error='Not enough space' (errno=12)
#
# There is insufficient memory for the Java Runtime Environment to continue.
# Native memory allocation (mmap) failed to map 8589934592 bytes for committing reserved memory.
# An error report file with more information is saved as:
# /home/project/apache-tomcat-9.0.54/bin/hs_err_pid23479.log

 

이 메시지는 다음을 나타냅니다:

  • JVM이 8GB의 메모리를 요청했으나, 서버의 물리 메모리가 부족하여 요청이 거부되었습니다.
  • 물리 메모리(7.7GB)가 JVM이 요청한 메모리보다 적었기 때문에, 시스템이 더 이상 JVM의 메모리 요청을 처리할 수 없었습니다.

원인 분석

  1. JVM 메모리 설정 과도
    Tomcat에서 JVM 힙 메모리 설정이 기본값보다 과도하게 높게 설정되어 있었습니다:
    • 초기 힙 메모리(-Xms): 8GB
    • 최대 힙 메모리(-Xmx): 8GB
  2. 물리 메모리 초과
    서버의 물리 메모리(7.7GB)가 JVM 메모리 설정을 감당할 수 없었기 때문에, JVM이 실행 중 메모리 할당 에러를 발생시켰습니다.

문제의 기존 설정

Tomcat의 setenv.sh 파일에 다음과 같은 JVM 메모리 설정이 있었습니다

export CATALINA_OPTS="$CATALINA_OPTS -Xms8192m"
export CATALINA_OPTS="$CATALINA_OPTS -Xmx8192m"
export CATALINA_OPTS="$CATALINA_OPTS -XX:NewSize=4096m"
export CATALINA_OPTS="$CATALINA_OPTS -XX:MaxNewSize=4096m"

 

해결 과정

이 문제를 해결하기 위해 다음과 같이 setenv.sh 파일을 수정했습니다:

수정된 setenv.sh 내용

# 기존 JVM 옵션 (주석 처리)
# export CATALINA_OPTS="$CATALINA_OPTS -Xms8192m"
# export CATALINA_OPTS="$CATALINA_OPTS -Xmx8192m"
# export CATALINA_OPTS="$CATALINA_OPTS -XX:NewSize=4096m"
# export CATALINA_OPTS="$CATALINA_OPTS -XX:MaxNewSize=4096m"

# 새로운 JVM 메모리 옵션 설정
export CATALINA_OPTS="$CATALINA_OPTS -Xms2g"
export CATALINA_OPTS="$CATALINA_OPTS -Xmx4g"
export CATALINA_OPTS="$CATALINA_OPTS -XX:NewSize=512m"
export CATALINA_OPTS="$CATALINA_OPTS -XX:MaxNewSize=1024m"

변경된 설정

  • 초기 힙 메모리(-Xms): 8GB → 2GB
  • 최대 힙 메모리(-Xmx): 8GB → 4GB
  • Young Generation 초기 크기(-XX:NewSize): 4GB → 512MB
  • Young Generation 최대 크기(-XX:MaxNewSize): 4GB → 1GB

 

설정 확인

JVM 메모리 옵션 확인

Tomcat이 올바르게 설정되었는지 확인하려면 아래 명령어를 사용하세요

jps -lvm

#결과 예시
15190 org.apache.catalina.startup.Bootstrap start -Xms2g -Xmx4g -XX:NewSize=512m -XX:MaxNewSize=1024m

 

결론

이 과정을 통해 Tomcat의 JVM 메모리 설정을 서버 환경에 맞게 조정하였습니다. 변경 후에는 더 이상 메모리 부족 에러가 발생하지 않았으며, 서버 리소스 사용이 안정화되었습니다.

교훈

JVM 메모리 옵션(-Xms, -Xmx)을 설정할 때는:

  1. 서버의 물리 메모리와 애플리케이션의 요구사항을 고려합니다.
  2. 필요 이상으로 높은 설정은 시스템에 오히려 부하를 줄 수 있습니다.
  3. GC 로깅 등을 통해 애플리케이션의 실제 메모리 사용량을 파악하고 설정을 최적화하세요.

'Trouble Shooting > java' 카테고리의 다른 글

Tomcat SSL 설정 중 포트 충돌 문제  (0) 2024.11.26

+ Recent posts