728x90

일반적으로 Web 서비스를 구성할때는 Load balancing 역활을 수행하는 L4 Switch 이하로 n대의 WEB 서버를 구성하여 부하분산과 이중화를 통해 서비스 가용성을 높인다.

 

만약 다량의 Web Server Node를 동시에 점검해야할 사항이 발생한다면, Client Hosts 파일에 서비스 도메인에 대하여 IP를 수동 정의하여 웹브라우저를 통해 Server Node별 체크를 수행하거나 각 웹서버별 Access 로그나 Error 로그를 기준으로 체크하게 된다.

 

만약 이런 일련의 과정이 여의치 못하거나 간단히 각 Web Server Node들의 상태체크만을 원한다면 아래와 같이 Shell Script를 통해 간단히 점검이 가능하다.

 

이하 Shell Script는 curl 명령을 통해 Web Server에서 응답된 상태 Code를 기준으로 상태를 판별하며, HTTP 응답코드는 아래와 같이 분류된다.

 

 

발췌 - 위키백과사전 HTTP 상태코드 (http://ko.wikipedia.org/wiki/HTTP_%EC%83%81%ED%83%9C_%EC%BD%94%EB%93%9C)

 

2xx (성공)
 
이 클래스의 상태 코드는 클라이언트가 요청한 동작을 수신하여 이해했고 승낙했으며 성공적으로 처리했음을 가리킨다.
 200(성공): 서버가 요청을 제대로 처리했다는 뜻이다. 이는 주로 서버가 요청한 페이지를 제공했다는 의미로 쓰인다.
 201(작성됨): 성공적으로 요청되었으며 서버가 새 리소스를 작성했다.
 202(허용됨): 서버가 요청을 접수했지만 아직 처리하지 않았다.
 203(신뢰할 수 없는 정보): 서버가 요청을 성공적으로 처리했지만 다른 소스에서 수신된 정보를 제공하고 있다.
 204(콘텐츠 없음): 서버가 요청을 성공적으로 처리했지만 콘텐츠를 제공하지 않는다.
 205(콘텐츠 재설정): 서버가 요청을 성공적으로 처리했지만 콘텐츠를 표시하지 않는다. 204 응답과 달리 이 응답은 요청자가 문서 보기를 재설정할 것을 요구한다(예: 새 입력을 위한 양식 비우기).
 206(일부 콘텐츠): 서버가 GET 요청의 일부만 성공적으로 처리했다.
 207(다중 상태, RFC 4918)
 208(이미 보고됨, RFC 5842)
 226 IM Used (RFC 3229)
 
3xx (리다이렉션 완료)
 
클라이언트는 요청을 마치기 위해 추가 동작을 취해야 한다.[1]
 300(여러 선택항목): 서버가 요청에 따라 여러 조치를 선택할 수 있다. 서버가 사용자 에이전트에 따라 수행할 작업을 선택하거나, 요청자가 선택할 수 있는 작업 목록을 제공한다.
 301(영구 이동): 요청한 페이지를 새 위치로 영구적으로 이동했다. GET 또는 HEAD 요청에 대한 응답으로 이 응답을 표시하면 요청자가 자동으로 새 위치로 전달된다.
 302(임시 이동): 현재 서버가 다른 위치의 페이지로 요청에 응답하고 있지만 요청자는 향후 요청 시 원래 위치를 계속 사용해야 한다.
 303(기타 위치 보기): 요청자가 다른 위치에 별도의 GET 요청을 하여 응답을 검색할 경우 서버는 이 코드를 표시한다. HEAD 요청 이외의 모든 요청을 다른 위치로 자동으로 전달한다.
 304(수정되지 않음): 마지막 요청 이후 요청한 페이지는 수정되지 않았다. 서버가 이 응답을 표시하면 페이지의 콘텐츠를 표시하지 않는다. 요청자가 마지막으로 페이지를 요청한 후 페이지가 변경되지 않으면 이 응답(If-Modified-Since HTTP 헤더라고 함)을 표시하도록 서버를 구성해야 한다.
 305(프록시 사용): 요청자는 프록시를 사용하여 요청한 페이지만 액세스할 수 있다. 서버가 이 응답을 표시하면 요청자가 사용할 프록시를 가리키는 것이기도 하다.
 307(임시 리다이렉션): 현재 서버가 다른 위치의 페이지로 요청에 응답하고 있지만 요청자는 향후 요청 시 원래 위치를 계속 사용해야 한다.
 308(영구 리다이렉션, RFC에서 실험적으로 승인됨)
 
4xx (요청 오류)
 
4xx 클래스의 상태 코드는 클라이언트에 오류가 있음을 나타낸다.
 400(잘못된 요청): 서버가 요청의 구문을 인식하지 못했다.
 401(권한 없음): 이 요청은 인증이 필요한다. 서버는 로그인이 필요한 페이지에 대해 이 요청을 제공할 수 있다.
 403(금지됨): 서버가 요청을 거부하고 있다.
 404(찾을 수 없음): 서버가 요청한 페이지를 찾을 수 없다. 예를 들어 서버에 존재하지 않는 페이지에 대한 요청이 있을 경우 서버는 이 코드를 제공한다.
 405(허용되지 않는 방법): 요청에 지정된 방법을 사용할 수 없다.
 406(허용되지 않음): 요청한 페이지가 요청한 콘텐츠 특성으로 응답할 수 없다.
 407(프록시 인증 필요): 이 상태 코드는 401(권한 없음)과 비슷하지만 요청자가 프록시를 사용하여 인증해야 한다. 서버가 이 응답을 표시하면 요청자가 사용할 프록시를 가리키는 것이기도 한다.
 408(요청 시간초과): 서버의 요청 대기가 시간을 초과하였다.
 409(충돌): 서버가 요청을 수행하는 중에 충돌이 발생했다. 서버는 응답할 때 충돌에 대한 정보를 포함해야 한다. 서버는 PUT 요청과 충돌하는 PUT 요청에 대한 응답으로 이 코드를 요청 간 차이점 목록과 함께 표시해야 한다.
 410(사라짐): 서버는 요청한 리소스가 영구적으로 삭제되었을 때 이 응답을 표시한다. 404(찾을 수 없음) 코드와 비슷하며 이전에 있었지만 더 이상 존재하지 않는 리소스에 대해 404 대신 사용하기도 한다. 리소스가 영구적으로 이동된 경우 301을 사용하여 리소스의 새 위치를 지정해야 한다.
 411(길이 필요): 서버는 유효한 콘텐츠 길이 헤더 입력란 없이는 요청을 수락하지 않는다.
 412(사전조건 실패): 서버가 요청자가 요청 시 부과한 사전조건을 만족하지 않는다.
 413(요청 속성이 너무 큼): 요청이 너무 커서 서버가 처리할 수 없다.
 414(요청 URI가 너무 긺): 요청 URI(일반적으로 URL)가 너무 길어 서버가 처리할 수 없다.
 415(지원되지 않는 미디어 유형): 요청이 요청한 페이지에서 지원하지 않는 형식으로 되어 있다.
 416(처리할 수 없는 요청범위): 요청이 페이지에서 처리할 수 없는 범위에 해당되는 경우 서버는 이 상태 코드를 표시한다.
 417(예상 실패): 서버는 Expect 요청 헤더 입력란의 요구사항을 만족할 수 없다.
 418(I'm a teapot, RFC 2324)
 420(Enhance Your Calm, 트위터)
 422(처리할 수 없는 엔티티, WebDAV; RFC 4918)
 423(잠김,WebDAV; RFC 4918)
 424(실패된 의존성, WebDAV; RFC 4918)
 424(메쏘드 실패, WebDAV)
 425(정렬되지 않은 컬렉션, 인터넷 초안)
 426(업그레이드 필요, RFC 2817)
 428(전제조건 필요, RFC 6585)
 429(너무 많은 요청, RFC 6585)
 431(요청 헤더 필드가 너무 큼, RFC 6585)
 444(응답 없음, Nginx)
 449(다시 시도, 마이크로소프트)
 450(윈도 자녀 보호에 의해 차단됨, 마이크로소프트)
 451(법적인 이유로 이용 불가, 인터넷 초안)
 451(리다이렉션, 마이크로소프트)
 494(요청 헤더가 너무 큼, Nginx)
 495(Cert 오류, Nginx)
 496(Cert 없음, Nginx)
 497(HTTP to HTTPS, Nginx)
 499(클라이언트가 요청을 닫음, Nginx)
 
5xx (서버 오류)
 
서버가 유효한 요청을 명백하게 수행하지 못했음을 나타낸다.[1]
 500(내부 서버 오류): 서버에 오류가 발생하여 요청을 수행할 수 없다.
 501(구현되지 않음): 서버에 요청을 수행할 수 있는 기능이 없다. 예를 들어 서버가 요청 메소드를 인식하지 못할 때 이 코드를 표시한다.
 502(불량 게이트웨이): 서버가 게이트웨이나 프록시 역할을 하고 있거나 또는 업스트림 서버에서 잘못된 응답을 받았다.
 503(서비스를 사용할 수 없음): 서버가 오버로드되었거나 유지관리를 위해 다운되었기 때문에 현재 서버를 사용할 수 없다. 이는 대개 일시적인 상태이다.
 504(게이트웨이 시간초과): 서버가 게이트웨이나 프록시 역할을 하고 있거나 또는 업스트림 서버에서 제때 요청을 받지 못했다.
 505(HTTP 버전이 지원되지 않음): 서버가 요청에 사용된 HTTP 프로토콜 버전을 지원하지 않는다.
 506(Variant Also Negotiates, RFC 2295)
 507(용량 부족, WebDAV; RFC 4918)
 508(루프 감지됨, WebDAV; RFC 5842)
 509(대역폭 제한 초과, Apache bw/limited extension)
 510(확장되지 않음, RFC 2774)
 511(네트워크 인증 필요, RFC 6585)
 598(네트워크 읽기 시간초과 오류, 알 수 없음)
 599(네트워크 연결 시간초과 오류, 알 수 없음)

 

 

 

1. Check 대상 Web Server Node의 IP 또는 Domain을 기준으로 리스트 파일 작성

 

[root@TEST-01 shell]# 
[root@TEST-01 shell]# vi list
127.0.0.1
168.126.63.1
168.126.63.2
1.2.3.4
yahoo.com
google.com
naver.com
helperchoi.com
helperchoi.com/notfound.html
[root@TEST-01 shell]# 

 

 

2. Shell Script 의 실행 예시

 

[root@TEST-01 shell]# 

[root@TEST-01 shell]# 
[root@TEST-01 shell]# ./check_web.sh

 

Usage1 - ./check_web.sh [List File]
ex1) - ./check_web.sh list

 

[root@TEST-01 shell]# 
[root@TEST-01 shell]# ./check_web.sh 111

 

Usage1 - ./check_web.sh [List File]
ex1) - ./check_web.sh list

 

[root@TEST-01 shell]# 
[root@TEST-01 shell]# ./check_web.sh list

 

========================= HTTP OK =========================
HTTP Code 301 OK - yahoo.com
HTTP Code 301 OK - google.com
HTTP Code 301 OK - naver.com
HTTP Code 200 OK - helperchoi.com

======================== HTTP Fail ========================
HTTP Code 403 Fail - 127.0.0.1
HTTP Code 404 Fail - helperchoi.com/notfound.html

===================== HTTP Not Listen =====================
HTTP Not Listen - 168.126.63.1
HTTP Not Listen - 168.126.63.2
HTTP Not Listen - 1.2.3.4

 

[root@TEST-01 shell]# 

[root@TEST-01 shell]# 

 

 

3. Shell Script Code

 

[root@TEST-01 shell]# 
[root@TEST-01 shell]# vi check_web.sh
#!/bin/bash

 

declare -a ARRAY_OK
declare -a ARRAY_FAIL
declare -a ARRAY_NOT

 

[ $1 -ge 0 2>/dev/null ]

 

