21장. 실전 JBoss EAP 운영환경 구성 가이드
지금까지는 간단히 JBoss EAP 6 인스턴스를 구동하고 설정을 변경하는 방법들을 살펴봤다. 하지만 실제 운영환경에 구축할 때는 디렉터리 구조를 결정하여 설치하여야 하고, 로그 디렉터리의 분리, 백그라운드로 실행 등 JBoss 인스턴스들을 관리하기 위한 다양한 스크립트가 필요하다. 리눅스 운영체제 등의 변경도 필요하다.
이번 장에서는 JBoss EAP 6를 실제 운영환경에 적용하기 위한 절차를 설명한다. 이 책을 읽고 나서 실제 운영 환경에 JBoss를 바로 적용할 수 있도록 가이드를 제공한다.
1.설치 환경
먼저 JBoss 인스턴스를 어떻게 구성할 것인지를 결정하여야 한다. 장애에 대비하기 위하여 같은 서비스를 제공하는 여러 개의 인스턴스를 클러스터로 구성한다. 이때 인스턴스들은 서로 다른 머신에 배치하여 하드웨어 장애에도 대비할 수 있도록 구성하는 것이 좋다.
Java의 힙 메모리를 많이 사용하면 JVM이 멈추는 Full GC 시간이 길어지기 때문에 1G2G정도의 힙 메모리를 사용하여야 한다. 12G 정도의 메모리만 사용하면 하드웨어의 메모리가 남기 때문에 한 머신에 여러 인스턴스를 구성하여야 한다.
이번 장에서는 다음 그림과 같이 3대의 머신에 1대는 JBoss EWS 웹 서버를 설치하고, 2대에는 JBoss EAP 6를 2개 스탠드얼론 모드의 인스턴스를 설치하여 클러스터를 구성하는 예제를 살펴보자.
예를 들어 각각의 머신은 다음과 같은 IP를 사용한다고 가정하자.
| 용도 | HOSTNAME | IP |
|---|---|---|
| 웹 서버 | WEB01 | 192.168.0.201 |
| WAS 서버 | WAS01 | 192.168.0.101 |
| WAS 서버 | WAS02 | 192.168.0.102 |
표 1. 머신 구성의 예
아래 그림과 같이 웹 서버와 JBoss EAP 6 서버 인스턴스를 구성한다고 가정하자.

디렉터리 구조
주요 설치 디렉터리
제품이 설치되는 디렉터리와 서비스에 사용할 인스턴스 들이 있는 디렉터리를 분리하는 것이 좋다. 또, 로그 파일이 별도 의 디렉터리에 저장되도록 설정하여 디스크가 꽉 차더라도 서비스에는 영향을 미치지 않도록 설정한다. 물론 로그를 남길 디렉터리는 OS에서 다른 파티션을 사용하도록 설정하여야 한다. 또 별도의 외부 애플리케이션 배포 디렉터리를 설정하면 한 머신에 한 번만 애플리케이션을 배포하면 된다.
| 구분 | 디렉터리명 | 설명 |
|---|---|---|
| JBoss EAP 6 제품설치 디렉터리 | /svc/test/was/jboss-eap-6.2 | JBoss EAP 6를 설치할 디렉터리이다. |
| JBoss인스턴스 디렉터리 | /svc/test/was/domains | 서비스에 사용할 JBoss 인스턴스들을 구성할 디렉터리이다. |
| 로그 디렉터리 | /logs/was/ | 인스턴스의 로그 파일들을 저장할 디렉터리이다. |
| 애플리케이션 디렉터리 | /svc/test/was/domains/applications | 애플리케이션 배포 디렉터리이다. |
| JBoss EWS 2 제품설치 디렉터리 | /svc/test/web/jboss-ews-2.0 | JBoss EWS 2를 설치할 디렉터리이다. |
표 2. 설치 디렉터리
인스턴스 디렉터리 구성
JBoss EAP 6를 설치한 디렉터리의 파일들은 수정하지 않고, 별도의 인스턴스 디렉터리를 설정하여 서비스한다.
/svc/test/was/domains 이라는 디렉터리 하위에 인스턴스 들을 구성한다. domains 하위에 서버 인스턴스 이름으로 디렉터리를 만든다. 인스턴스의 이름은 다음 그림과 같이 서버의 이름 + 머신번호 + 인스턴스 번호와 같은 규칙을 사용하는 것이 좋다.
실제 서버의 이름은 서비스를 나타내는 고유명칭으로 변경하여 사용하면 된다. 머신 번호는 JBoss에 사용할 머신에 1번부터 차례대로 붙인 번호를 사용하고, 인스턴스 번호는 같은 머신 내의 인스턴스 개수를 1번부터 번호를 붙인다.
이렇게 인스턴스 이름을 지정하면 모든 인스턴스가 고유한 이름을 갖게 된다. 이 고유한 인스턴스 이름은 클러스터링에서 세션ID, 로그 파일의 이름, nohup 로그 파일의 이름 등에 사용하게 된다. 장애 상황이나 로그 파일를 확인하는 등 어떤 상황에서도 서버 이름만 보면 어떤 머신의 어떤 인스턴스의 것인지 금방 구분할 수 있게 된다.

