Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- maven
- no space left
- aggregation
- restart
- 몽고DB
- MongoDB
- 상태
- GRACEFUL
- 톰캣
- 확인
- 진행
- 배포
- 무중단
- slowQuery
- was
- troubleshooting
- tomcat
- web
- projection
- kill
- apache
- deploy
- NoSQL
- LocalRepository
- 테크블로그
- 인덱스
- 성능
- Pipeline
- httpd
- longQuery
Archives
- Today
- Total
boogie의 가벼운 개발 일기
[Infra] Apache-Tomcat 무중단 배포 구성기 - (2) 최종 적용 방식 및 warm-up 본문
세번째 시도 // Worker의 Status를 직접 제어하자 (성공)
- jk status (status worker) 또는 graceful restart
jk status manager의 web view 화면. 이런게 웹 포트가 열려있다니 방화벽으로 막는다고 해도 꺼림칙하다..
- js status manager
- worker의 상태를 관리하는 worker를 별도로 띄운다
- 해당 status worker에 GET 요청을 날려서 worker의 상태를 확인하거나 변경할수 있음
- 해당 페이지에 접근하게되면 서버들을 모두 disable 할 수 있기때문에 보안상 좋은 방법은 아니라고 생각함
- apache graceful restart
- 서버에서 설정파일을 직접 변경, 아파치를 reload하는 방식
- 장점 : apache graceful 명령어를 통해 현재 처리중 요청을 완료한 프로세스들이 종료되고 점차 신규 프로세스로 교체되게 됨
- apache -k graceful 하고 수초 뒤, KeepAlive 상태이션 TCP connection들이 강제 timeout처리되면서 Dynatrace에 Connectivity 이슈로 잡힌다.
- 하지만 아직 해결되지 않는 이슈들이 있었으니...
One more thing // 잘 떼었다 붙이기만 한다고 되는게 아니었다.
- KeepAlive connection 이슈
- 아파치 프로세스가 종료될때 KeepAlive=On 설정인 경우, KeepAliveTimeout 동안 대기하고 TCP연결을 강제종료하게 된다. (nginx도 그렇다..)
- KeepAlive된 세션을통해 계속해서 요청이 들어오면 해당 프로세스의 종료가 지연된다. (어쩌면 계속..)
- 이 부분은 테스트 해 보니, KeepAlive를 Off로 변경해도 성능에 유의미한 차이가 발생하지 않았다. (apache httpd 문서에서도 'static한 resource들을 서빙하는 서버'의 경우 성능에 차이가 '날 수 있다' 라고 되어있었다)
- 첫 리퀘스트 처리속도 이슈 ( WarmUp )
- JVM이 처리하는 첫번째 리퀘스트는 lazy class loading, just-in-time(jit) 컴파일 등에 의해 눈에띄게 느릴수 있다.
- 적용해야 할 프로젝트가 한두개가 아니기때문에 application단에 적용하기보다, resource로 warm-up용 uri를 넣어주면 배포 스크립트에서 자동으로 수행하도록 했다.
- 아래는 jvm 문서에서 발췌한 내용
The first request made to a Java or JVM web application is often substantially slower than the average response time over the life of the process. This warm-up period can usually be attributed to lazy class loading and just-in-time compilation, which optimize the JVM for subsequent requests that execute identical code. As a result, many users find it beneficial to submit a few artificial requests into the JVM process before using it to handle real traffic. Even a simple set of no-op requests to your application can warm-up the networking and messaging parts of the stack, which usually constitute a large portion of the request overhead.
- proxy에서의 lb method로 인한 부하 쏠림
- 이건 꼭 배포와 연관이 있는 부분은 아니지만, 위의 warm-up 이 필요하다는 것을 알기 이전에 리서치하다가 알게되어 함께 적용하였다.
- 무중단 배포를 구성하고 있는 apache - tomcat 각 물리서버 윗단에 proxy로 load balancing 되어있었는데 worker(이 경우 proxy의 worker니까 apache httpd들)중 일부가 일시적으로 버거워서 응답이 늦더라도, 아주 꾸준하게 공평하게 proxy에서 부하를 나누어준다.
- 실 서비스중에도 특정 서버가 무거운 리퀘스트를 처리하면서 지연이 생기면 그 지연기간동안에도 계속 요청이 큐에 쌓이게 된다.
- 그래서 buBusyness로 lbMethod를 변경함
- ConnectionTimeout이 없으면 ...
- apache - tomcat 에 connectionTimeout이 없으면, worker가 1개가 되었을때 그쪽으로 모든 연결이 집중되었다가, 다시 worker가 2개가 되어도, connection이 자연적으로 끊어지지 않기 때문에 계속 유지가 된다. (즉, 한대의 worker로만 트래픽이 들어간다..!)
- 어찌 이런것 조차도 설정이 안되어있는걸까...
- autoDeploy 설정의 문제점
- 톰캣의 autoDeploy가 켜져있으면, war파일이 변경되었을때 톰캣이 멋대로 class reload를 한다..!
- 제어되지 않은 시점에 context가 내려가고 warm-up없이 올라오면서 응답지연이 발생한다.
결과 //
- 배포 시점의 tps 변화
- 배포 시점의 응답시간 (히트맵)
- jenkins 배포 시 console output
- 배포 쉘 작성 내용
배포 쉘 구성은 3개 파일로 되어있다.
파일 1 - 절체/투입 할 apache worker 정보(이름) 및 health check uri, warm-up uri 목록이 담긴 파일 위치
이건 민감한 정보가 있어서 비공개..
파일 2 - 각 worker를 graceful하게 재기동하고 실패시 오류코드를 반환하는 배포 실행 쉘
#!/bin/sh
SHELL_DIR="$( cd "$( dirname "$BASH_SOURCE" )" && pwd -P )"
cd ${SHELL_DIR}
source common.sh
echo "■■■■■■■■■■■■■■■■■■■■ ${WORKER1_NAME} START ■■■■■■■■■■■■■■■■■■■■■■■"
`pwd`/graceful.sh ${PROJECT} 1 ${WORKER1_NAME} ${WORKER1_HTTP_PORT}
if [ $? -ne 0 ]; then
echo "[ERROR] FAILED ON BUILD/DEPLOY"
exit 1
fi
echo "■■■■■■■■■■■■■■■■■■■■ ${WORKER2_NAME} START ■■■■■■■■■■■■■■■■■■■■■■■"
`pwd`/graceful.sh ${PROJECT} 2 ${WORKER2_NAME} ${WORKER2_HTTP_PORT}
if [ $? -ne 0 ]; then
echo "[ERROR] FAILED ON BUILD/DEPLOY"
exit 1
fi
echo "SUCCESS"
exit 0
파일 3 - 실제 해당 worker를 아파치 설정파일에서 상태 변경, 아파치 재시작, 톰캣 재기동, 헬스체크, 웜업, 아파치에 재투입 하는 쉘
#!/bin/sh
SHELL_DIR="$( cd "$( dirname "$BASH_SOURCE" )" && pwd -P )"
cd ${SHELL_DIR}
source common.sh
PROJECT=$1
SERVER_NUM=$2
WORKER_NAME=$3
HTTP_PORT=$4
cp -rf ${WORKER_PROPERTIES} ${WORKER_PROPERTIES}_backup
PRESET_EXISTS=`grep "worker.${WORKER_NAME}.activation=" ${WORKER_PROPERTIES}`
if [ "${PRESET_EXISTS}" == "" ]; then
echo -e "worker.${WORKER_NAME}.activation=" >> ${WORKER_PROPERTIES}
fi
## worker activation=stopped
echo -e "\n\n> [DEACTIVATE] ${WORKER_NAME}"
sed -i "s/^worker.${WORKER_NAME}.activation=$/worker.${WORKER_NAME}.activation=s/g" ${WORKER_PROPERTIES}
${HTTPD_HOME}/bin/httpd -k graceful
echo "> wait deactivation 20s"
sleep 20
## 톰캣 구동
echo -e "\n\n> [STARTUP] tomcat ${WORKER_NAME}"
${BASEDIR}/bin/manage-tomcat.sh ${PROJECT} ${SERVER_NUM} start
## WAS 구동 확인
echo -e "\n\n> [HEALTH CHECK] ${WORKER_NAME}"
CNT=1
LAST_STATUS=-1
while [[ ("$STATUS" -ne 200) && ($CNT -lt 30) ]]; do
echo "◆ ${CNT}: http://localhost:${HTTP_PORT}${HC_ROUTE}"
STATUS=$(curl -o /dev/null -w "%{http_code}\n" "http://127.0.0.1:${HTTP_PORT}${HC_ROUTE}")
echo "STATUS : ${STATUS}"
sleep 5
CNT=$((CNT+1))
LAST_STATUS=${STATUS}
done
if [ $LAST_STATUS -ne 200 ]; then
echo "[ERROR] FAILED ON HTTP HEALTH CHECK"
exit 1
fi
## WARM-UP
echo -e "\n\n> [WARMUP] warming up ${WORKER_NAME}"
CNT=1
for ROUTE in $(cat ${BASEDIR}/src/web/resources/main/warmup_urls.txt)
do
echo -e "\n◆ ${CNT}: calling http://localhost:${HTTP_PORT}${ROUTE}"
STATUS=$(curl -o /dev/null -w "%{http_code}" "http://127.0.0.1:${HTTP_PORT}${ROUTE}")
echo "status : ${STATUS}"
if [ ${STATUS} -ne 200 ]; then
echo "[ERROR] FAILED ON WARM-UP URL : http://127.0.0.1:${HTTP_PORT}${ROUTE} --> STATUS : ${STATUS}"
##exit 1 ## warm-up url은 실패해도 배포를 계속 진행한다
fi
done
sleep 5
## worker activation=active
echo -e "\n\n> [ACTIVATE] WORKER ${WORKER_NAME}"
sed -i "/^worker.${WORKER_NAME}.activation=/d" ${WORKER_PROPERTIES}
${HTTPD_HOME}/bin/httpd -k graceful
echo "> wait activation(30s)"
sleep 30
echo -e "\n\n[COMPLETE] ${WORKER_NAME}"
'Server, Infra' 카테고리의 다른 글
[Infra] Apache-Tomcat 무중단 배포 구성기 (1) 구상 및 실패 사례 (0) | 2021.06.29 |
---|---|
[Infra] 빌드 배포 서버에서 user home 디렉토리 용량 가득 참 (0) | 2021.06.29 |