반응형

도커 환경에서 tomcat, mariadb 컨테이너 구성하여 테스트하는 중.

이상한 증상이 있었음.

war를 올려서 구동하는데, 너무 늦게 구동됨. 1분 정도?? 딜레이가 발생하였다...

tomcat 로그를 봐도 알수가 없었음. WAR가 풀리고 중간에 1분 정도 멈췄다가 다시 진행되어 WAS가 구동되는 현상.

원인은??? DB의 name resolve 문제였음. DBMS가 외부에서 온 접속을 IP 주소에서 호스트명으로 변환을 시도하다 호스트명 resolve를 못하고 타임아웃까지 기다리는 현상이 원인이었던 것으로 추정된다. (어디서는 이런 현상이 없었는데, 어디서는 이런 현상이 발생하고 그랬다. 어떤 환경차이인지는 모르겠다.)

해결방안 my.cnf 파일을 만들어 DB 컨테이너 만들때 config에 넣어준다. 아래에서 보면 skip-name-resolve  한 줄을 추가했더니, 위에 1분간 딜레이되던 현상이 없어졌다. 바로 war가 풀리고 정상 가동되었다. 

my.cnf

[mysqld]
character-set-server=utf8
collation-server=utf8_general_ci
skip-character-set-client-handshake
skip-name-resolve
#default-authentication-plugin=mysql_native_password
#sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
#sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION

(sql_mode가 DBMS에 따라 가끔 지원하지 않는 필드들이 있어서 위에 주석처리한 것들이 있음.)

 

+ tomcat, mariadb 도커 환경 구축

여기서는 식별을 위해서 컨테이너 이름이나 포트번호에 2를(db2, 23306, tomcat2, 28080 등) 붙였다. (이후에 또 만들것들은 3, 4, 등으로 연속해서 추가하는 방식으로 관리하였다.)

1. create_db.sh ; DB 컨테이너 생성하여 실행 또는 있으면 재실행

현재 폴더에 db 폴더가 없으면 최초 실행으로 판단하여 db 설정(my.cnf)를 복사하고 DB를 초기화한다.

#!bin/sh
if [ "$(ls -A db)" ]; then
	echo "db dir is already exist."
else
	echo "created db dir and copied my.cnf."
	mkdir -p db/config
	cp my.cnf db/config
fi

docker rm -f db2
docker run -d --restart always \
--name db2 \
-v /home/storage/2.mysvc/db/config/my.cnf:/etc/mysql/my.cnf \
-v /home/storage/2.mysvc/db/data:/var/lib/mysql \
-v /home/storage/2.mysvc/db/log:/var/log/mysql \
-v /home/storage/2.mysvc/db/temp:/temp \
--privileged \
-p 23306:3306 \
-e TZ=Asia/Seoul \
-e LC_ALL=C.UTF-8 \
-e MYSQL_ROOT_PASSWORD=mysvc00. \
mariadb:latest

위 쉘을 실행하여 mariadb가 떴으면 23306 포트로 접속하여 쿼리로 데이터베이스와 테이블들을 생성해 주면 된다.

 

2. create_tomcat.sh ; tomcat 실행 또는 재실행(이미 컨테이너가 떠 있는 경우)

아래의 경우 맥주소를 고정할 필요가 있어서 --mad-address 옵션을 추가한 것이다. (필요시 사용)

webapps 폴더가 생성될 것이고, 여기에 war를 올리면 구동될 것이다.

myconfig라고 폴더를 지정한 것은 war에서 사용할 설정 파일들을 특정 위치에 고정시키려고 한 것이다. (필요시 사용)

locallib 폴더는 native library (*.so)를 JVM에서 사용하려고 올려 넣은 것이다. (필요시 사용)

link로 위에서 만든 컨테이너 db2를 사용할수 있도록 지정함.

#!/bin/sh
docker rm -f tomcat2
docker run -d --restart always \
--mac-address=12:33:44:55:66 \
--name tomcat2 \
-v /home/storage2/2.mysvc/myconfig:/myconfig \
-v /home/storage2/2.mysvc/webapps:/usr/local/tomcat/webapps \
-v /home/storage2/2.mysvc/locallib:/usr/local/lib \
--privileged \
--link db2:db2 \
-p 28080:8080 \
-e TZ=Asia/Seoul \
-e LC_ALL=C.UTF-8 \
-e JAVA_OPTS="$JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -Duser.timezone=GMT+9:00 -Djava.library.path=/usr/local/lib" \
tomcat:8

war 설정 파일들(/myconfig)과 war 파일을 다 올렸으면, 로그를 확인함.

3. log.sh  ; 톰캣 최근 1분 로그부터 보기

#!/bin/sh
docker logs -f --since 1m tomcat2

4. stop.sh ; 컨테이너 종료.

#!/bin/sh
docker rm -f db2
docker rm -f tomcat2

 

이제 간단하게 shell script 만 실행하면서 쉽게 개발 테스트를 할 수 있다.

 

반응형


+tomcat의 구동 스크립트에 환경변수를 추가하여 java 메모리튜닝 및 외부 라이브러리 경로 설정을 한다.


구동 스크립트 경로: /usr/tomcat7/bin/catalina.sh