if [ $# -eq 1 -a -e "$1" ]
then
 LIST_FILE=`cat $1`

 

 for LIST in ${LIST_FILE}
 do
  CHECK_HTTP_CODE=`curl -I -4 -m 1 ${LIST} 2>/dev/null | grep "^HTTP" | awk '{print $2}'`
  VERIFY_CEHCK=`expr ${CHECK_HTTP_CODE} + 0 2>/dev/null`
 
  if [ "$VERIFY_CEHCK" -ge 1 ]
  then
   if [ "$CHECK_HTTP_CODE" -eq 200 -o "$CHECK_HTTP_CODE" -le 308 ]
   then
    ARRAY_OK=("${ARRAY_OK[@]}" "`echo "HTTP Code ${CHECK_HTTP_CODE} OK - ${LIST}"`")
   else
    ARRAY_FAIL=("${ARRAY_FAIL[@]}" "`echo "HTTP Code ${CHECK_HTTP_CODE} Fail - ${LIST}"`")
   fi
  else
   ARRAY_NOT=("${ARRAY_NOT[@]}" "`echo "HTTP Not Listen - ${LIST}"`")
  fi
 done
 
 echo
 echo "========================= HTTP OK ========================="
 LOOP_COUNT=0
 LOOP_LIMIT=${#ARRAY_OK[@]}
 while [ "${LOOP_COUNT}" -le "${LOOP_LIMIT}" ]
 do
  echo "${ARRAY_OK[${LOOP_COUNT}]}"
  LOOP_COUNT=`echo "${LOOP_COUNT} + 1" | bc`
 done
 
 echo "======================== HTTP Fail ========================"
 LOOP_COUNT=0
 LOOP_LIMIT=${#ARRAY_FAIL[@]}
 while [ "${LOOP_COUNT}" -le "${LOOP_LIMIT}" ]
 do
  echo "${ARRAY_FAIL[${LOOP_COUNT}]}"
  LOOP_COUNT=`echo "${LOOP_COUNT} + 1" | bc`
 done
 
 echo "===================== HTTP Not Listen ====================="
 LOOP_COUNT=0
 LOOP_LIMIT=${#ARRAY_NOT[@]}
 while [ "${LOOP_COUNT}" -le "${LOOP_LIMIT}" ]
 do
  echo "${ARRAY_NOT[${LOOP_COUNT}]}"
  LOOP_COUNT=`echo "${LOOP_COUNT} + 1" | bc`
 done

 

else 
 echo
 echo "Usage1 - $0 [List File]"
 echo "ex1) - $0 list"
 echo
 exit 0
fi

 

 

출처 : 불량펭귄 - http://blog.helperchoi.com

반응형

'UNIX & LINUX > CentOS' 카테고리의 다른 글

centOS iptables 사용법  (0) 2016.05.27
728x90

iptables은 강력한 패킷필터링 툴입니다.
기존의 iptables에 관한 자세한 문서들이 많이 나와있지만
이 문서는 리눅스 환경을 전제로 하며 iptables의 초심자들을 위해 설명을 하고자 합니다.
오타나 틀린 내용이 있으면 홈페이지에 관련부분을 기제해주기바랍니다.

작성일 2002.10.13

작성자 : 김창현 [CTCquatre] http://www.eyetolife.com

[ 패킷필터링 지식 ]

패킷필터링이란?

패킷필터링은 지나가는 패킷의 해더를 보고 그 전체 패킷의 운명을 결정하는 것을 말한다.
(iptables의 경우 많은 개발중인 기능에서 헤더에 그치지 않고 data의 내용을 검토하기도 한다. 가장 대표적인것이 string match기능이다.)

*:(일반적으로 패킷은 헤더와 데이타를 가진다. 헤더에 필터링할 정보인 출발지IP:PORT,도착지 IP:PORT, checksum,프로토콜 옵셋등을 가지며 데이터는 각각의 전송데이터가 들어간다.)

리눅스 박스의 패킷필터링의 역사

리눅스는 커널 1.1버젼 부터 패킷필터링을 포함하기 시작했다.
제 1세대는 BSD의 ipfw을 기본으로 하였고 
2.0버젼에서 ipfwadm이 사용되었으며
1998년에 2.2기반 패킷필터링툴인 ipchains를 내놓았다. 
그리고 이글에서 논의하고자 하는 제 4세대 필터링툴인 iptables이 2.4커널을 위해
만들어졌다.

netfilter?

일반 iptables사용자들이 가장간과하기 쉬운부분중 한 부분이다.
iptables이 패킷을 필터링 하는것이 아니다.
패킷필터링은 커널에 탑제된 netfilter기능으로 하며
iptables은 단지 netfilter의 룰을 세워줄 뿐이다.
즉 다시 말하자면 iptables은 룰셋구축 툴이라는 말이다.

[ 패킷필터링 ]

iptables에 대해

iptable에 기본 Chain은 아래와 같다.

INPUT chain
FORWARD chain
OUTPUT chain

위의 3가지가 기본 체인이다. 체인들의 모식도는 아래와 같다.

——>INPUT——> Linux Box ——>OUTPUT———>
———↕—————————-↕
———└——— FORWARD ———-┘

여러분의 Linux box를 도착지로 삼는 모든패킷은 INPUT Chain을 통과하게 되며 
여러분의 Linux box에서 생성되 외부로 보내지는 모든패킷은 OUTPUT Chain을 
통과하게 된다.

Forward chain은 *엄밀히 말하자면 도착지가 여러분의 Linux box가 아닌 패킷이 통과하게 되는 체인이다.

*:(다음문서에 다루게 될 Masqurading시에 패킷의 destnationIP정보는 여러분의 Linux box이지만 패킷의 최종도착지는 내부네트워크의 어떠한 컴퓨터일것이다)

지금 커맨드라인에 아래와 같이 쳐보기 바란다.

# iptables -A INPUT -j DROP

엔터키를 누르는 즉시 여러분의 Linux box로 오는 패킷은 모두 거부당할것이다. 즉 모든 통신이 끊어진다.

위의 룰을 굳이 말로 옮기자면

-A:룰을 추가한다 
INPUT: 패킷이 들어오는 체인에 
-j:패킷의 운명을 결정한다. 
DROP: 패킷을 버려라.

즉, INPUT체인으로 들어오는 패킷을 모두 버리는 룰을 추가하는 명령이다.

적용시킨 룰을 보고 싶다면 

# iptables -L 

이라는 명령을 치면된다.

-A와 같은 위치에 있는 옵션은 아래와 같다.

체인에 새로운 규칙을 추가하기 (-A) 
체인의 어떤 지점에 규칙을 삽입하기 (-I) 
체인의 어떤 지점의 규칙을 교환하기 (-R) 
체인의 어떤 지점의 규칙을 제거하기 (-D) 
체인에서 일치하는 첫번째 규칙을 제거하기 (-D) 

이제 위에서 내린 룰을 지워 통신이 되게 하자.
아래와 같이 명령을 내리면 된다.
# iptables -D INPUT 1
또는
# iptables -D INPUT -j DROP 하면 될것이다.

첫번째 방법은 index(룰의 순서)를 지정해서 지우는 방법이고, 두번째는 룰의 내용으로 지우는것이다.

-I,-R은 첫번째 방법과 유사하게 쓸수있다.

룰을 다시 세우고 목록을 보자.

# iptables -A INPUT -j DROP
# iptables -L

살펴보면 

Chanin INPUT (policy ACCEPT)

위와 같은 줄을 볼수있을것이다.
저 줄 밑에는 여러분들이 세운 룰의 정보를 볼수있을것이다.

(policy ACCEPT)를 설명하자면 여러분들이 세운룰에 해당되지 않을때
마지막으로 기본정책을 따라 패킷의 운명을 결정하게 된다. 여기서는 ACCEPT이므로
패킷은 받아드려질것이다. 아지만 이것을 DROP으로하면 패킷은 버려질것이다.

그리고 패킷필터링을 알아가면서 여러룰들을 세울것이다.
기본적으로 룰은 세워진 순서대로 패킷을 검사한다.

이제 기본정책을 바꾸어 보자.

# iptables -P INPUT DROP

위의 명령을 내리고 다시 iptables -L을 하면

Chanin INPUT (policy DROP)으로 된걸 볼수있다.

-P와 동등 위치의 옵션은 아래와 같다.

새로운 체인 만들기 (-N). 
비어있는 체인을 제거하기 (-X).
※ 이 두옵션은 직접체인을 만들었을경우와 제어할경우에 해당된다. 기본체인(INPUT,OUTPUT,FORWARD) 에는 해당되지 않는다.

미리 만들어진 체인의 정책을 바꾸기 (-P) 
어떤 체인의 규칙들을 나열하기 (-L) 
체인으로부터 규칙들을 지우기 (-F) 
체인내의 모든 규칙들의 패킷과 바이트의 카운드를 0 으로 만들기 (-Z) 

[ 패킷의 목적지또는 출처 제어 ] 

패킷출처 제어옵션 -s

# iptables -A INPUT -s 192.168.10.10 -j DROP 

위에 같은 명령을 내렸다면 192.168.10.10으로 부터 온 패킷은 모두 버려지게 된다.

-s(–source,–src와 같은 옵션이다.) : 패킷의 출처 IP 지정

목적지 제어옵션 -d

# iptables -A INPUt -d 192.168.10.12 -j DROP

위와 같은 명령을 내렸다면 192.168.10.12의 IP를 도착지로 가지고있는 패킷은 모두 버려지게된다.

-d(–destination,–dst와 같은 옵션이다.): 패킷의 도착지 IP지정

※ IP지정 이외에 몇 가지 방법이 더 존재한다.
-s www.xxxx.com : 도메인으로 제어
-s 192.168.10.0/24 : 네트워크 또는 집단으로 제어
-s 192.168.10.0/255.255.255.0 :위와 동일

※ 보통 프로그래밍 약속기호처럼 !는 역(‘not’)이라는 것을 표시한다.
ex) -s ! 192.168.10.10 이라고 하면 “출발지가 192.168.10.10이 아닌” 이라는 뜻이된다.

[ 프로토콜 제어 ]

프로토콜제어 옵션은 -p이다

-p옵션의 인자는 TCP,UDP,ICMP가 될수있다.

# iptables -A INPUT -p TCP -j ACCEPT 

라는 명령을 내렸다면 tcp프로토콜을 쓰는 모든 패킷은 ACCEPT에 의해 허락될것이다.

※ -p의 인자로 TCP,UDP,ICMP의 프로토콜번호를 알고있다면 번호를 써도 상관없다.

포트 제어

포트제어 옵션은 –sport와 –dport이다

–sport는 패킷의 출발지 포트이다.( –source-port와 같은 옵션이다.)

–dport는 패킷의 도착지 포트이다.( –destination-port와 같은 옵션이다.)

# iptables -A INPUT -p tcp –dport 80 -j DROP

위와 같은 명령은 tcp프로토콜의 80(www:웹서버포트)번 포트를 목적지로 하는 패킷을
버리는 것이다.

※ –dport나 –sport의 인자로 서비스이름을 적어도 된다.
ex) –dport www

※ 여러 포트를 지정해야 된다면 –dport 1024:65535 와 같이 지정할수있다. 
뜻은 1024 부터 65535번까지라는 뜻이다.

[ 인터페이스 지정 ]

인터페이스는 -i (input interface), -o (output interface)로 지정할수있다.

# iptables -A INPUT -i eth0 -p tcp –dport 80 -j DROP

위의 명령은 -i eth0옵션을 빼고는 port지정 예와 같다.

-i eth0는 eth0로 들오는 모든 패킷을 뜻한다.

보통 리눅스 박스처럼 인터넷과 연결된 디바이스가 1개라면 필요없는 옵션이 되겠지만
만약 eth0, eth1등 2개이상의 인터페이스가 인터넷과 연결되어있다면 위의 옵션은 유용하게 쓰일것이다.

※ INPUT 체인은 -i 옵션만 쓸수 있고, OUTPUT 체인에는 -o옵션만 쓸쑤있다.
반면에 FORWARD 체인은 -i,-o 옵션 두가지 다 쓸쑤있다. 이유는 다음문서에서 다루겠다.

총괄적인 예:

# iptables -A INPUT -i eth0 -d 192.168.10.10 -p tcp –dport 80 -j DROP

해설: INPUT 체인에 – 입력인터페이스가 eth0이고 도착지가 192.168.10.10이고
프로토콜은 tcp이며 도착 포트는 80(www)인 패킷은 DROP시켜라.

이제까지는 별 다른 지식이 없이도 이해할수있는 부분이었다.
하지만 지금부터 나오게될 내용은 tcp/ip의 기반적인 지식을 가지고있어야
이해하기 쉬울것이다.
tcp/ip지식이 필요한 옵션에 대해서는 그에따른 자세한 설명을 하겠지만
이해가 되지 않는 부분은 다른 문서나 책을 찾아보길 바란다.

[ 패킷의 행동 유형에 따른 필터링(–tcp-flags,m state –state) ]

! 주의 : 밑에 나오는 모든옵션은 TCP프로토콜옵션(-p TCP)가 먼저 
선행되어 있어야 적용되는 옵션이다.

1)
–tcp-flags 옵션은 상태에 따라 유용하게 설정할수있다.
이 옵션을 설정하는 가장 큰 예는 한방향으로만 통신이 되게끔설정하기 위해
많이 사용한다. 
tcp/ip는 3핸드쉐이크의 접속방식이다.
즉. 접속요청패킷,접속허가 패킷,확인패킷

접속 단계를 좀더 자세하게 보면

C: Client S:Server

1) C ——— syn ——-▷ S
2) C ◁——- syn ack —– S
3) C ——— ack ——-▷ S