또, 포트 오프셋 번호는 ‘인스턴스의 번호 * 100’을 사용하면, 포트를 구분하기 쉽다. 기본 포트셋 + 포트오프셋으로 사용하는 포트가 지정되는데, 사용하는 대부분의 포트 번호가 100번대가 0이기 때문에 해당 인스턴스가 사용하는 번호를 기억하기 쉽다.
예를 들어 인스턴스 이름이 ‘frontSvr24’이라면, 2번째 JBoss 머신의 4번째 인스턴스를 의미하며, 이 인스턴스가 사용하는 HTTP 포트는 8480(8080 + 400) 포트를 사용하고, AJP 포트는 8409(8009 + 400) 포트를 사용한다.
예제에서는 다음과 같이 WAS 머신 2대에 각각 2개의 인스턴스를 구성한다.
| 머신명 | 디렉터리명 | 포트 오프셋 | HTTP포트 | AJP포트 |
|---|---|---|---|---|
| WAS01 (192.168.0.101) | /svc/test/was/domains/server11 | 100 | 8180 | 8109 |
| /svc/test/was/domains/server12 | 200 | 8280 | 8209 | WAS02 (192.168.0.102) |
| /svc/test/was/domains/server21 | 100 | 8180 | 8109 | /svc/test/was/domains/server22 |
표 3. 머신 별 인스턴스 구성
JBoss EAP 6운영 스크립트
JBoss EAP 6가 설치된 디렉터리가 아닌 다른 디렉터리에서 JBoss 인스턴스를 실행하려면 몇 가지 옵션을 지정해야 한다. 가장 중요한 옵션은 ‘-Djboss.server.base.dir’로 서버 인스턴스의 디렉터리를 지정하는 데 사용된다. 이 외에도 여러 가지 옵션들을 변경하여 위치를 변경하여야 한다.
JBoss 운영 환경을 구축하기 위해서는 많은 작업이 필요하다. JBoss를 시작할 때도 백그라운드 프로세스로 실행하여야 하며, nohup 로그를 남겨두어야 스레드 덤프를 받을 때 파일에 남게 된다. 백그라운드로 실행 중인 JBoss를 종료하는 방법도 필요하다.
운영환경에 사용할 수 있도록 JBoss EAP 6 스크립트를 github 에 올려두었다. 이 파일을 다운로드받아 사용하면 된다. 스탠드얼론 모드용 스크립트와 도메인 모드용 스크립트를 모두 제공하고 있다.
- JBoss EAP 6 스크립트 다운로드
https://github.com/nameislocus/jboss-eap-6-scripts
$ git clone https://github.com/nameislocus/jboss-eap-6-scripts
git가 설치되어 있지 않으면, 다음 명령으로 git를 설치한다.
$ sudo yum install git
github에 있는 주요 스크립트 파일은 아래 표와 같다. 인스턴스를 시작, 종료, kill, 로그 tail, 프로세스 확인, 스레드 덤프 등 JBoss 인스턴스를 운영하는 데 필요한 대부분의 스크립트를 제공하고 있다.
이 스크립트파일들은 모두 환경설정 파일인 env.sh 파일을 참조하여 실행된다. 따라서, 위에서 설명한 JBoss 설치 디렉터리, 인스턴스 구성 디렉터리, 로그 디렉터리 등의 설정은 모두 env.sh 파일의 내용만 수정하면 된다.
| 스크립트 파일 | 설명 |
|---|---|
| env.sh | JBoss 운영환경 주요 환경 설정 스크립트 |
| start.sh | JBoss Standalone 인스턴스 실행 스크립트 |
| shutdown.sh | JBoss Standalone 인스턴스 정상 종료 스크립트 |
| kill.sh | JBoss 강제 종료 스크립트 |
| nohup.sh | nohup 로그의 tail 보기 스크립트 |
| tail.sh | JBoss server.log 파일 tail 보기 스크립트 |
| status.sh | JBoss 인스턴스가 실행중인지 체크하는 스크립트 |
| jboss-cli.sh | JBoss CLI 모드로 접속하는 스크립트 |
| jconsole.sh | JConsole로 접속하여 JMX MBean 정보를 확인하기 위한 스크립트(GUI 환경 필요) |
| add-user.sh | 사용자를 추가하기 위한 스크립트 |
| dump.sh | 인스턴스 장애시 Java 프로세스의 스레드 덤프를 받기 위한 스크립트 |
| env.properties | 자바 시스템 프로퍼티를 설정하는 파일이다. 인코딩 설정이 정의되어 있다. |
표 4. JBoss EAP 6 운영 스크립트
-
env.sh 파일
env.sh는 JBoss EAP 6환경설정을 위한 파일이다. 각 인스턴스의 모든 설정은 이 파일에서 하면 된다. 4개의 JBoss 인스턴스마다 각각의 인스턴스의 이름, 디렉터리의 이름, 포트 오프셋 등을 설정하면 된다. 또 이 파일에는 JVM의 메모리 옵션, GC 옵션, OufOfMemory 오류가 발생할 때 Heapdump를 출력하는 옵션 등이 설정되어 있다.
스탠드얼론 인스턴스가 사용할 프로파일을 변경하려면, CONFIG_FILE=standalone-full-ha.xml 과같이 프로파일 파일명을 지정하면 된다.
#!/bin/sh
DATE=`date +%Y%m%d%H%M%S`
##### JBOSS Directory Setup #####
export JBOSS_HOME=/svc/test/was/jboss-eap-6.2
export DOMAIN_BASE=/svc/test/was/domains
export SERVER_NAME=server11
export JBOSS_LOG_DIR=/logs/was/server11
if [ e$JBOSS_LOG_DIR = "e" ]
then
export JBOSS_LOG_DIR="$JBOSS_HOME/log"
fi
if [ e$JBOSS_LOG_DIR != "e" ]
then
export JBOSS_LOG_DIR="$JBOSS_LOG_DIR"
fi
##### Configration File #####
export CONFIG_FILE=standalone-ha.xml
export EXTERNAL_DEPLOYMENT=/svc/test/was/domains/applications
export HOST_NAME=master
export NODE_NAME=$SERVER_NAME
export PORT_OFFSET=100
export JBOSS_USER=jboss
##### Bind Address #####
export BIND_ADDR=192.168.0.101
export MULTICAST_ADDR=230.1.1.1
export JMS_MULTICAST_ADDR=231.7.1.1
export MODCLUSTER_MULTICAST_ADDR=224.1.1.105
export MGMT_ADDR=192.168.0.101
export CONTROLLER_IP=$MGMT_ADDR
let CONTROLLER_PORT=9999+$PORT_OFFSET
export CONTROLLER_PORT
export LAUNCH_JBOSS_IN_BACKGROUND=true
##### JBoss System module and User module directory #####
export JBOSS_MODULEPATH=$JBOSS_HOME/modules
# JVM Options : Server
export JAVA_OPTS="-server $AGENT_OPTS $JAVA_OPTS"
# JVM Options : Memory – 자바 힙 메모리 옵션을 설정한다.
export JAVA_OPTS=" $JAVA_OPTS *-Xms1024m -Xmx1024m -XX:MaxPermSize=256m*"
export JAVA_OPTS=" $JAVA_OPTS -XX:+PrintGCTimeStamps "
export JAVA_OPTS=" $JAVA_OPTS -XX:+PrintGCDetails "
export JAVA_OPTS=" $JAVA_OPTS -Xloggc:$JBOSS_LOG_DIR/gclog/gc_$DATE.log "
export JAVA_OPTS=" $JAVA_OPTS -XX:+UseParallelGC "
#export JAVA_OPTS=" $JAVA_OPTS -XX:+UseConcMarkSweepGC "
export JAVA_OPTS=" $JAVA_OPTS -XX:+ExplicitGCInvokesConcurrent "
export JAVA_OPTS=" $JAVA_OPTS -XX:-HeapDumpOnOutOfMemoryError "
export JAVA_OPTS=" $JAVA_OPTS -XX:HeapDumpPath=$JBOSS_LOG_DIR/heapdump "
# Linux Large Page Setting
#export JAVA_OPTS=" $JAVA_OPTS -XX:+UseLargePages "
#export JAVA_OPTS=" $JAVA_OPTS -verbose:gc"
export JAVA_OPTS=" $JAVA_OPTS -Djava.net.preferIPv4Stack=true"
export JAVA_OPTS=" $JAVA_OPTS -Dorg.jboss.resolver.warning=true"
export JAVA_OPTS=" $JAVA_OPTS -Dsun.rmi.dgc.client.gcInterval=3600000 "
export JAVA_OPTS=" $JAVA_OPTS -Dsun.rmi.dgc.server.gcInterval=3600000"
export JAVA_OPTS=" $JAVA_OPTS -Djboss.modules.system.pkgs=org.jboss.byteman,com.khan"
export JAVA_OPTS=" $JAVA_OPTS -Djava.awt.headless=true"
export JAVA_OPTS=" $JAVA_OPTS -Djboss.server.base.dir=$DOMAIN_BASE/$SERVER_NAME"
export JAVA_OPTS=" $JAVA_OPTS -Djboss.server.log.dir=$JBOSS_LOG_DIR"
export JAVA_OPTS=" $JAVA_OPTS -Djboss.external.deployments=$EXTERNAL_DEPLOYMENT"
export JAVA_OPTS=" $JAVA_OPTS -Djboss.socket.binding.port-offset=$PORT_OFFSET"
export JAVA_OPTS=" $JAVA_OPTS -Djboss.node.name=$NODE_NAME"
export JAVA_OPTS=" $JAVA_OPTS -Djboss.bind.address.management=$MGMT_ADDR"
export JAVA_OPTS=" $JAVA_OPTS -Djboss.bind.address=$BIND_ADDR"
#export JAVA_OPTS=" $JAVA_OPTS -Djboss.default.jgroups.stack=tcp"
export JAVA_OPTS=" $JAVA_OPTS -Djboss.default.multicast.address=$MULTICAST_ADDR"
export JAVA_OPTS=" $JAVA_OPTS -Djboss.messaging.group.address=$JMS_MULTICAST_ADDR"
export JAVA_OPTS=" $JAVA_OPTS -Djboss.modcluster.multicast.address=$MODCLUSTER_MULTICAST_ADDR"
export JAVA_OPTS=" $JAVA_OPTS -Dorg.jboss.as.logging.per-deployment=false "
echo "================================================"
echo "JBOSS_HOME=$JBOSS_HOME"
echo "DOMAIN_BASE=$DOMAIN_BASE"
echo "SERVER_NAME=$SERVER_NAME"
echo "CONFIG_FILE=$CONFIG_FILE"
echo "BIND_ADDR=$BIND_ADDR"
echo "PORT_OFFSET=$PORT_OFFSET"
echo "MULTICAST_ADDR=$MULTICAST_ADDR"
echo "CONTROLLER=$CONTROLLER_IP:$CONTROLLER_PORT"
echo "================================================" -
start.sh 파일
JBoss 인스턴스를 시작하는 스크립트이다. 이 파일에서는 JBoss 인스턴스가 이미 실행되어 있는지 조사하여 다시 실행되지 않도록 하며, env.sh 파일에서 JBOSS_USER로 JBoss 프로세스를 관리하는 사용자로 지정한 사용자만 JBoss 인스턴스를 시작할 수 있도록 한다.
GC 로그를 남길 디렉터리나 로그 디렉터리, Heap dump를 남길 디렉터리가 없으면 생성한다.
JBoss 인스턴스는 nohup 로그를 남기며 백그라운드로 실행된다. 기존의 nohup로그는 현재 실행 시각을 확장자로 하여 백업하고 새로운 nohup 로그 를 남긴다.
#!/bin/sh
DATE=`date +%Y%m%d%H%M%S`
. ./env.sh
PID=`ps -ef | grep java | grep "=$SERVER_NAME " | awk '\{print $2}'`
echo $PID
if [ e$PID != "e" ]
then
echo "JBoss SERVER - $SERVER_NAME is already RUNNING..."
exit;
fi
UNAME=`id -u -n`
if [ e$UNAME != "e$JBOSS_USER" ]
then
echo "Use $JBOSS_USER account to start JBoss SERVER - $SERVER_NAME..."
exit;
fi
echo $JAVA_OPTS
if [ ! -d "$JBOSS_LOG_DIR/nohup" ];
then
mkdir -p $JBOSS_LOG_DIR/nohup
fi
if [ ! -d "$JBOSS_LOG_DIR/gclog" ];
then
mkdir -p $JBOSS_LOG_DIR/gclog
fi
if [ ! -d "$JBOSS_LOG_DIR/heapdump" ];
then
mkdir -p $JBOSS_LOG_DIR/heapdump
fi
mv $JBOSS_LOG_DIR/nohup/$SERVER_NAME.out $JBOSS_LOG_DIR/nohup/$SERVER_NAME.out.$DATE
nohup $JBOSS_HOME/bin/standalone.sh -DSERVER=$SERVER_NAME -P=$DOMAIN_BASE/$SERVER_NAME/env.properties -c $CONFIG_FILE >> $JBOSS_LOG_DIR/nohup/$SERVER_NAME.out 2>&1 &
if [ e$1 = "enotail" ]
then
echo "Starting... $SERVER_NAME"
exit;
fi
#tail -f log/server.log
tail -f $JBOSS_LOG_DIR/nohup/$SERVER_NAME.out -
shutdown.sh
shutdown CLI 명령을 사용하여 JBoss 인스턴스를 종료하는 스크립트이다. shutdown명령을 사용하여 종료하기 때문에 작업 중이던 처리를 모두 완료한 후 종료한다.
#!/bin/sh
. ./env.sh
$JBOSS_HOME/bin/jboss-cli.sh --connect --controller=$CONTROLLER_IP:$CONTROLLER_PORT --command=:shutdown -
status.sh
JBoss 인스턴스가 실행 중인지 프로세스를 체크하는 스크립트이다.
#!/bin/sh
. ./env.sh
ps -ef | grep java | grep "SERVER=$SERVER_NAME " -
kill.sh
kill -9 <pid>로 JBoss 인스턴스를 강제 종료하는 스크립트이다. 서버를 실행하는 start.sh 스크립트에서$SERVER_NAME환경변수를 지정하였기 때문에 해당 자바 프로세스만 kill 한다. grep시 맨 뒤에 있는 공백이 꼭 필요하니 주의하여야 한다. 예를 들어$SERVER_NAME이 front1인 프로세스와 front12인 프로세스가 실행 중이면, 공백이 없으면 두 프로세스 모두 kill 된다.#!/bin/sh
. ./env.sh
ps -ef | grep java | grep "SERVER=$SERVER_NAME " | awk \{'print "kill -9 " $2'} | sh -x -
nohup.sh
JBoss 인스턴스의 nohup로그를 tail로 보는 스크립트이다.
#!/bin/sh
. ./env.sh
tail -f $JBOSS_LOG_DIR/nohup/$SERVER_NAME.out -
jboss-cli.sh
해당JBoss 인스턴스에 CLI로 접속하는 스크립트이다. 스크립트를 실행하면 env.sh 파일에 정의된 컨트롤러로 자동으로 접속한다.
#!/bin/sh
. ./env.sh
export JAVA_OPTS=" -Djava.awt.headless=false $JAVA_OPTS"
$JBOSS_HOME/bin/jboss-cli.sh --controller=$CONTROLLER_IP:$CONTROLLER_PORT --connect $@ -
jconsole.sh
JConsole을 실행하는 스크립트이다. 이 스크립트를 실행하면 해당 JBoss 인스턴스에 접속하는 remoting-jmx URI를 화면에 출력하고 JConsole을 실행한다. 원격에서 접속하려면 화면에 출력되는 JMX URL을 사용하면 된다. JMX의 사용법에 대해서는 ‘19장. JBoss EAP 6 모니터링’에서 자세히 설명하고 있다.
#!/bin/sh
. ./env.sh
echo "======================================================="
echo " JMX URL : service:jmx:remoting-jmx://$MGMT_ADDR:$CONTROLLER_PORT"
echo "======================================================="
$JBOSS_HOME/bin/jconsole.sh -
dump.sh
이 스크립트를 실행하면 자동으로 3초 간격으로 5회 스레드 덤프를 nohup에 출력한다.
#!/bin/sh
. ./env.sh
for count in 1 2 3 4 5; do
echo "Thread Dump : $count"
for i in `ps -ef | grep java | grep "SERVER=$SERVER_NAME " | awk '\{print $2}'`;do
echo "+kill -3 $i"
kill -3 $i
echo "sleep 1 sec"
sleep 1
done
echo "done"
sleep 3
done
2.운영체제 환경 설정
JBoss 사용자
웹 애플리케이션 서버 프로세스는 일반 사용자 계정으로 기동해야 한다. 보안상의 이유로 root 계정을 사용하지 않는 것이 좋다. 예제에서는 ‘jboss’라는 사용자를 추가한다. JBoss EAP 6 스크립트에서 env.sh 파일에 JBOSS_USER 환경변수에 JBoss 인스턴스를 구동할 리눅스 사용자 이름 ‘jboss’를 설정하면, jboss 사용자만 인스턴스를 구동할 수 있다.
$ adduser jboss
env.sh 파일에서 JBOSS_USER 환경변수를 설정한다.
export JBOSS_USER=jboss
리눅스 커널 파라미터
웹 서버와 웹 기반 미들웨어 서버는 모두 네트워크를 통해 서비스를 제공하는 시스템이다. 네트워크를 통해 데이터를 전달하기 때문에, 운영체제의 TCP/IP에 대한 튜닝은 필수적이다. 아래 표에서 설명한 핵심적인 파라미터를 적용하는 것이 좋다. 특히 TCP의 수신, 송신 버퍼의 크기는 운영체제가 기본적으로 제공하는 것보다 크게 설정해야 서버의 성능을 향상할 수 있다. 다음 설정을 웹 서버와 JBoss 운영 서버에 대해 모두 적용한다.
| 파라미터 | 권장값 | 설명 |
|---|---|---|
| net.ipv4.tcp_keepalive_time | 30 | keep-alive 시간을 줄인다. |
| net.ipv4.tcp_fin_timeout | 10 | FIN 타임아웃 시간을 줄여 FD를 빨리 확보할 수 있도록 한다. |
| net.core.netdev_max_backlog | 2500 | 백로그에 들어오는 소켓 개수를 늘린다. |
| net.ipv4.tcp_retries1 | 3 | TCP 연결에 문제가 있을 때 연결을 재시도하는 횟수(최솟값은 3이다) |
| net.ipv4.tcp_retries2 | 3 | TCP 연결을 끊기 전에 재시도하는 횟수를 줄인다. |
| net.ipv4.ip_local_port_range | 1024 65000 | 사용할 수 있는 로컬 포트 범위를 늘린다. |
| net.core.rmem_max | 56777216 | TCP 수신 버퍼크기 최댓값을 늘린다. |
| net.core.rmem_default | 16777216 | TCP 수신 버퍼크기 기본값을 늘린다. |
| net.core.wmem_max | 56777216 | TCP 전송 버퍼크기 최댓값을 늘린다. |
| net.core.wmem_default | 16777216 | TCP 수신 버퍼크기 기본값을 늘린다. |
| net.ipv4.tcp_window_scaling | 1 | 65kb 이상의 큰 TCP 윈도우 스케일링을 사용한다. |
| net.ipv4.tcp_orphan_retries | 0 | 서버 측에서 닫은 TCP 연결을 끊기 전에 확인하는 횟수를 줄인다. 기본값은 7로 50초~16분 정도 걸린다. |
| net.ipv4.tcp_sack | 0 | SYNC 패킷을 전송한 후 일부 ACK를 받지 못했을 경우 선택적으로 받지 못한 ACK 패킷을 받도록 설정할 수 있다. 0은 받지 않는 설정이다. 패킷 유실이 많은 네트워크에서는 1로 설정한다. |
표 5. 주요 리눅스 커널 파라미터
-
적용방법
웹 서버와 JBoss 서버 모두
/etc/sysctl.conf파일에 다음 설정을 추가한다.# Updates
net.ipv4.neigh.default.unres_qlen=100
net.ipv4.tcp_keepalive_time = 30
net.ipv4.tcp_fin_timeout = 10
net.core.netdev_max_backlog = 2500
net.ipv4.tcp_retries1 = 2
net.ipv4.tcp_retries2 = 3
net.ipv4.ip_local_port_range = 1024 65000
net.core.rmem_max =56777216
net.core.rmem_default = 16777216
net.core.wmem_max = 56777216
net.core.wmem_default = 16777216
net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_sack = 0
net.ipv4.tcp_orphan_retries = 0적용방법은 sysctl 명령을 사용하면 된다. 물론 리눅스 커널 파라미터를 수정하는 것이기 때문에 root 계정을 사용하여야 한다.
$ sudo sysctl -p
사용자 limit 값 설정
운영체제에서는 파일을 열 수 있는 개수 제한이 있다. 파일 오픈 개수를 늘려주는 것이 좋다.
웹 서버나 JBoss 서버 모두 네트워크를 주로 사용한다. 연결을 맺을 때 소켓(Socket)을 사용하는 것이다. 그런데 운영체제에서는 이 소켓도 파일처럼 간주한다. FD(File Descriptor)는 프로세스가 열 수 있는 파일과 소켓을 모두 포함한 값이다.
사용자가 사용할 수 있는 FD 개수가 작다면, 열 수 있는 소켓, 즉, 동시에 받아들일 수 있는 요청의 개수도 작아지게 되는 것이다. 동시에 더 많은 요청을 처리하려면 FD 값도 그만큼 커야 한다.
리눅스의 /etc/security/limits.conf 파일에서 jboss 사용자가 오픈할 수 있는 파일의 개수를 지정한다. 이 값은 웹 서버와 JBoss 서버 모두 지정한다.
또, jboss 사용자에 대한 nproc 값도 지정했는데, 이것은 프로세스의 최대 개수를 지정하는 것이다.
# /etc/security/limits.conf
#
… 생략 …
#<domain> <type> <item> <value>
#* soft core 0
#* hard rss 10000
#@student hard nproc 20
#@faculty soft nproc 20
#@faculty hard nproc 50
#ftp hard nproc 0
#@student - maxlogins 4
jboss hard nofile 65536
jboss soft nofile 65536
jboss soft nproc 2047
jboss hard nproc 16384
# End of file
3.JBoss EAP 6 인스턴스 구성
JBoss EAP 6 설치
먼저 설치할 디렉터리를 생성한다.
$ sudo mkdir -p /svc/test/was/domains
$ sudo mkdir -p /logs/was/server11
$ sudo mkdir -p /logs/was/server12
$ sudo mkdir -p /svc/test/was/domains/applications
JBoss EAP 6.2을 /svc/test/was 디렉터리에 설 치한다.
$ cp jboss-eap-6.2.0.zip /svc/test/was
$ cd /svc/test/was
$ unzip jboss-eap-6.2.0.zip
/svc/test/was 디렉터리를 jboss 사용자가 사용할 수 있도록 권한을 준다.
$ sudo chown -R jboss.jboss /svc/test/was
$ sudo chown -R jboss.jboss /logs/was
네이티브 모듈 설치
네이티브 모듈은 아파치 웹 서버의 통신 모듈을 라이브러리로 만든 APR(Apache Portable Runtime)을 사용하여 HTTP, AJP 통신을 하는 모듈이다. 이 모듈을 설치하면 통신 성능이 향상된다. 자세한 내용은 ’20장. JBoss EAP 6 튜닝’의 4. 웹 서브시스템 절을 참조하라.
설치방법은 간단하다. 해당 플랫폼과 아키텍처에 맞는 파일을 다운로드하여 압축을 풀기만 하면 된다.
$ cp jboss-eap-native-6.2.0-RHEL6-x86_64.zip /svc/test/was
$ cd /svc/test/was
$ unzip jboss-eap-native-6.2.0-RHEL6-x86_64.zip
네이티브 모듈을 사용하려면 리눅스에 다음 패키지들을 설치해야 한다.
$ sudo yum install nss elinks apr-devel apr-util-devel krb5-workstation mod_auth_kerb
네이티브 모듈을 JBoss EAP 6에서 사용하려면, 웹 서브 시스템에서 native 를 true로 설정하여야 한다. 3.3절에서 인스턴스를 구성할 때 다음과 같이 설정하게 된다.
$ vi configuration/standalone-ha.xml
<subsystem xmlns="urn:jboss:domain:web:1.5" default-virtual-server="default-host" instance-id="${jboss.node.name}" native="true">
인스턴스 구성
도메인 디렉터리에 JBoss 스탠드얼론 인스턴스들을 구성한다. 이제부터는 jboss 사용자로 로그인하여 작업한다.
인스턴스 복사
JBoss EAP 6가 설치된 디렉터리에 있는 standalone 디렉터리를 구성하려는 서버 인스턴스 디렉터리로 복사한다.
$ cd /svc/test/was/jboss-eap-6.2
$ cp -R standalone /svc/test/was/domains/server11
$ cp -R standalone /svc/test/was/domains/server12
스크립트 복사
github에서 다운로드한 스크립트 파일들을 JBoss인스턴스 디렉터리로 복사한다.
$ cd git/jboss-eap-6-scripts/standalone1
$ cp *.sh /svc/test/was/domains/server11
$ cp *.properties /svc/test/was/domains/server11
$ cp *.sh /svc/test/was/domains/server12
$ cp *.properties /svc/test/was/domains/server12
*. sh 파일에 실행 권한을 준다.
$ chmod u+x /svc/test/was/domains/server11/*.sh
$ chmod u+x /svc/test/was/domains/server12/*.sh
env.sh 파일 수정
각 인스턴스 디렉터리 server11, server12, server21, server22 디렉 터리에서 다음 env.sh 파일의 디렉터리 설정과 IP 주소, 포트 오프셋 등을 각각 머신 및 인스턴스 이름에 맞게 변경한다.
… 생략…
##### JBOSS Directory Setup #####
export JBOSS_HOME=/svc/test/was/jboss-eap-6.2
export DOMAIN_BASE=/svc/test/was/domains
export SERVER_NAME=server11
export JBOSS_LOG_DIR=/logs/was/server11
export PORT_OFFSET=100
export JBOSS_USER=jboss
export BIND_ADDR=192.168.0.101
export MULTICAST_ADDR=230.1.1.1
export JMS_MULTICAST_ADDR=231.7.1.1
export MODCLUSTER_MULTICAST_ADDR=224.1.1.105
export MGMT_ADDR=192.168.0.101
… 생략…
수정한 server11/env.sh 파일을 server12로 복사하면 몇 가지 설정만 변경하면 된다.
$ cp env.sh ../server12/
server12/env.sh 파일 변경
… 생략…
export SERVER_NAME=server12
export JBOSS_LOG_DIR=/logs/was/server12
export PORT_OFFSET=200
… 생략…
관리자 추가
add-user.sh 스크립트를 실행하여 JBoss 관리자를 추가한다.
$ cd /svc/test/was/domains/server11
$ ./add-user.sh
$ cd /svc/test/was/domains/server12
$ ./add-user.sh
웹 서브시스템 설정
웹 서브시스템에 몇 가지 설정이 필요하다. 먼저 ‘16장. JBoss EAP 6클러스터링’에서 설명한 것과 같이 mod_jk 연결을 위해서 세션 ID에 사용할 instance-id를 설정해야 한다. 이 이름은 mod_jk의 워커 이름과 같아야 한다.
여기서는 JBoss 인스턴스의 이름인 server11, server12, server21, server22를 사용하려고 한다. 이미 env.sh 파일에서 -Djboss.node.name=$NODE_NAME으로 설정했기 때문에, standalone-ha.xml 파일에 ${jboss.node.name}만 설정하면 인스턴스별로 해당 노드 이름이 설정된다.
또, HTTP 요청을 APR 모듈 사용하여 처리하는 네이티브 모듈을 설치하였기 때문에 native를 true로 설정한다.
$ cd /svc/test/was/domains/server11
$ vi configuration/standalone-ha.xml
<subsystem xmlns="urn:jboss:domain:web:1.5" default-virtual-server="default-host" instance-id="${jboss.node.name}" native="true">
스레드 풀 설정
스레드 풀의 설정에 대해서는 ‘20장. JBoss EAP 6 튜닝’에서 자세히 설명하고 있다.
HTTP/AJP 연결에 대한 스레드 풀의 최댓값을 충분한 값으로 설정해 주어야 한다.
http-thread-pool을 최대 250개 사용할 수 있도록 설정한다.
<subsystem xmlns="urn:jboss:domain:threads:1.1">
… 생략 …
<unbounded-queue-thread-pool name="http-thread-pool">
<max-threads count="250"/>
<keepalive-time time="60" unit="minutes"/>
</unbounded-queue-thread-pool>
… 생략 …
</subsystem>
ajp 커넥터와 http 커넥터가 위에서 설정한 http-thread-pool 스레드 풀을 사용하도록 다음과 같이 설정한다.
<connector name="ajp" protocol="AJP/1.3" scheme="http" socket-binding="ajp" executor="http-thread-pool" max-connections="3260"/>
<connector name="http" protocol="HTTP/1.1" scheme="http" socketbinding="http" enable-lookups="false" executor="http-thread-pool" max-connections="3260"/>
배포스캐너 설정
별도의 디렉터리를 애플리케이션 배포 디렉터리로 사용할 수 있도록 배포 스캐너를 설정한다.
<subsystem xmlns="urn:jboss:domain:deployment-scanner:1.1">
<deployment-scanner path="deployments" relative-to="jboss.server.base.dir" scan-interval="5000"/>
<deployment-scanner name="external-deployment-scanner" path="$\{jboss.external.deployment:/svc/test/was/domains/applications}" scan-interval="5000" auto-deploy-exploded="false"/>
</subsystem>
server11에서 설정한 standalone-ha.xml 파일을 server12로 복사한다.
$ cd /svc/test/was/domains/server11/configuration
$ cp standalone-ha.xml ../../server11/configuration/