위 스크립트 가장 앞 부분에 추가한다.
보통 외부 라이브러리 경로는 /usr/local/lib에 추가한다. 그곳에 *.so 동적 라이브러리들을 추가하고 아래와 같이 LD_LIBRFARY_PATH에 추가해 준다.

#!/bin/sh

export LD_LIBRARY_PATH=.:/usr/lib/oracle/12.1/client64/lib:/usr/lib:/usr/local/lib
export CLASSPATH=/usr/java/latest/jre/lib/ext:/usr/java/latest/lib/tools.jar
JAVA_OPTS="-Dhttps.protocols=TLSv1,TLSv1.1,TLSv1.2 -Djava.library.path=/usr/local/lib -Djava.awt.headless=true -Dfile.encoding=UTF-8 -server -Xms1024m -Xmx1024m -XX:NewSize=512m -XX:MaxNewSize=512m -XX:PermSize=512m -XX:MaxPermSize=512m -XX:+DisableExplicitGC"

export TOMCAT_HOME=/usr/tomcat7
export CATALINA_HOME=/usr/tomcat7
export CATALINA_BASE=/usr/tomcat7
export CATALINA_PID=/usr/tomcat7/bin/tomcat.pid




+ 톰캣 튜닝
# vi /usr/tomcat/conf/server.xml


connectionTimeout="5000" 
     타임아웃으로 기본 60초 (60000) 이다. 10초이내 권장
maxThreads="100"
     tomcat의 최대 쓰레드 수. 최대 접속 가능한 active user수
acceptCount="100"
     tomcat thread full일 경우 대기 queue의 길이
disableUploadTimeout="true"
     데이터 업로드 할 때 사이즈가 크면 timeout이 걸릴수 있음. 이를 방지.
maxConnection="8192"
     tomcat이 유지하는 최대 접속 수.
     


-listner 설정
루트 계정으로 실행 못하게 막기
 <Listener className="org.apache.catalina.security.SecurityListener" checkedOsUsers="root" /> 

-Connector 설정
protocol="org.apache.coyote.http11.Http11Protocol"
acceptCount="10"
enableLookups="false"
compression="off"
maxConnection="8192"
maxKeepAliveRequest="1"
maxThread="100"
tcpNoDelay="true"

예)
<Connector port="8080" address="localhost" maxThreads="250" maxHttpHeaderSize="8192" emptySessionPath="true" protocol="HTTP/1.1" enableLookups="false" redirectPort="8181" acceptCount="100" connectionTimeout="20000" disableUploadTimeout="true" URIEncoding="UTF-8" />


       <Connector port="8443" protocol="HTTP/1.1"
                SSLEnabled="true" scheme="https" secure="true"
                clientAuth="false" sslProtocol="TLS"
                keystoreFile="/var/www/tomcat.keystore" keystorePass="패스워드"
                URIEncoding="UTF-8"
                maxThreads="250" maxHttpHeaderSize="8192"
                enableLookups="false" acceptCount="100" connectionTimeout="20000"
                disableUploadTimeout="true" 
     compression="off"
     tcpNoDelay="true"
/>


+JVM 튜닝
vi $CATALINA_HOME/bin/catalina.sh
첫 줄에 JAVA_OPTS 추가.
-Xmx1024m –Xms1024m -XX:MaxNewSize=384m -XX:MaxPermSize=128m

메모리 부족시 덤프를 뜨게하여 추적할 수 있다.
-XX:-HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./java_pid<pid>.hprof
-XX:ParallelGCThreads=2 -XX:-UseConcMarkSweepGC

예)
JAVA_OPTS="-Djava.awt.headless=true -Dfile.encoding=UTF-8 -server -Xms1024m -Xmx1024m -XX:NewSize=512m -XX:MaxNewSize=512m -XX:PermSize=512m -XX:MaxPermSize=512m -XX:+DisableExplicitGC"



+++ OS 튜닝 필요

+ 사용자 최대 파일(소켓 포함) 오픈 개수
ulimit -a로 확인 가능
소켓도 파일 이므로 최대 사용 개수가 제한된다....

:변경 방법
#sysctl -w fs.file-max=372738

아래도 작업
#vi /etc/sysctl.conf
fs.file-max=372738

#sysctl -p

; 변경 확인
sysctl fs.file-max
or
cat /proc/sys/fs/file-max

-최대 파일 오픈 개수 확인 ; ulimit -a
open files ; 1024
>변경방법
#vi /etc/security/limits.conf
* soft nproc 65535
* hard nproc 65535
* soft nofile 65535
* hard nofile 65535
; xxxx는 65535 등...
ulimit -a 로 확인

-backlog 최대값 ; sys/socket.h
SOMAXCONN 값을 참조
>변경 방법
sysctl -a | grep somaxconn     ; 확인
sysctl -w net.core.somaxconn=2048



'Develop > Java' 카테고리의 다른 글

tomcat 프로세스 모니터링. 죽으면 다시 시작  (0) 2018.03.06
CentOS, tomcat 타임존 문제  (2) 2018.03.06
jqGrid(2) row(줄) 색상 변경/값 변경  (0) 2016.01.22
jqGrid (1)  (0) 2016.01.19
한글 인코딩 UTF8  (0) 2015.06.02

+ Recent posts