이런식으로 접속절차가 이루어진다.

syn패킷은 접속요청 플래그(syn)가 설정된 패킷이므로 syn패킷만 막으면 상대편에서 접속을 할수 없다는 것이다.

※ Dos공격의 일종인 Syn Flooding이 서버에 위에서 말한 syn형패킷을 무수히 많이
보내는 것이다.

이제 본격적으로 –tcp-flags옵션으로 syn 접속형 패킷을 막는것을 하겠다.

# iptables -A INPUT -p TCP –tcp-flags SYN,RST,ACK SYN -j DROP

–tcp-flags에 첫번째 인자는 검사할 리스트 마스크이다. 
두번째 인자는 설정되어있어야할 플래그다.
즉 syn,rst,ack플래그중 syn이 set이 1로 되어있으면 위의 –tcp-flags설정에
해당이 되므로 패킷은 DROP된다.

위의 옵션과 같은 뜻을 가진것이 있는데 그것은 –syn이다.
–syn은 ‘–tcp-flags SYN,RST,ACK SYN’의 뜻을 가지고 있다.

2)
–tcp-flags보다 더 간단하게 설정하는 방법이 있다.
바로 tcp의 상태천이 다이아그램을 축소시켜 놓은듯한 느낌을 받는 상태에 따른 패킷분류를 iptables은 지원한다.

이것은 확장기능이므로 -m 플래그로 설정은 한다.

사용옵선은 -m state –state 이다.

인자값으로 들어가야할 상태에따른 리스트는 아래와 같다.

NEW : 새로운 접속을 만드는 패킷 

ESTABLISHED :존재하는 접속에 속하는 패킷 (즉, 응답 패킷을 가졌던 것) 
즉 접속이 허가되고 통신하면서 발생되는 패킷이다. 

RELATED :기존의 접속의 부분은 아니지만 연관성을 가진 패킷으로 . 
ICMP 에러 나 (FTP 모듈이 삽입 되어있으면) ftp 데이터 
접속을 형성하는 패킷. 

INVALID :어떤 이유로 확인할 수 없는 패킷. 알려진 접속과 부합하지 않는 ICMP 에러와 
‘out of memory’ 등을 포함한다. 보통 이런 패킷은 DROP 된다. 

이제 이 state 옵션을 사용해보자

위의 –tcp-flags옵션에서 예제와 같은 작용을 하는 룰을 만들어보겠다.

# iptables -A INPUT -p TCP -m state –state NEW -j DROP

왜 룰이 이렇게 되는지 차근차근 읽어보았다면 쉽게 이해가 될것이다.

일반적으로 서버는

# iptables -A INPUT -p TCP –dport 특정포트 -m state –state NEW,ESTABLISHED -j ACCEPT

이렇게 룰을 많이 세운다.
뜻은 tcp 특정 포트에 new:접속패킷과,established:통신패킷(정확히 쉽게 설명할 
단어가 생각나지 않아 부적절하지만 통신패킷이라 부른다)을 허용하라.

그리고 클라이언트 측에서는 위의 state상태에서 NEW를 빼고 사용한다.

# iptables -A INPUT -p TCP –sport 특정포트 -m state –state ESTABLISHED -j ACCEPT

왜 NEW를 뺄까? 그 이유는 
그 이유는 클라이언트입장에서 보면 접속을 허가해달라는 패킷이 필요없다는것이다.
더 쉽게 말하자면 클라이언트는 접속허가를 요청하는 위치이지 요청받는 
위치가 아니라는 말이다.
그러므로 ESTABLISHED만 있으면 일반적으로 통신하는데 아무런 문제가 없다

그리고 주의깊게 본 사람이라면 위에 –sport가 쓰여진것을 볼수있을것이다.

왜 서버에서는 –dport로 제어를 하면서 클라이언트는 –sport로 제어를 할까?

지금 리눅스 박스라면 wget을 쓰던지 x-windows에서 브라우져를 쓰던지 아무런 웹사이트에 접속을 하고 바로 콘솔에서 ‘netstat -nat’라는 명령을 내려보자.

무슨말인지 알겠는가?

서비스를 한번이라도 해본적있는 사람이면 알겠지만 서버는 특정PORT를 열어놓고 접속을 기다린다.
클라이언트는 특정 서버에 접속을 하기 위해 별도로 포트를 생성하고 접속을 시도한다.
이때 클라이언트가 생성하는 포트번호는 1024이후의 랜덤값이다. 이런이유로 클라이언트입장에서는
–dport로 제어를 하지않는게 보통이다. 제어를 하더라도 상관없다. 하지만 그것은
상당한 비효율적인 룰이 될것이다.

[ftp를 위한 상태천이를 이용해 룰 설정]

ftp는 참 유별난 프로토콜이다. 특히 마스커레이드때 쓰이는 nat과 잘 맞지도 않을뿐더러.
ftp서버에서 passive모드로 운영을 할시 iptables로 제어하고 싶다면 따로 모듈이 필요하다.

passive로 1025:65535까지 임이의 데이타 전송포트를 쓸때 
상태천이로 제어를 하자면,보안상 NEW를 사용하지 않는다.
즉,새로운 접속을 허가하지 않고
RELATED로 기존접속에 관련된것만 접속을 허용한다.

즉 실제 룰을 보면 아래와 같다

# iptables -A INPUT -p tcp –dport 1024:65535 
-m state –state ESTABLISHED,RELATED -j ACCEPT

※ 만약 NEW를 사용한다면 방화벽 구실을 못할것이다.
왜그런지는 직접 생각해보라 위에서 이미 충분히 설명하였다.

ftp에서 위처럼 RELATED로 방화벽룰을 설정했다면 
ip_conntrack_ftp라는 모듈없이 연결이 제대로 되지 않을것이다.

ip_conntrack_ftp는 ftp서버의 ftp접속 추적 모듈이다.

[ 조각(Fragments) 처리하기 ]

때때로 하나의 패킷이 한 번에 한 회선을 통과하기에는 너무 큰 경우가 발생한다.
이 때는 패킷이 `조각’으로 나뉘어 여러 개의 패킷으로 전송된다.
받는 쪽에서는 이 조각을 모아 하나의 패킷으로 재구성한다.

패킷 필터링 HOWTO에서는 nat이나 접속추적을 할때에는 분절패킷이 하나의 패킷으로

재구성되어 필터링되기때문에 해당되지 않는다고 명시되어 있다.

하지만 위와 같은 상황이 아니라면 조각을 처리해야하나 안전성을 이유로 처리하지
않는 것을 권장하고 있다. 그 이유는 아래에 설명할것이다.

일반적으로 패킷이 분절(토막)될때 필터링을 할 정보인 특히 발신지 포트,
목적지 포트, ICMP 유형, ICMP 코드 또는 TCP SYN 플래그등은 첫번쩨 패킷의
헤더에 밖에 포함되지 않는다. 즉 두번째 분절패킷부터는 그 정보가 없다는 말이다.
이를 위해서 우리는 분절된 패킷을 처리하기 위해 -f 옵션을 사용한다.

하지만 -f옵션을 권장하지 않는다. 왜냐하면 첫번째 필터링정보가 담긴 헤더를 보고
필터링을 할때 그 패킷이 거부하는 룰에 적용되어 거부되면 분절된 패킷이 거부되지
않고 오더라도 그것은 하나의 패킷으로 재구성 되지 않고 버려지기 때문이다.

사용법은

# iptables -A OUTPUT -f -d 192.168.1.1 -j DROP

처럼 사용한다.
위의 뜻은 192.168.1.1을 항해 나가는 분절된 패킷은 모두 버린다 이다.

다시 한번 말하지만 꼭 필요한경우를 제외하고 이 옵션은 권정하지 않는다.

이정도로 iptables의 기본 사용법에 대해 마치고자 한다.
이문서에서는 방화벽설정에서 자주 사용하게 되는 옵션에 대해서만 언급했다.
아니 이정도 옵션들이면 어느정도 방화벽은 구성할수 있을것이다.
나머지 옵션들은 man패이지나 패킷필터링 HOWTO에서 찾아보기 바란다

반응형

'UNIX & LINUX > CentOS' 카테고리의 다른 글

웹 서버 상태 체크하기 #웹서버  (0) 2016.07.02
728x90

Log4j에서 LOGBack으로 마이그레이션 하기 ( migrate from log4j to logback)

몇년전 부터 프로젝트에서 로그 라이브러리로 “LOGBack“를 사용하고 있습니다.

혹시나 모르시는 분을 위해서 간략하게 설명하면 “LOGBack“은
Log4J“, “Apache Common Logging“, “Java Logging” 같은 “Logger” 라이브러리 입니다.
또한 “Log4J“를 만든 개발자가 만들어서 “Post Log4J“라고도 합니다.

보다 자세한 내용은 예전에 제가 포스팅 했던

logback을 사용해야 하는 이유 (Reasons to prefer logback over log4j)

을 참고 하시기 바랍니다.

프로젝트를 신규로 만들때는 “LOGBack” 라이브러리 와
logback.xml (log4j.xml와 비슷한 설정 파일)” 파일 두 가지만 있으면
쉽게 적용이 가능 합니다.

하지만 대부분 기존 시스템들은 “Log4J“를 이미 사용하고 있거나 또는 본인 의지와 상관 없이
3rd 라이브러리들이 내부적으로 사용하고 있는 경우 일 것입니다.
이럴 경우 몇가지 주의해야 할 사항에 대해서 말씀 드리겠습니다.

# SLF4J

마이그레이션에 대한 설명을 드리기 전에 “SLF4J“에 대한 이해가 필요 합니다.
SLF4J의 핵심은 다양한 Logger 구현체들을 추상화를 통해서 언제든지 교체 가능 할수 있도록 하는 것입니다.
즉,  “Logger Facade” 라이브러리 입니다.

concrete-bindings

(이미지 출처 : http://www.slf4j.org/images/concrete-bindings.png)

위의 그림을 보게되면 모든 “어플리케이션“은 구현체를 직접 호출하는 것이
아니라 “SLF4J API를 호출하게 됩니다.

SLF4J는 전달받은 메세지 정보를 실제 구현체로 전달 합니다.

pseudocode 코드로 표현 하면

1
2
3
4
5
6
7
8
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
...
private static final Logger LOGGER = LoggerFactory
            .getLogger(Dummy.class);
public void echo () {
   LOGGER.info("hello SLF4J");
}

어플리케이션을 개발하는 사람은 “SLF4J API를 사용하며, 여기에는 실제
구현체에 대해서 명시하지 않습니다.

이렇게 API로 랩핑하기 때문에 “Logger 구현체“를 쉽게 교체할수 있도록 합니다.

Bridge Log4J

Migration“을 가장 쉽게 하는 방법은 단지 “Log4J” 라이브러리를  제거하고 “LOGBack“라이브러리를
추가 하는 것입니다.

하지만 문제는 3rd (외부 라이브러리)가 직접 구현체 “Logger”를 호출한다는 것입니다.

pseudocode 코드로 표현 하면

1
2
3
import org.apache.log4j.Logger;
...
private static Logger logger=Logger.getLogger("LoggingExample");

직접 작성한 소스인 경우는 요새 워낙 IDE가 제공하는 “refactoring” 기능이 좋아서
금방 작업을 할 수 있지만, 외부 라이브러리 같은 경우는 “어플리케이션 제어권 밖”
이기 때문에  난처한 상황이 발생 합니다.

혹시나 해서 본인의 어플리케이션을 구동해서 에러가 없다 하더라도
논리적으로 이러한 “Issue“는 잠재적으로 발생한다는 것입니다.

저 같은 경우는 Junit을 실행할때는 문제가 없다가 전체 어플리케이션을
구동할때 “ClassNotFoundException“가 발생했던 기억이 나며, 생각보다
해당 “Issue“를 디버깅하기는 쉽지 않습니다.

제가 말씀드리고 싶은건  마이글이션시 SLF4J를 사용하던, Log4J 구현체를 사용하건
어플리케이션을 다쳐서는 안된다는 것입니다.

SLF4J“에서는 다행히 이러한 이슈를 해결하기 위해서 “extend” 라이브러리를 제공 합니다.

slf4j-with-jcl-and-log4j

(이미지 출처 : http://espenberntsen.files.wordpress.com/2010/06/slf4j-with-jcl-and-log4j.png)
log4j-over-slf4j.jar” 파일을 압축해제하면 “log4j.jar” 와
동일한 패키지, 클래스가 존재 합니다.
즉, 패키지, 클래스를 동일하게 해서 구현체 클래스를 fake하는 것입니다.

그렇게 호출된 로그정보(메세지, 로그레벨…) 는 SLF4J에게 전달하고 바인딩된
LOGBack“이 실제로 로그를 Write하는 것입니다.

Maven (pom.xml)

Migration“에서 필요한 라이브러리를 아래와 같이 추가 합니다.

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
32
33
34
35
36
37
38
...
 
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-access</artifactId>
<version>1.0.13</version>
 </dependency>
 <dependency>
<groupId>ch.qos.logback</groupId>
    <artifactId>logback-core</artifactId>
    <version>1.0.13</version>
 </dependency>
 <dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.0.13</version>
 </dependency>
 <dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.5</version>
 </dependency>
 <dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>jcl-over-slf4j</artifactId>
    <version>1.7.5</version>
 </dependency>
 <dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>log4j-over-slf4j</artifactId>
    <version>1.7.5</version>
 </dependency>
 <dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-jcl</artifactId>
    <version>1.7.5</version>
 </dependency>
...

logback.xml

logback.xml (설정 파일)”을 “classpath“경로에 생성 합니다.

이미지 2--

기본 설정을 합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
 
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoders are assigned the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
 
<root level="debug">
<appender-ref ref="STDOUT" />
 </root>
</configuration>

multiple SLF4J bindings

모든 설치/설정이 끝나고 “어플리케이션”를 구동하면 에러 없이 정상적으로 기동이 되는데
LOGBack” 설정이 안되는 경우가 있습니다.

그런 이유는 “SLF4J” 인터페이스를 구현한 구현체가 아직까지 존재하기 때문입니다.
아래 그림을 보면 SLF4J가 구동하면서 binding 대상을 scan
합니다.
내부적으로는 깊게 봐야하겠지만 현상으로 보면 여러 구현체 중에서 첫번째 것을
채택을 합니다.

이미지 3

그래서 “Log4J” 라이브러리를 혹시 참조하는 것이 있는지 확인을 하고, 혹시 있다면
exclude를 해야 합니다.

※ Log4J 관련된 라이브러리들만 exculde 해야 합니다.

라이브러리 관계 와 Exclude를 하는 것은 쉽지가 않습니다. 하지만 Eclipse에서 제공하는
Maven 플러그인을 사용하면 좀더 쉽게 수정 할 수 있습니다.

이미지 5

오른쪽 에디터에서 중복된 라이브러리를 체크 후 exclude를 하면서
왼쪽 라이브러리 path에서 빠져있는지 동시에 확인 합니다.

Migration“이 정상적으로 되었다면 아래와 같이 “LOGBack” 메세지를 확인 할수 있습니다.
이미지 6

conclusion

지금까지 “Log4J“에서 “LOGBack“로 “migration” 하는 방법에 대해서 설명 드렸습니다.
Logger 코드”는 소스 대부분에 많이 삽입이 되어 있어서 반드시 꼼꼼하게 확인이 필요하며
“과연 마이그레이션을 해야하는 것인가?”에 대한 충분한 팀 협의가 필요하고
만약 마이그레이션을 한다면 본 포스팅이 조금이나 도움이 되었으면 합니다.


반응형

'BigData > LogBack' 카테고리의 다른 글

1. logback 사용해야 하는 이유  (0) 2016.01.20
728x90

logback 사용해야 하는 이유 (Reasons to prefer logback over log4j)


출처 : https://beyondj2ee.wordpress.com/2012/11/09/logback-사용해야-하는-이유-reasons-to-prefer-logback-over-log4j/

최근 프로젝트를 진행하면서 자바 로깅 구현체(logger)로  “LOGBack“을 사용 하고 있습니다.

개발자의 얼리“적 성향이기 보다는 “log4j“에서 제공을 하지 않는기능 외에 다양한 이점이 있기 때문 입니다.
아시는 분들도 있지만, 모르시는 분들을 위해서 간략하게 말씀 드리자면

Log4j” (현재는 Apache Logging Service라는 Top Project)는  Ceki Gülcü라는
개발자가 최초로 만들었습니다.
Log4J“는 java world에서 “가장 많이 사용하고 있는 logger“라고 감히 말씀 드릴수 있습니다.

이러한 성공에 힘을 입어 “Ceki Gülcü“는 좀더 “Logger“에 대해서 깊은 프로젝트를 시작했고,
그것이 바로 “SLF4J” 와 “LOGBack” 입니다.

SLF4J“는 “로깅 구현체“라기 보다는 “Logging Facade” 입니다.
(※ facade pattern 참조)

일명 창구 일원화” 패턴인데, “SLF4J“의 API를 사용하면, 구현체의 종류와 상관없이
일관된 로깅 코드“를 작성할 수있으며,  “Apache Commons Logging“를 사용하다가
Log4J“로 변경을 할 경우 최소한의 수정으로 구현체를 교체 할수 있습니다.

오늘 설명하는 “LOGBack“은이중 하나의 “구현체” 입니다. 그래서 과연
어떤 이점이 있는지 quick 하게 둘러보고자 합니다.

해당 내용은 (Reasons to prefer logback over log4j)의 자료를 참고 했습니다.

(1) Faster implementation

LOGBack“은 새롭게 작성 한것이 아니라, 오랫동안 검증된 “LOG4J”의 아키텍쳐 기반으로
재작성 되었습니다.
특히 성능은 약 10배 정도 빠르게 개선을 했고, 또한 메모리 점유도 보다 적게 사용을 합니다.
역시 성능에 관련된 얘기 입니다.

(2) Extensive battery of tests

위에서 말씀 드렸듯 “새로운 오픈소스” 이지만 , 이미  “Log4j” 시절 부터 수년간 수 많은 광범위한 테스트
를 진행했고, 더욱더 많은 테스트의 반복 과정을 수행 했습니다.
Log4j보다 훨씬 뛰어난 가장 큰 이유중 하나“라고 합니다.
그 만큼 “높은 쿼리티“에 대한 자신감을 엿볼수 있습니다.

(3) logback-classic speaks SLF4J natively

LOGBack“은 크게 3가지 컴포넌트로 구성이 되어 있습니다.
logback-core“는 말 그대로 핵심 코어 컴포넌트 입니다.
logback-classic“은 “slf4j“에서 사용이 가능하도록 만든 플러그인 컴포넌트 입니다.
logback-access“는 사용하는 어플리케이션이 “웹 어플리케이션“일 경우 빛을 바라는
컴포넌트 입니다.” HTTP 요청에 대한 강력한 디버깅 기능을 제공 합니다.

(4) Extensive documentation

오픈소스 선택“에 있어서 레퍼런스 메뉴얼은 상당히 중요한 포인트 입니다.
LOGBack“은 지속적이면서, 상세한 메뉴얼을 제공 합니다.

(5) Configuration files in XML or Groovy

logging 설정에 대한 syntax는 기본적으로 “XML” 형태로 되어 있습니다.
또한 Groovy의 “syntax” 를 지원 합니다.

(6) Automatic reloading of configuration files

개인적으로 호감이 가는 기능중 하나 입니다. 일하는 도메인 마다 틀리겠지만
기본적으로 “운영 서버” 모드에서는 로그레벨을 “WARN” 또는 “ERROR” 입니다.

하지만 만약 운영중에 좀더 상세한 로그를 보기 원할 경우가 있습니다.
예를 들어서 “INFO” 레벨로 변경하는 경우 입니다.

log4j” 같은 경우는 다음과 같이  “서버를 셧다운 -> 재설정 -> 서버 기동” 의
절차로 진행을 합니다. 즉, 핵심 포인트는 “서버를 재기동” 해야 한다는 것입니다.

이러한 매커니즘은 “내부 스캐닝하는 별도의 쓰레드“가 감지를 하기 때문 입니다.
하지만 이런 “스캐닝 쓰레드”는 메모리에 대한 점유율을 최소화 하며,
심지어 “100개의 쓰레드가 초당 백만 invocation“을 발생해도 시스템에
크게 무리를 주지 않는 다고 합니다.

주로 이런 기능은 “WAS에서 동장하는 웹 어플리케이션“에서 많이 사용이 될듯 합니다.

(7) Graceful recovery from I/O failures

Log4j” 같은 경우  “JDBC” , “Socket“등 다양한 “Appender“를 지원 합니다.
특히. 대다수의 환경에서는 “File”에 제일 많이 로그를 저장 할 것입니다.

하지만 만약 “파일 서버가 일시적으로 장애가 발생 할경우” , “파일 서버가 복구 될때까지
어플리케이션을 중지 시켰다가” 다시 파일 서버가 복구되면, 그때 서버를 재기동 할것 입니다.
하지만 “LOGBack“은 “서버 중지 없이, 이전 시점부터 복구를 graceful “하게 지원을 합니다.

(8) Automatic removal of old log archives

대부분 환경에서는 “하나의 파일”에 기록하는 것이 아니고, “특정 시간” 또는 “특정 파일 사이즈
로 “Rolling” 해서 “Archiving“을 할 것입니다.

하지만 “Archiving된 로그 파일“을 계속 유지하지 않고, 일정 기간 지나면
서비스에  부담을 주지 않기 위해서” 파일을 삭제 할것 입니다.

이럴경우 “Crontab” 또는 다른 삭제 스케줄러를 설정 또는 개발을 할것입니다.
LOGBack“은 “maxHistory“라는 설정 정보를 통해서 주기적으로 “Archive
파일을 자동 삭제 합니다.
maxHistory“의 값이 “12“일 경우, “12개월 이후 삭제 하라는” 뜻입니다.

(9) Automatic compression of archived log files

Archived Log File“를 만들때 비동기적으로 롤링 할 동안
자동 압축을 실행 합니다. 심지어 파일 용량이 커도, 또한
이러한 압축 작업은 어플리케이션을 block 시키지 않습니다.

(10) Prudent mode

만약 하나의 서버에서 “다수의 JVM“이 기동중일 경우 “하나의 파일“에
로그를 수집하려고 할때 사용하는 기능 입니다.

즉, “Log Aggregation” 기능 입니다. 조금만 아이디어를 내면, 매우 유용하게
사용이 가능 합니다.
다만 서로 쓰레드간 writing 할때 경합이 생기기 때문에 대량의 데이터를 사용할때
는 다소 피해야 합니다.

그렇기 때문에 반드시 해당 옵션을 적용시 “LOGBack” 메뉴얼을 참고 하시기 바랍니다.

(11) Lilith

Lilith“은 “현재 발생하는 로그 이벤트에 대한 상태 정보를 볼수 있도록 지원 하는 
뷰어” 입니다.
log4j“를 지원하는 “chainsaw” 와 비슷한 기능을 합니다. 다만 차이점은 “Lilith
Large data“를 지원 합니다.

(12) Conditional processing of configuration files

빌드를 해본 사람이라면 아실듯 합니다. 빌드시 제일 골치가 아픈 것이 “config” 정보 와
log file path” 입니다.
이유는 어플리케이션이 구동하는 환경이 “로컬, staging, cbt” 마다 틀리기 때문 입니다.
이런점을 해결 하기 위해서 “Maven Filter” 기능을 사용 하거나,  “JVM -D환경변수“를
통해서 각 환경 마다 선택적으로 “log 설정파일“을 선택하도록 구성을 할 것입니다.

LOGBack“은 이런 이슈를 좀더 “Graceful“하게 지원을 합니다.
JSTL” 같이 분기 스크립트 (<if><then> and <else>)를 제공해서 하나의 파일
에서 다양한 빌드 환경을 제공 하도록 지원을 합니다.

(13) Filters

Filter” 기능은 “Log4j“에서 지원하는 기능입니다. 주 기능은 “로깅을 남길지 , 말지를”
핸드링 할수 있는 기능 입니다.
좀더 이해를 돕기 위해서 “UseCase“를 설명 드리겠습니다.

만약 “A“라는 사용자에게 비즈니스적으로 문제점이 발견이 되었습니다.
이럴경우는 “logical exception“이기 때문에 원인을 잡기가 쉽지가 않습니다.
또한 현재 “운영 서버“의 “Log LEVEL“이 “ERROR“일 경우 로그를 확인 할수가 없을
것입니다.
더우기 “운영 서버 logical exception“은 “staging” 환경과 데이터가 틀리기 때문에
실제 운영 로그를 확인하지 않고서는 재현을 할수가 없습니다.

그래서 “운영 서버의 로그 레벨“을   “DEBUG“로 수정합니다. 하지만 로그는 보이지만 전체 사용자가
해당이 되기 때문에 로그 데이터를 분석하기가 어렵습니다.
이럴 경우 “Filter“를 사용해서 “다른 사용자“는 “ERROR” 레벨을 유지하고,
“A” 사용자만 “DEBUG“로 설정을 하면, 분석하는데 많은 도움을 받을 수 있습니다.

(14) SiftingAppender

SiftingAppender“는 “Filter“의 기능과 유사하면서 다른 기능을 제공 합니다.
로그 파일을 특정 주제별로 분류“를 할 수 있도록 합니다.
예를 들어서 “HTTP Session“별로 로그 파일을 저장한다거나, “사용자별“로 별도의 로그파일을
저장 할 수 있습니다.

(15) Stack traces with packaging data

자바 어플리케이션에서 “Exception“이 발생을 하면 “Stack Trace“를 출력을 합니다.
자바는 “Exception” 정의가 잘되어 있어서 쉽게 “디버깅“을 할 수 있습니다.

하지만 제일 디버깅이 힘든 것중 하나가 “라이브러리에 의한 Exception” 입니다.
이럴 경우 “LOGBack“은 Exception 발생시 참조 했던 외부 라이브러리 버전을
출력하게 해줍니다.

(16) Logback-access, i.e. HTTP-access logging with brains, is an integral part of logback

위에서 언급했듯이 “logback-access“는 “웹 어플리케이션” 사용시 유용한 툴로써 제공 됩니다.
특히나 요새는 전통적인 “HTML” 출력이 아닌 “REST 서버“로써의 역할을 많이 합니다.
이럴 경우 “HTTP 디버깅“을 제공 합니다.

Conclusion

지금 까지 간략하게 “LOGBack” 기능을 살펴 봤습니다.
이외에 유용하고, 멋진 기능들이 많이 있습니다.

logging“의 중요함은 지나치게 말씀을 드려도 지나치지 않습니다.
특히나 “클라우드 빅데이터” 시대에서 “logger“는 바로 최초 시작점 입니다.

제일 궁금했던 것이 “log4j를 만든 사람이 왜 ? logback를 만들었을까?” 입니다.

개인적 생각은 “log4j“를 “하위 호환성을 유지하면서 큰 리팩토링을 하기에는 다소 부담감
과 “상용 버전을 위한 비즈니스적 관점“이 아닐까 조심 스럽게 말씀 드리고 싶습니다.

LOGBack“의 큰 매력은 “Log4J 와 상당히 친숙함” 일것입니다. 이말은 그 만큼 사용하는데
있어서 낯설지 않다는 얘기 입니다.
심지어 “log4j.properties“를 “logback.xml” 설정 파일로 변환하는 “웹 변환기“도 제공 합니다.

또한 “SLF4J“를 지원하기 때문에 마음에 들지 않으면 “언제든지 다른 로거로 swiching“이 가능 합니다.


반응형
728x90

1. 계정의 테이블 스페이스 생성

create tablespace [tablespace_name] 
datafile '/home/oracle/oradata/DANBEE/[file_name].dbf' size 500m;

예)
CREATE TABLESPACE ADMIN DATAFILE 'D:\ORACLE\ORADATA\XE\ADMIN.dbf' SIZE  500M ;


2. 오라클 유저 만들기

CREATE USER [user_name] 
IDENTIFIED BY [password]
DEFAULT TABLESPACE [tablespace_name]
TEMPORARY TABLESPACE TEMP;

예)
CREATE USER nextree IDENTIFIED BY nextree DEFAULT TABLESPACE NEXTREE TEMPORARY TABLESPACE TEMP;


3. 생성한 USER에 권한주기

GRANT connect, resource, dba TO [user_name];

예)
grant connect, dba, resource to 유저명; (모든 권한 주기)

GRANT CREATE SESSION TO 유저명         // 데이터베이스에 접근할 수 있는 권한
GRANT CREATE DATABASE LINK TO 유저명
GRANT CREATE MATERIALIZED VIEW TO 유저명
GRANT CREATE PROCEDURE TO 유저명
GRANT CREATE PUBLIC SYNONYM TO 유저명
GRANT CREATE ROLE TO 유저명
GRANT CREATE SEQUENCE TO 유저명
GRANT CREATE SYNONYM TO 유저명
GRANT CREATE TABLE TO 유저명             // 테이블을 생성할 수 있는 권한
GRANT DROP ANY TABLE TO 유저명         // 테이블을 제거할 수 있는 권한
GRANT CREATE TRIGGER TO 유저명 
GRANT CREATE TYPE TO 유저명 
GRANT CREATE VIEW TO 유저명

GRANT  
 CREATE SESSION
,CREATE TABLE
,CREATE SEQUENCE   
,CREATE VIEW
TO 유저명;

4. 생성한 USER로 ORACLE에 접속하기

sqlplus nextree/nextree[@db_sid]


5. 계정 삭제하기

drop user 사용자계정 cascade;

-- 테이블 스페이스 크기 확장해주는 쿼리문
alter database 
datafile 'D:\oracle\oradata\XE\ADMIN.DBF'  resize 900M;

--테이블 스페이스 정보 보는 쿼리문 
SELECT file_name, tablespace_name, bytes, status FROM  DBA_DATA_FILES;

--테이블 명시적 인덱스 생성
--1번째 방법
CREATE INDEX MSID_IDX1 ON TEST(MSID)
--2번째 방법
create index test1_test on test1(test) 
tablespace users 
storage 

initial 10k 
next     10k 
pctincrease 0) 
pctfree 10

--테이블 정보 보는 쿼리
select * from user_constraints-- where table_name = upper('test1');

--ORA-00054: 자원이 사용중이고, NOWAIT가 지정되어 있습니다 해결 방법 
select a.sid, a.serial# 
from v$session a, v$lock b, dba_objects c 
where a.sid=b.sid and 
b.id1=c.object_id and 
b.type='TM' and 
c.object_name='CAR_INFO';

alter system kill session '12, 27846';

-- CAR_INFO에는 있는 값을 DASH_BOARD에 넣기
INSERT INTO DASH_BOARD(CAR_LICEN_NUM)
SELECT CAR_LICEN_NUM FROM CAR_INFO
MINUS
SELECT CAR_LICEN_NUM FROM DASH_BOARD


SYSTEM 계정 패스워드 변경하기
사용자계정 : /as sysdba

alter user system identified by "암호";
일반 스트링은 관계없지만 특수문자가 있을경우 반드시 "" 따옴표로 감싸준다.


반응형
728x90

IBM JVM 튜닝 - 1

JVM 구조

IBM JVM 구성하는각각의 Component structure 아래와 같이 나뉜다.

 

 영역의 주요 기능은 아래와 같이 요약된다.

 

구분

기능

JVM API

JVM External program 사이의 상호작용에 관여

Diagnostics

JVM 기능에 편리성과 유용성(RAS) 제공

Memory

management

Java application 의한 System memory 효율적인 사용에 관여함

Class loader

Java code 동적 로딩의 편리성 제공

Interpreter

Stack-base bytecode 해석에 관여함

Platform

port layer

다양한 운영시스템에서 JVM native function 사용할  있도록하는 기능제공

[ 1] IBM JVM 구성 요소 설명

 

 

여기서 우리는 ‘Memory management’  중점적으로 다뤄본다.


JIT 컴파일러

흔히, IBM JVM JIT계열의 JVM이라고 표현한다.

JIT 흔히 Just-In-Time 약자로 알려져 있으며이는 JVM  part라기 보다는, SDK 기본 구성요소로 생각하는 것이 맞다.

 

Java Interpreter 언어이고이는 소스가 bytecode 컴파일 되고실행되기 위해서는 다시금 system code 해석되어 수행되어야 하는, performance적인 저하요소를 극복하기 위해 자주 수행되는 Java method 대상으로 미리 system code해석해서, Method call되면 컴파일 과정 없이 바로 서비스를 하는 방식으로 작동한다.

 

 이런 JIT 컴파일러가 때때로 Runtime 문제점이 발생하는 경우는아래의 방법으로 JIT 옵션을 꺼둘 수도 있다.

 

구분

설명

Unix 환경변수 제어방법

Korn  : export JAVA_COMPILER=NONE

Bourne  : JAVA_COMPILER=NONE

export JAVA_COMPILER

 : setenv JAVA_COMPILER NONE

JVM Option 1

-Djava.compiler=NONE

JVM Option 2

-Xint

[ 2] JIT 컴파일러 비활성화

 

 

아래와 같이 JIT 옵션을  수도 있다.

 

구분

설명

Unix 환경변수 제어방법

Korn  : exprt JAVA_COMPILER=jitc

Bourne  : JAVA_COMPILER=jitc

export JAVA_COMPILER

 : setenv JAVA_COMPILER jitc

JVM Option 1

-Djava.compiler=jitc

JVM Option 2

-Xjit

[ 3] JIT 컴파일러 활성화


Garbage Collector

Sun HotSpot 계열의 JVM ‘New/Old/Permanent’등의 세대(Generation)’ 불리는 영역으로 분리된 Heap구조를 가진다.

이에 반해, IBM JVM 영역이 따로 분리되지 않은 하나의 ‘Single Space’ Heap 구성되어 있다.

 

heapbase

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

heaplimit

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

heaptop

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

참고로, IBM JDK 1.5부터는 아래와 같이 세대(Generation)’기반의 Heap 구조를 지원한다.

(GC 알고리즘이 Concurrent Generational Collector  경우의 Heap 구조임)


  

 영역이 어떤 식으로 Garbage Collector 의해 사용되는지 설명하기 위해서,

‘Generational Concurrent Garbage Collection’ 알고리즘에 대해 잠깐 언급하도록 한다.

 

JVM Logic 처리하는 동안새로운 Object들은 당연히 ‘Nursery’영역에 생기게 된다만일새로운 Object 할당되는데 필요한 연속된 메모리 영역 부족하게 되면객체는 ‘Tenured’영역으로 옮겨지게 된다또한, Garbage collection 발생시 옮겨지기도 한다.

 

Nursery 영역은 ‘Allocate Space’ ‘Survivor Space’ 나뉘게 된다.

Object 최초 Allocate Space 생기게 된다만일, Space 부족하게 되는 경우,

Allocation Failure 발생되면 Garbage Collector 작동되고, Scavenge 시작된다.

Scavenge 진행되는 동안, reference 살아있는 Object들은 ‘Survivor Space’ 이동되고이때 reference 없는Object들은 건들지 않는다.

Reference 살아있는 Object들의 이동작업이  끝나게 되면, ‘Allocate Space’ ‘Survivor Space’  역할을 순간적을 바꾸게 된다.

 

이때기존의 reference 없는 Object들은 순간적으로 비워지게 된다그리고다음 Scavenge 발생할  까지는‘Survivor Space’ Object 위한 Allocate 공간 업무를 수행하게 된다.

 


JVM 주요 옵션 소개

GC command-line options

-verbose:gc

garbage collection  정보를 standard out 으로 출력한다.

 

-Xverbosegclog:<file, X, Y>

garbage collection  정보를 파일로 출력한다만약 integer X Y 값을 명시하면 output Y GC Cycle output 포함하는 X 파일로 재지정된다.

) -Xverbosegclog:/user/logs/gclog/gclog.log //로그 경로 설정

 

-Xgcpolicy: <optthruput | optavgpause | gencon | subpool>

 option garbage collector 행동을 제어한다.

-. optthruput

concurrent mark 비활성화 한다만약 application response time 문제가 없다면  option 사용하여 최적의throughput   있다. Optthruput default 값이다.

-. optavgpause

concurrent mark 활성화 한다만약 일반적인 garbage collections  의해 application response time 문제가 있다면 option 사용함으로 문제를 줄일  있다.

-. gencon

Concurrent generational GC 겸용하여 사용함으로 garbage collection 지체 시간을 최소화   있다.

-. subpool

concurrent mark 비활성화 한다이것은 heap 객체들을 배치할   나은 성능을 내기 위해 향상된 object allocation알고리즘을 사용한다 option 16 이상의 processor SMP system에서 실행되며, subpool option AIX, Linux PPC  zSeries, z/OS, i5/OS 에서 가능하다.

 

-Xmx<value>

최대 heap size 지정한다. (Xmx >= Xms)

-Xmx256m // 최대 heap size 256mb  지정한다.


-Xms<value>

최소 heap size 지정한다 Xmo 또한 사용할  있다최소 size 8KB이다.

scavenger  활성화 되어 있을 경우, -Xms >= -Xmn + -Xmo

scavenger  비활성화 되어 있을 경우, -Xms >= -Xmo

-Xms256m // 최소 heap size 256mb  지정한다.


-Xcompactgc

모든 garbage collections(system 또는 global)  대하여 압축을 가능하게 한다.


-Xnocompactexplicitgc

System.gc() 호출에 의한 압축을 불가능하게 한다압축은 만약 –Xcompactgc 명시하거나 또는 compaction triggers 만나면 global garbage collections 에서 발생한다.


-Xcompactexplicitgc          

System.gc() 호출  때마다 모든 GC 시스템에서 압축을 사용 가능하게 한다.


-Xnocompactgc

모든 garbage collections(system 또는 global)  대하여 압축을 사용 불가능하게 한다.


-Xnoclassgc

Class garbage collection  비활성화 한다. JVM 의해서  이상 사용되지 않는 Java class 들과 연관된 storagegarbage collection 끈다 dynamic 클래스 로드 해제를 사용 불가능하게 한다.


-Xclassgc

dynamic 클래스 로드 해제를 사용 가능하게 한다.


-Xalwaysclassgc

global collection 동안 항상 dynamic class load 해제를 수행한다. Default  -Xclassgc  의해 정의된다.

 

-Xmaxf<percentage>

garbage collection  free 되어야 하는 heap 최대 percentage 지정한다만약 free 영역이  값을 초과하면 JVMheap 줄이기 위해 시도한다. Default 0.6(60%) 이다.


-Xminf<percentage>

garbage collection이후 free되어야 하는 heap 최소 percentage 지정한다만약 free영역  값에  미치는 경우 JVM heap 확장하기 위해 시도한다. Default 30%이다.


-Xgcthreads<number>

Garbage Collector  thread 수를 지정한다. Default 물리적인 CPU 수로 지정된다다른 수로 지정하기 위해 (예를 들어 4)  -Xgcthreads4  표기한다.

 

Nonstandard command-line options

-Xss<size>

모든 Java thread 최대 stack size 지정한다. Default 32bit JVM에서 256KB, 64bit JVM에서 512KB 이다.


-Xmso<size>

OS thread stack size 지정한다 

JIT command-line options

-Xint

JVM JIT 사용불가하고, Interpreter 로만 사용한다.


-Xquickstart

최적화를 지연하여 시작 시간을 향상시킨다. 


 분석 기술

GC 알고리즘의 이해

IBM JDK에서는 아래와 같이 주요 4가지 Garbage Collection 옵션을 제공한다.

이들은 아래와 같은 방법으로 설정이 가능하다.

-Xgcpolicy

여기에 설정할  있는 옵션은 다음과 같다.

optthruput GC 알고리즘 설명

구분

설명

옵션 

-Xgcpolicy:optthruput

설명

 옵션은 default GC 알고리즘 이다.

특징으로는작동  일시적으로 정지하는 현상이 발생한다는 점이다.

Object할당을 시도할 , Allocation Failure 발생하게 되면, Garbage Collector reference 끊긴 Object 수집하여 삭제하게 된다.

이때필연적으로 JVM Lock 걸리면서 멈추는 현상이 발생하게 된다.

Application 복잡해지고그에 따라 Heap 커지게 되면역시 GC발생시 멈추게 되는 시간도 증가하게 된다.

장점

Throughput 향상될  있다.
(General GC, Disable concurrent mark)

단점

작동  일시적으로 정지하는 현상이 발생한다.

 

optavgpause GC 알고리즘 설명

구분

설명

옵션 

-Xgcpolicy:optavgpause

설명

위에서 설명한 ‘optthruput’ GC 알고리즘의 단점인 ‘JVM 정지시간 보완하기위한 GC 알고리즘  하나이다.

이는, Application 수행   , Garbage Collection 위한 Thread추가적으로 생성하고 기동시켜서, reference 끊긴 Object들에 대한 scavenge작업을 수행시켜서실제 Garbage Collector 수행될 전체 Heap영역에 대한 Object선별작업을 수행할 필요 없이 reference 끊긴 Object들만을 수거해  있도록 돕는다.

장점

전반적인 응답속도(Response Time) 향상하는 효과를 가져올  있다.

(Enables concurrent mark)

단점

Concurrent Thread 기동에 의한실제 Application 수행에 있어서의

Throughput 감소한다.

 

gencon GC 알고리즘 설명

구분

설명

옵션 

-Xgcpolicy:gencon

설명

해당 옵션이 설정되면, JVM 할당된 Heap 세대(Generation)’기준으로 분류한다이는 위에서 살펴보았듯이, ‘Nursery Space’ ‘Tenured Space’ 말한다.

JVM Logic 처리하는 동안새로운 Object들은 당연히 Nursery’영역에 생기게된다만일새로운 Object 할당되는데 필요한 연속된 메모리 영역이

부족하게 되면 객체는 Tenured 영역으로 옮겨지게 된다.

또한, Garbage collection 발생시 옮겨지기도 한다.

Nursery 영역은 Allocate Space’와 Survivor Space 나뉘게 된다.

Object 최초 Allocate Space 생기게 된다만일, Space 부족하게 되는경우, Allocation Failure 발생되면, Garbage Collector 작동되고, Scavenge 시작된다.

Scavenge 진행되는 동안 reference 살아있는 Object들은 SurvivorSpace 이동되고이때 reference 없는 Object들은 건들지 않는다.

Reference 살아있는 Object들의 이동작업이  끝나게 되면, Allocate Space Survivor Space   역할을 순간적을 바꾸게 된다.

이때기존의 reference 없는 Object들은 순간적으로 비워지게 된다그리고 다음 Scavenge 발생할  까지는 Survivor Space Object 위한 Allocate공간 업무를 수행하게 된다.

장점

전반적인 응답속도(Response Time), Throughput 동시에 평균적으로 향상하는효과를 가져올  있다.
(Enable concurrent mark + General GC)

단점

CPU overhead 상대적으로 발생할  있다.

 

subpool GC 알고리즘 설명

구분

설명

옵션 

-Xgcpolicy:subpool

설명

Heap 공간을 다수의 sub pool 할당하여 Object 관리하는 기법이다.

여기에 LOA(Large Object Area) SOA(Small Object Area) 개념이 들어간다.

장점

상대적으로 높은 성능을 발휘한다.

단점

16 CPU 이상의  사양 서버 환경에서 사용해야 한다.

또한, AIX, z/OS, Linux PPC  특정 플랫폼에서만 사용할  있다.

 

GC Dump 이해

앞에서, GC 알고리즘에 대해 개략적으로 살펴보았다.

여기서는로그가 실제 어떤 식으로 생성되는지 간략한 예를 살펴보도록 한다.

아래는실제로 JEUS 각각의 GC 알고리즘을 적용시켜 생성한 Dump이다.

 

–Xgcpolicy:optthruput GC dump

<af type="tenured" id="4" timestamp="  2 28 10:16:42 2008" intervalms="432.499">

  <minimum requested_bytes="33562648" />

  <time exclusiveaccessms="0.140" />

  <tenured freebytes="158830512" totalbytes="536870912" percent="29" >

    <soa freebytes="136268104" totalbytes="493921280" percent="27" />

    <loa freebytes="22562408" totalbytes="42949632" percent="52" />

  </tenured>

  <gc type="global" id="5" totalid="5" intervalms="434.640">

    <compaction movecount="450409" movebytes="69221728" reason="heap fragmented" />

    <refs_cleared soft="0" threshold="32" weak="0" phantom="0" />

    <finalization objectsqueued="0" />

    <timesms mark="72.584" sweep="5.045" compact="130.030" total="207.766" />

    <tenured freebytes="340455528" totalbytes="536870912" percent="63" >

      <soa freebytes="292138088" totalbytes="488553472" percent="59" />

      <loa freebytes="48317440" totalbytes="48317440" percent="100" />

    </tenured>

  </gc>

  <tenured freebytes="306892880" totalbytes="536870912" percent="57" >

    <soa freebytes="258575440" totalbytes="488553472" percent="52" />

    <loa freebytes="48317440" totalbytes="48317440" percent="100" />

  </tenured>

  <time totalms="208.154" />

</af>

로그 패턴을 보면, Allocation Failure 발생하였고, GC 거쳐 Tenured영역의 Free Space 57% 증가했음을  있다. 

–Xgcpolicy:optavgpause GC dump

<af type="tenured" id="40" timestamp="  2 28 10:17:02 2008" intervalms="223.402">

  <minimum requested_bytes="37748760" />

  <time exclusiveaccessms="36.573" />

  <tenured freebytes="28931592" totalbytes="1073741824" percent="2" >

    <soa freebytes="28931592" totalbytes="1073741824" percent="2" />

    <loa freebytes="0" totalbytes="0" percent="0" />

  </tenured>

  <gc type="global" id="42" totalid="42" intervalms="223.577">

    <refs_cleared soft="0" threshold="32" weak="0" phantom="0" />

    <finalization objectsqueued="0" />

    <timesms mark="28.562" sweep="3.428" compact="0.000" total="32.092" />

    <tenured freebytes="211487536" totalbytes="1073741824" percent="19" >

      <soa freebytes="211487536" totalbytes="1073741824" percent="19" />

      <loa freebytes="0" totalbytes="0" percent="0" />

    </tenured>

  </gc>

  <tenured freebytes="173738776" totalbytes="1073741824" percent="16" >

    <soa freebytes="173738776" totalbytes="1073741824" percent="16" />

    <loa freebytes="0" totalbytes="0" percent="0" />

  </tenured>

  <time totalms="68.845" />

</af>

 
–Xgcpolicy:gencon GC dump

<af type="tenured" id="154" timestamp="  2 29 09:57:50 2008" intervalms="452.265">

  <minimum requested_bytes="37748760" />

  <time exclusiveaccessms="2.137" />

  <nursery freebytes="33161216" totalbytes="33554432" percent="98" />

  <tenured freebytes="242872304" totalbytes="1006632960" percent="24" >

    <soa freebytes="211147296" totalbytes="956301312" percent="22" />

    <loa freebytes="31725008" totalbytes="50331648" percent="63" />

  </tenured>

  <gc type="global" id="226" totalid="1071" intervalms="452.406">

    <refs_cleared soft="0" threshold="32" weak="0" phantom="0" />

    <finalization objectsqueued="8" />

    <timesms mark="26.053" sweep="3.163" compact="0.000" total="29.278" />

    <nursery freebytes="33494840" totalbytes="33554432" percent="99" />

    <tenured freebytes="470984032" totalbytes="1006632960" percent="46" >

      <soa freebytes="439259024" totalbytes="946235392" percent="46" />

      <loa freebytes="31725008" totalbytes="60397568" percent="52" />

    </tenured>

  </gc>

  <nursery freebytes="33494840" totalbytes="33554432" percent="99" />

  <tenured freebytes="433235272" totalbytes="1006632960" percent="43" >

    <soa freebytes="401510264" totalbytes="946235392" percent="42" />

    <loa freebytes="31725008" totalbytes="60397568" percent="52" />

  </tenured>

  <time totalms="31.585" />

</af>

 

<af type="nursery" id="881" timestamp="  2 29 09:57:50 2008" intervalms="285.580">

  <minimum requested_bytes="37748760" />

  <time exclusiveaccessms="0.110" />

  <nursery freebytes="31100848" totalbytes="33554432" percent="92" />

  <tenured freebytes="433235272" totalbytes="1006632960" percent="43" >

    <soa freebytes="401510264" totalbytes="946235392" percent="42" />

    <loa freebytes="31725008" totalbytes="60397568" percent="52" />

  </tenured>

  <gc type="scavenger" id="846" totalid="1072" intervalms="285.732">

    <flipped objectcount="3460" bytes="171648" />

    <tenured objectcount="0" bytes="0" />

    <refs_cleared soft="0" weak="0" phantom="0" />

    <finalization objectsqueued="0" />

    <scavenger tiltratio="50" />

    <nursery freebytes="33013736" totalbytes="33554432" percent="98" tenureage="3" />

    <tenured freebytes="433235272" totalbytes="1006632960" percent="43" >

      <soa freebytes="401510264" totalbytes="946235392" percent="42" />

      <loa freebytes="31725008" totalbytes="60397568" percent="52" />

    </tenured>

    <time totalms="3.648" />

  </gc>

  <nursery freebytes="33013736" totalbytes="33554432" percent="98" />

  <tenured freebytes="433235272" totalbytes="1006632960" percent="43" >

    <soa freebytes="401510264" totalbytes="946235392" percent="42" />

    <loa freebytes="31725008" totalbytes="60397568" percent="52" />

  </tenured>

  <time totalms="3.923" />

</af>

  

–Xgcpolicy:subpool GC dump

<sys id="1" timestamp="  2 29 10:03:16 2008" intervalms="0.000">

  <time exclusiveaccessms="0.048" />

  <tenured freebytes="373520640" totalbytes="536870912" percent="69" />

  <gc type="global" id="1" totalid="1" intervalms="0.000">

    <classloadersunloaded count="0" timetakenms="0.973" />

    <refs_cleared soft="73" threshold="32" weak="127" phantom="4" />

    <finalization objectsqueued="21" />

    <timesms mark="56.218" sweep="5.343" compact="0.000" total="62.748" />

    <tenured freebytes="491131504" totalbytes="536870912" percent="91" />

  </gc>

  <tenured freebytes="491131504" totalbytes="536870912" percent="91" />

  <time totalms="63.282" />

</sys>

 

Subpool CPU 16 이상인 환경에서 최적화 되어있다고 앞서 말했다.

종종 System Capacity 부족한 환경에서는 아래와 같은 로그가 목격되기도 한다.

Module=/usr/java5_64/jre/bin/libj9gc23.so

Module_base_address=0900000001046000

Target=2_30_20071004_14218_BHdSMr (AIX 5.3)

CPU=ppc64 (4 logical CPUs) (0x1f0000000 RAM)

 

위의 로그와 비슷하게, System.gc() 명시적으로 호출된 경우는 아래와 같은 GC Dump 발생한다.

<sys id="1" timestamp="  2 29 10:03:16 2008" intervalms="0.000">

  <time exclusiveaccessms="0.048" />

  <tenured freebytes="373520640" totalbytes="536870912" percent="69" />

  <gc type="global" id="1" totalid="1" intervalms="0.000">

    <classloadersunloaded count="0" timetakenms="0.973" />

    <refs_cleared soft="73" threshold="32" weak="127" phantom="4" />

    <finalization objectsqueued="21" />

    <timesms mark="56.218" sweep="5.343" compact="0.000" total="62.748" />

    <tenured freebytes="491131504" totalbytes="536870912" percent="91" />

  </gc>

  <tenured freebytes="491131504" totalbytes="536870912" percent="91" />

  <time totalms="63.282" />

</sys>


Java Thread Dump 분석

Java Thread Dump특정 Java Process 대한 청사진이라 해석될  있다.

IBM 플랫폼에서 Java Thread Dump text형태로 생성된다.

이를직접 열어서 내용을 Trace하는 것도 가능하지만여기서는 Visual Tool 이용한 분석법을 소개한다.

 

JCA 이용한 Java Thread Dump 분석

1. 다운로드 : http://www.alphaworks.ibm.com/tech/jca (파일명:jca*.zip)

2. 실행화면

 

 3. 설명

실제 javacore덤프를 분석한 화면이다.

덤프 생성 당시가용한 메모리가 없었다는 경고와 함께, Worker Thread  하나가

Running 상태였다는 정보를 쉽게   있다.

이와 같이, Worker Thread 상태정보  Heap Memory Usage정보, Thread Monitor 상태정보(dead lock)등의 정보에쉽게 접근이 가능하다.


Java Heap Dump 분석

Java Heap Dump특정 Java Process allocation 되었던 Heap Memory 대한 청사진이라   있다.

IBM 플랫폼에서는 text형태혹은 phd(Portable Heap Dump)포맷으로 생성된다.

Heap Dump 분석에는 주로 아래와 같은 방법이 사용된다.

구분

설명

URL

Text기반

HeapRoots (HR*.jar)

http://www.alphaworks.ibm.com/tech/heaproots/download

Svcdump (svcdump.jar)

http://www-1.ibm.com/support/docview.wss?rs=180&uid=swg21190476

GUI 기반

HeapAnalyzer (ha*.jar)

http://www.alphaworks.ibm.com/tech/heapanalyzer/download

 

여기서는 GUI기반의 HeapAnalyzer 소개한다.

HeapAnalyzer 이용한 Java Heap Dump 분석

1. 실행화면 


2. 
설명

실제 Heap Dump 분석한 화면이다.

Heap Dump 생성 당시의 Memory allocation 대한 Stack정보를 계층구조로 보여주고 있어서, Memory 누수 라던지OOM(Out Of Memory)상황이 발생하였을 경우 원인파악에 매우 도움이 되는 화면을 제공한다.

(*주의: Heap Dump Size 매우  경우는서버의 X-Window환경에서 작업하도록 한다통상적인 Heap Dump 분석에는 많은 Memory 필요하기 때문이다.)


GC Dump 분석

GC Dump 분석이란, -verbose:gc –Xverbosegelog:logname.log  결과로 생성된 GC log파일을 분석하는 것을 말한다.

 역시, script 이용하는 방법과 command-line 이용한 명령어 사용방법 등이 있는데여기서는 역시 GUI 기반의 툴인‘GCCollector’ 이용하는 방법을 소개한다.

 

GCCollector 이용한 GC Dump 분석

1. 다운로드: GCCollector 실행하기 위해서는 JFreeChart  다운받아야 한다.           

구분

URL

GCCollector

http://www.alphaworks.ibm.com/tech/gcdiag/download (파일:GCCollector.zip)

JFreeChart

http://www.jfree.org/jfreechart/index.html

 

2. GCCollector 실행파일에 오류가 발생할 경우 아래와 같이 작성한다.

javaw -Xmx300m –classpath lib/GCCollector.jar;lib/jfreechart-1.0.0-rc1.jar;lib/jcommon-1.0.0-rc1.jar it.imperato.jvmperf.GCCollector

3. 실행화면

 

4. 설명

실제 GC Dump 분석한 화면이다. (-Xgcpolicy:optthruput or –Xgcpolicy:optavgpause)

GCCollector 통해 판단할  있는 항목은 아래와 같다.

l     GC Interval

l     GC Duration (Mark, Sweep, Compact, Total)

l     Allocation Failure: 실제 Garbage Collector 작동된 count 같다고 생각하면 된다.


이럴  이렇게

표준 설정 옵션

표준 옵션

-Xms512m -Xmx1024m

-verbose:gc   

-Xverbosegclog:/user/logs/gclog/gclog.log

전체적인 GC Time 너무 길고, Response Time 너무 나오지 않습니다.

상황

GC 수행시간 그래프를 보면수행시간이 오래 걸리는 GC들의 peak 자주 목격됩니다.

Response Time 역시 너무  나옵니다.

조치

대부분, GC 있어서 Full heap collection 혹은 compaction 소요되는 시간이 너무  경우 발생할  있습니다.

 경우, -Xgcpolicy:optavgpause 옵션을 적용하면, concurrent 하게 heap collection 발생하게 되고, GC 따른 pause시간이 감소하여전체적인 Response Time 향상을 기대할  있습니다.

적용 옵션

-Xgcpolicy:optavgpause

Throughput 너무 적게 나옵니다.

상황

CPU  Memory등의 capacity 좋은 장비임에도 불구하고, WAS 서비스의 전체적인

Throughput 너무 나오지 않습니다.

조치

 경우, -Xgcpolicy:optthruput 옵션을 적용하면, concurrent  mark&sweep 작업을 막음으로써대부분의 ThreadBusiness Service 수행하는데 사용되도록 유도하여 전체적인 Throughput 향상시키는데 도움이   있습니다.

만일, CPU 16 이상인  사양 환경의 경우 –Xgcpolicy:subpool 옵션이 좀더 효과적인 성능을 발휘   있습니다.

 

적용 옵션

일반적인 경우 : -Xgcpolicy:optthruput

16 이상의 CPU 환경 : -Xgcpolicy:subpool

Garbage Collection 너무 자주 발생합니다.

상황

GC Interval 매우 좁게 나타나며, GC count 너무 높게 나옵니다.

조치

Application 특성에 비해 Heap Size 너무 작게 설정되어 있을  있습니다.

또한 경우 –Xgcpolicy:optthruput 옵션이 도움이   있습니다.

적용 옵션

-Xmx 늘림

-Xgcpolicy:optthruput

설정된 Heap Size 실제 사용량의 차이가 너무 심하게 납니다.

상황

실제 WAS JVM 할당한 Heap Size 사용되는 Heap Size 등락폭이 너무 심하게 자주 바뀝니다.

조치

Heap Size 너무 크게 설정되어 있을  있습니다.

Heap Size 줄이고, Generation Heap Space 설정된 경우 ‘Nursery’영역의 Size 좀더

할당해 주는 것도 도움이   있습니다.

적용 옵션

-Xmx 줄임

-Xgcpolicy:optthruput

CPU 16 이상의 환경에서 WAS 운영하는 경우권장 GC 정책은 무엇인가요?

상황

CPU 16 이상의 AIX장비의 IBM JDK 1.5 이상 환경에서 WAS 운영하고자 합니다.

권장 GC 정책은 무엇 인가요.

조치

 경우 -Xgcpolicy:subpool 옵션을 권장합니다.

하지만 Business Application 성격에 따라 다른 결과가 나올  있음으로다른 GC 정책과의 비교 Test 필요합니다.

적용 옵션

-Xgcpolicy:subpool

 Heap Size 넉넉하게 설정하였음에도 불구하고, Allocation Failure 자주 발생합니다.

상황

Heap Size 넉넉하게 설정하였습니다. Application에서 사용하는 Object들도 매우  경우는 별로 발견되지 않는데잦은AF(Allocation Failure) 발생하고 있습니다.

조치

메모리 단편화(Memory Fragmentation) 의심해   있습니다.
WAS
 JVM -Dibm.dg.trc.print=st_verify  설정하여, kCluster/pCluster 설정이 필요합니다또한, -Xloratio옵션을주어 LOA 영역에 대한 사이즈 조절도 때때로 유효한 경우가 있습니다.

적용 옵션

-Xk –Xp 설정 (-Dibm.dg.trc.print=st_verify 설정 로그 분석을 통한 Size 설정)
stdout 로그에 verbosegc정보에 pinned=xxx 라는 형식으로정 보가 남게된다.

-Xloratio 설정

 

반응형

'UNIX & LINUX > AIX' 카테고리의 다른 글

AIX 에서 FTP 접속 Log를 남기려  (0) 2016.08.23
AIX wget 설치  (0) 2015.10.20
728x90

Putty 설정 파일 백업하는 법

2010.10.20 15:46
regedit을 실행하신 다음에
내 컴퓨터\HKEY_CURRENT_USER\Softeare\Simon Tatham\PuTTY
에 있습니다.

호스트키까지 똥째로 저장하시려면 이 뿌띠 키(디렉토리처럼 생긴거)를 통째로 저장하거나 아니면 이아래에 있는 Session키를 저장하시면 됩니다. (한번 저장해놓고 여러 컴퓨터에서 활용하시려면 Session 만 저장하세요)

왼쪽트리에서 키를 선택하고 나서 메뉴에서 레지스트리->레지스트리 파일 내보내기->선택한 분기 에서 "PuTTYHosts.reg" 처럼 원하시는 이름으로 저장하세요.

이 파일을 더블클릭하시면 설정값들을 다시 입력하실수 있습니다. 자신이 쓰는 깨끗하게 호스트들을 깨끗하게 정리해서 만들어놓고 웹에 올려놓으면, 어디서든지 뿌띠하고 이 파일을만 받아서(뿌띠도 설치할 필요 없으니) 바로 사용할수 있어서 편합니다.

출처 : http://kldp.org/node/46298


반응형
728x90

AIX가 인터넷이 된다면...

root로....

ftp ftp.software.ibm.com
Name> ftp
Password> 이메일
ftp> cd aix/freeSoftware/aixtoolbox/RPMS/ppc/wget
ftp> binary
ftp> get wget-1.9.1-1.aix5.1.ppc.rpm
ftp> quit
rpm -hUv wget-1.9.1-1.aix5.1.ppc.rpm

끝~
wget 사용...


반응형

'UNIX & LINUX > AIX' 카테고리의 다른 글

AIX 에서 FTP 접속 Log를 남기려  (0) 2016.08.23
IBM JVM 튜닝  (0) 2015.10.27
728x90

 

 

 

1. webtob(WS: 정적인 업무 처리) 구동시
 a 1) WSM(웹서버 모니터 프로세스), HTL, HTH 3가지가 구동됨
  2) HTL(리스닝 작업)이 클라이언트로부터 리슨하고,
  3) HTH로 핸들링해서 HTH에서 업무프로세스에 할당하고 처리한 값을 다시 HTL로 보냄
   3-1) HTH 앞단에 큐를 사용하여 과부하를 막음
   3-2) 단위 업무자체가 클 경우 업무프로세스를 확장
   3-3) 사용자가 몰릴경우 HTH(인스턴스)를 4개까지 확장 가능(안에 컨테이너 수는 제한없음)
  4) WSM이 HTL과 HTH를 모니터링하여 문제 발생시 처리

 

 

2. JEUS 구조
  - SERVER > NODE > 제우스 메니저 <동급> 제우스 컨테이너
  1) 제우스 메니저의 역할
     - J2EE 서비스, 리소스 관리(시큐리티, 데이터베이스, 외부소스, jndi 등등)
  2) 제우스 컨테이너
     - 서블릿 엔진, EJB, JMS 등등 업무처리

 

 

3. webtob

  1) 설치 중간에 servlet은 제하고 순수 webtob체크
  2) /bin파일/ wsboot, wscfl(실행파일 설정), wsdown

 

 


4. jeus
  1) 설치 중간에 어드민 패스워드 입력
  2) webserver(내장 webtob ==> 인스턴스 1개만 생성가능, 같은 공간의 제우스하고만 연결) 
  3) /webserver/config/ws_engine.m 을 http.m으로 새로 저장하여 작업
  4) cmd창 /webserver/config> wscfl -i http.m(파일 유효성 검사) --> wsconfig생성
  5) cmd창 /webserver/config> wsboot --> 웹투비 가동
                              wsdown --> 웹투비 다운

 

  6) jeus 환경설정
    --> /config/해당컴터이름/jeusmain.xml 수정
        /config/해당컴터이름/해당컴터이름_servlet_engine1/webmain.xml 수정 
    --> 최초의 연결설정은 jeus에서 webtob로 설정명령
 

  7) cmd창> jeus
 

  8) cmd창> jeusadmin 사용자컴터이름  ==> 어드민 로그인
 

  9) cmd창> boot  ==> 제우스 가동
                  down  ==> 제우스 다운

 

 10) 

기타 환경 변수 추가는 jeus가 설치된 폴더(c:\tmaxsoft)의 bin 폴더의 jeus.properties.cmd       파일을 열어 설정해 줄 수 있다.

         - JEUS_BASEPORT : JEUS 가 사용할 네트워크 포트중 기본 포트 --> 9736

         - JAVA_HOME : Java 2 설치 디렉토리

         등등...

         - JEUS_BASEPORT를 수정할 경우

           : %JEUS%\config\vhost.properties의

             컴퓨터이름 = 컴퓨터이름:9736 의 포트도 같이 수정

 

 11) admin페이지 접속 ==> http://localhost:9744/webadmin/ 

      (포트는 jeus.properties.cmd 의 JEUS_BASEPORT 숫자 + 8한 숫자)

      (로그 보기 및 jdbc 컨넥션 풀, 어플리케이션 배포 등 설정)

       - webadmin 을 실핼 시키기 위해서는 JEUSMain.xml 에 <enable-webadmin> 태그의 값이

          true 로 설정 되어 있어야 한다.

          (경로--> %JEUS_HOME%\config\<nodename>\JEUSMain.xml)

  12) /lib/datasource 안에 관련 jar파일(jdbc 드라이버 등) 저장

  13) admin 명령어 (admin으로 cmd창에서 접속후 cmd창>help 로 확인가능)
     -  st -v
        st -p
        st -r
        q
        conlist
        downcon [컨테이너명] 
        applist
        dsinfo
        ti -a
        dsconinfo -con [컨테이너명] -t [컨넥션풀 이름]
        등등


  14) 설정파일의 xml스키마를 보고싶을땐  /lib/schemas/jeus/ 안에서 참조

 

  15) jeus/bin/ 안에서 .cmd 파일로 만들고 cmd창에서 모아서 어디서든 실행할 수 있다.

       (서버 내리기, 어드민 접속 등등)
      예) jeusadmin [컴퓨터이름] -Uadministrator -Ppassword jeusexit   ==>jdown.cmd로 만듬    
           jeus -Uadministrator -Ppassword   ==> jboot.cmd로 만듬
          jeusadmin [컴퓨터이름] -Uadministrator -Ppassword  ==>jadmin.cmd로 만듬

  

  16) 메뉴얼
     [jeus 6.x]
      http://technet.tmax.co.kr/kr/edocs/jeus/60/index.html

     [webtob 4.x]
     http://technet.tmax.co.kr/kr/edocs/webtob/41/index.htm

  

 

 

 

 

======= java.net.ConnectException: Connection refused: connect

           worker(webtob1-hth0(localhost:9900)-w00:null) : Failed to reconnect
                                                                                                        ===============

1. webtob와 설정이 맞지 않기 때문이다.

2. jeus 설정을 바꿨다면 webtob까지 모두 내렸다가 다시 올려야 한다.

 

 

 

 

 

 

 

================================ log 설정 =======================================

1. JeusMain.xml (<node> 태그 사이에 작성)

<system-logging>
            <name>jeus</name>
            <handler>

                <console-handler>

                      <name>handler0</name>
                      <level>FINE</level>
                 </console-handler>
                <file-handler>
                    <name>handler1</name>
                    <level>FINE</level>
                     <valid-day>1</valid-day>
                     <file-name>D:\Project\workspace\JeusLog\JeusServer.log</file-name>
                </file-handler>
            </handler>
</system-logging>

 

2. ~~-servlet 폴더의 WEBMain.xml(<context-group>안에..)

<logging>
            <access-log>
                <handler>

                   < console-handler>

                      <name>handler0</name>
                    </console-handler>                   

                   <file-handler>
                        <name>handler1</name>
                    </file-handler>
                </handler>
            </access-log>
        </logging>

 

 

==================== OutOfMemoryError:PermGem Space 에러 =================

<JEUSMain.xml>

<engine-container>
            <name>container1</name>
     <command-option>-Xms256m -Xmx512m -XX:PermSize=512m

                                -XX:MaxPermSize=1024m</command-option>
            <sequential-start>true</sequential-start>
            <engine-command>
                <type>ws</type>
                <name>engine1</name>
            </engine-command>
            <engine-command>
                <type>jms</type>
                <name>engine1</name>
            </engine-command>
            <engine-command>
                <type>ejb</type>
                <name>engine1</name>
            </engine-command>
            <engine-command>
                <type>servlet</type>
                <name>engine1</name>
            </engine-command>
        </engine-container>

 

==> 이런식으로 PermSize를 늘려준다.

 

 

 

============================= webtob 사용 안하기 ==============================

<해당 servlet-engine의 WEBMain.xml>

<webserver-connection>
            <http-listener>
                <listener-id>http1</listener-id>
                <port>8088</port>
                <thread-pool>
                    <min>10</min>
                    <max>20</max>
                    <step>1</step>
                </thread-pool>
            </http-listener>
            <!--<webtob-listener>
                <listener-id>webtob1</listener-id>
                <port>9900</port>
                <output-buffer-size>8192</output-buffer-size>
                <thread-pool>
                   <min>1</min>
                   <max>5</max>
                   <step>1</step>
                   <max-idle-time>30000</max-idle-time>
                </thread-pool>
                <webtob-address>localhost</webtob-address>
                <registration-id>MyGroup</registration-id>
            </webtob-listener>
  -->
        </webserver-connection>

==> webtob를 사용하지 않고 jeus만으로 web을 구동할 경우

      <webtob-listener>를 주석처리한다.

 

 

 

======================== <invocation-manager-action> =========================

1. Warning

  : 이 선택사항이 선택되면, 만약 한 자원이 무상태 메소드 호출 동안 사용되었지만 반환할 때 닫지 않게 될 경우 이벤트가
container log에 warning 메세지로 기록된다.

 

2.AutoClose:
이 선택사항이 선택되면, 만약 한 자원이 무상태 메소드 호출 동안 사용되었으나 반환할 때 닫히지 않는다면 자원이
자동적으로 닫힌다.


===JEUSMain.xml===
<jeus-system>
  <node>
...
    <engine-container>
...
      <invocation-manager-action>
          AutoClose
      </invocation-manager-action>
...
    </engine-container>
  </node> 
</jeus-system>

 

 

 

============================ jeus admin 비밀번호 수정 ========================

1. cmd창 열고
2. java -classpath "%JEUS_HOME%\lib\system\jeus.jar" jeus.security.util.Base64Coder <바뀔 암호>
   하면 암호가 반환됨
3. %JEUS_HOME%\config\컴퓨터이름\security\SYSTEM_DOMAIN\accounts.xml을 열어서

<?xml version="1.0"?>
<accounts xmlns="http://www.tmaxsoft.com/xml/ns/jeus" version="6.0">
      <users>
        <user>
            <name>administrator</name>
            <password>{base64}이부분 수정</password>
            <group>Administrators</group>
        </user>
    </users>
    <groups>
        <group>
            <description>A group for administrators</description>
            <name>Administrators</name>
        </group>
    </groups>
</accounts>

 

출처 : http://sararing.tistory.com/176

반응형
728x90

MERGE 문의 이해

  • - MERGE문은 조건에 따라서 데이터의 삽입,갱신,삭제 작업을 한번에 할 수 있다.
  • - 해당 행이 존재하는 경우 UPDATE(DELETE포함 할 수 있음)를 수행하고, 새로운 행일경우 INSERT를 수행한다.
  • - 대상 테이블에 대한 UPDATE/INSERT 조건은 ON절에 의해 결정된다.
  • - MERGE문에서 CLOB 사용시 업데이트 할 내용이 2000bytes가 넘을때 ORA-00600 오류가 발생하며, patch set 11.2.0.2 버전으로 해결할 수 있다.

MERGE Syntax
1
2
3
4
5
6
7
8
9
10
11
12
13
MERGE [ hint ]
   INTO [ schema. ] { table | view } [ t_alias ]
   USING { [ schema. ] { table | view }
         | subquery
         } [ t_alias ]
   ON ( condition )
WHEN MATCHED THEN
UPDATE SET column = { expr | DEFAULT }
           [, column = { expr | DEFAULT } ]...
[ DELETE where_clause ]
WHEN NOT MATCHED THEN
INSERT [ (column [, column ]...) ]
VALUES ({ expr [, expr ]... | DEFAULT })
  • INTO : DATA가 UPDATE되거나 INSERT 될 테이블 또는 뷰를 지정.
  • USING : 비교할 SOURCE 테이블 또는 뷰나 서브쿼리를 지정, INTO절의 테이블과 동일하거나 다를 수 있다.
  • ON : UPDATE나 INSERT를 하게 될 조건으로, 해당 조건을 만족하는 DATA가 있으면 WHEN MATCHED 절을 실행하게 되고, 없으면WHEN NOT MATCHED 이하를 실행하게 된다.
  • WHEN MATCHED : ON 조건절이 TRUE인 ROW에 수행 할 내용 (UPDATE, DELETE포함 될 수 있음)
  • WHEN NOT MATCHED : ON 조건절에 맞는 ROW가 없을 때 수행할 내용 (INSERT)

MERGE 예제1

아래 예제는 부서번호 20,30의 사원이 존재하면 급여를 10% 인상하고, 존재하지 않으면 급여가 1000보다 큰 사원정보를 등록하는 예이다. (INSERT, UPDATE 예제)

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
32
-- 부서번호 10, 20의 사원정보를 가지는 테스트 테이블을 생성하자
CREATE TABLE emp_merge_test
AS SELECT empno, deptno, sal FROM emp WHERE deptno IN (10, 20);
 
 
-- 데이터를 확인해 보자
SELECT * FROM emp_merge_test;
 
 
-- 사원이 존재하면 급여를 10% 인상하고, 없으면 INSERT 한다.
MERGE INTO emp_merge_test m
USING ( SELECT empno, deptno, sal    -- USING절에 뷰가 올수 있다.
        FROM emp
        WHERE deptno IN (20,30)) e
ON ( m.empno = e.empno)
WHEN MATCHED THEN
  UPDATE SET m.sal = ROUND(m.sal*1.1)
WHEN NOT MATCHED THEN
INSERT (m.empno, m.deptno, m.sal)
VALUES (e.empno, e.deptno, e.sal)
WHERE e.sal > 1000                 -- INSERT 절의 조건절도 지정이 가능하다
COMMIT;
 
 
-- 20부서의 급여가 10%증가했고, 30부서는 등록되었는지 확인해 보자
SELECT * FROM emp_merge_test;
 
 
-- 다음 테스트를 위해서 emp_merge_test 테이블에 30부서 데이터를 삭제하자
-- 부서번호 10과 20의 사원정보만 남을 것이다.
DELETE FROM emp_merge_test WHERE deptno = 30;
COMMIT;

MERGE 예제2

아래는 부서번호 10의 사원 급여를 10% 인상하고, 부서번호 20의 사원정보는 삭제하며, 부서번호 30의 사원 급여를 20% 인상하는 예이다. (INSERT, UPDATE, DELETE 예제)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
-- 30 부서가 삭제되었는지 확인한다.
SELECT * FROM emp_merge_test;
 
 
-- MERGE 문 작성
MERGE INTO emp_merge_test m
USING emp e
ON (m.empno = e.empno)
WHEN MATCHED THEN
  UPDATE SET m.sal = ROUND(m.sal*1.1)
  DELETE WHERE (m.deptno = 20)   -- 부서번호 20의 사원정보는 삭제.
WHEN NOT MATCHED THEN
INSERT (m.empno, m.deptno, m.sal)
VALUES (e.empno, e.deptno, ROUND(e.sal*1.2));
COMMIT;
 
 
-- 정상적으로 변경되었는지 확인해 보자
SELECT * FROM emp_merge_test;
 
 
-- 테스트 테이블은 삭제하자
DROP TABLE emp_merge_test;

원본 위치 <http://www.oracleclub.com/lecture/2225>


반응형

'DataBase > Oracle' 카테고리의 다른 글

Pragma Autonomous_Transaction 사용방법  (0) 2016.08.03
오라클 사용자 생성 및 권한주기  (0) 2015.10.30
컬럼에 '(single quote) 데이터 조회하기  (0) 2015.10.05
DBA 접속방법  (0) 2015.10.05
SQL Code (ORA-?????)  (0) 2015.10.05

+ Recent posts