2014년 4월 11일 금요일

오랜만에 Garbage Collection 정리

  1. WAS를 다시보려니 JDK 8도 나오고.... 그러고보니 JDK 5 이후에는 JVM Spec을 찾아본적도 없고.... 간만에 6,7,8 한꺼번에 따라가 봅니다.  내용은 주로 Middleware의 성능튜닝과 관련된 HotSpot 관련 정보입니다.
  2. 문서에서는 다음과 같은 내용에 대한 정보를 제공합니다.
    1. JVM 이란?
    2. JVM에서 Heap과 GC란?
    3. GC 의 종류는
    4. GC 적용 전략
    5. What's new JDK 8
  3. JVM이란
    1. JVM의 장점
      1. 멀티 플랫폼, 높은 호환성
        1. 대부분의 OS에 맞는 JVM Binary 제공
      2. 개발 생산성, 잘 다듬어진 JAVA Comp
        1. Component-inheritance, Implement, Over….
      3. 개발/운영의 편의성
        1. 메모리 자동관리 (never malloc/free)
        2. 시스템 자원 자동할당
    2. JVM의 단점
      1. 이 죽일 놈의 속도 (JNI필수, 개선 JIT/hotspot compiler)
        1. 시어머니가 둘이다! (JNI Interface, OS Interface)
      2. 자동화의 단점, 통제가 안 된다
        1. 메모리 정리(GC)는 JVM 맘대로? System.gc()
        2. 공유객체(static obj)는 말 그대로 공유 쓰레기통?
      3. 높은 생산성 대비 막 운영(?), 막 개발(?)의 폐해
        1. 일단 돌아가게 메모리 많이 줘버려! 
        2. 알아볼 수 없는 코드, 1000개 조회 해서 10개 쓴다, 나쁜 유지관리
    3. OS 측면에서 보면  JVM도 Process 일 뿐이다.
      1. JAVA Process는?
    4. JVM입장에서 보면 WAS도 Java Application 일 뿐이다.
      1. JVM위에서 구현된 Application = Web Application Server
      2. 성능과 자기만의 색깔을 위해 도입된 JNI 와 확장 Package들
        1. JNI : Java Native Thread 들, JVM의 취약점인 IO관련 작업을 C로 처리한다
          1. 사용자 요청을 받아들이는 Server Socket 부문
          2. DB Connection을 생성하는 Client Socket 부문
          3. Log Write를 관리하는 File IO부문 
        2. 확장 Package
          1. Open Source 들 중에 괜찮은 Pkg를 선택해서 추가한다.
          2. 추가할때 그냥 하면 빈티 나니까.... 의존성을 높이기 위해... 편의 API를 제공한다.
            1. JMS를  쓰겠다고 Weblogic Intigration API를 사용했다면 Weblogic에 의존적이됨
            2. Session 공유를 하겠다고 JBoss Infinispan을 쓰면 JBoss와 노예계약  (잘 쓰면 득 못쓰면 독)
      3. WAS의 일반적인 버그는 기능 설정과 관련이 있다
      4. WAS의 Critical 버그는 JVM 버그에 의존적이다.
  4.  JVM에서 Heap 과 GC란
    1. Heap
      1. JAVA Object들의 작업 공간 (Sun(oracle) JVM / HP JVM Architecture,  not equal IBM / BEA(ORACLE) jrockit)
        1. Sun JVM 구조
          1. NEW(Eden) : 신규 생성 되는 객체 들이 저장 되는곳  
          2. Survivor 1(From,ss1),2(To,ss2) : Old로 이전 되기 전 Promotion 대상이 되기 위해 거쳐 가는 곳
          3. Old : 오래(?) 사용되어야 하거나 NEW가 부족한 경우 저장되는 공간
          4. Perm(Permanent) : java code, method들의 List,Static Object 들이 저장되는 공간 (메타데이터라고 들 한다), 
          5. Stack : Thread 당 할당된다.(너무 크게 잡으면 메모리 낭비, 적으면 Stack Overflow)   
          6. Native(Other) : JNI관련 시스템 Object들이 사용하는 공간 
            1. !! Xmx 2G로 잡았는데  Top 명령에서 RSS를 보면 2G를 넘는이유는 Stack 과 Native가 잡는 영역 때문이다.
            2. !! 예를들어 기본적으로 Xmx보다 너무 크다면 Xss를 너무 크게 잡으면 늘어난다.
            3. !! 동적으로 Xmx 보다 크게 늘어난다면 File IO 또는 Socket IO 용 버퍼가 크거나 많이 사용되면 늘어날 수 있다.
            4. !! JIT로 인한 증가는 일반적으로 수백Mbyte 이하이다. JIT로 인한 메모리 누수에는 아래와 같이 JIT대상에서 제외 할 수 있다.
              1. -Xjit:exclude={package/class.method|package/class.method}
              2. 또는 파일에 exclude 대상을 리스팅하여 넣고(한줄에 제외할 메서드 하나씩)
                1. .hotspot_compiler  파일을 만들고 안에다가 내용을 넣는다.
                  1. exclude com/amir/SomeClass someMethod  (한줄에 하나씩, Class를 넣어도 되고 Method를 넣어도 된다.)
                2. -XX:CompileCommandFile=/my/excludefile/location/.hotspot_compiler
            5. JNI로 별도로 개발된 모듈의 메모리 누수는 ..... JNI 할아버지를 불러야 한다...

        2. SUN JVM 구조 
          The memory model of the Sun Hotspot JVM
        3. BEA JVM 구조 (Nursery : 보육장 - Sun의 ᅟ Young)
          Heap of the Oracle JRockit JVM
        4. IBM JVM 구조
          The IBM JVM generational heap
        5. Sun JVM G1 구조

          Humongous(엄청난?) : region의 50%가 넘는 크기의 Obj가 생성되면 Humongous region(몇 개의 region을 합함)으로 저장한다.
        6. Sun JVM의 상세 구조
        7. Heap에 저장되는 Object의 구조 
    2. Garbage Collection 
      1. 이란
        1. Referrer가 없는 Object  들을 메모리에서 제거(Minor, MajorGC) 하거나 지속해서 사용할 Object를 Promotion 하여 저장(OLD)
        2. 단편화된 메모리 공간을 조각 모음 하는 작업
          1. Live,reachable Object : 현재 사용 중인 Object로 GC대상이 아니다.
          2. Unreachable Object :  사용하지 않는 Objject의경우 GC 대상이 된다.
          3. 사용중 과 아님의 기준은? : 참조하는 상위클래스가있는가 == 나에게 referrer가 있는가 
          4. Static Object : Static Object로 선언한 객체의 경우 GC 대상이 아니다.
          5. 위와 같은 그림이지만 Root set이라는 개념과 Obj중 상위 클래스를 참조하는 경우라도 상위 클래스의 참조가 없으면 unreachable 이라는것이 설명 가능해서 추가함
      2. 메모리 관리를 위한 기본 컨셉
        1. weak generational hypothesis  (영역에 대한 자신 없는 가설)
          1. 대부분의 객체는 금방 접근 불가능 상태(unreachable)가 된다.
          2. 오래된 객체에서 젊은 객체로의 참조는 아주 적게 존재한다.
        2. 그래서 두 개의 영역으로 쪼갰다
          1. Young 영역(Yong Generation 영역): 새롭게 생성한 객체의 대부분이 여기에 위치한다. 대부분의 객체가 금방 접근 불가능 상태가 되기 때문에 매우 많은 객체가 Young 영역에 생성되었다가 사라진다. 이 영역에서 객체가 사라질때 Minor GC가 발생한다고 말한다.
          2. Old 영역(Old Generation 영역): 접근 불가능 상태로 되지 않아 Young 영역에서 살아남은 객체가 여기로 복사된다. 대부분 Young 영역보다 크게 할당하며, 크기가 큰 만큼 Young 영역보다 GC는 적게 발생한다. 이 영역에서 객체가 사라질 때 Major GC(혹은 Full GC)가 발생한다고 말한다.
        3. 그래도 느리다.
          1. 병렬로 처리 하자
          2. 실시간으로 처리하자
        4. 구조적으로 도저히 방법이 없다. 해결하자
          1. New/Old개념은 가져가되 구조적 영역은 포기
          2. CG First(G1) 알고리즘 제공
      3. 하면
        1. 기본적으로 JVM은 STW (Stop The World) 된다. (GC 튜닝은 STW을 줄이는것이 최종 목표)
      4. 하고 나면 
        1. 필요한 메모리가 정리되고 새로운 Object 생성이 가능하다
      5. 실패하면
        1. 지속적으로 GC를 시도하게 되며, 그동안 STW 상태이므로 사용자는 장애로 판단한다.



      6. 실패하는 이유
        1. 생성해야 할 Object가 너무 큰 거나 Heap이 부족하거나
          1. 생성하고자 하는 Object가 New 영역보다 작을때 : Minor GC를 수행하고 남는 공간이 생성할 공간만 큼 되면 생성한다.
          2. 생성하고자 하는 Object가 New 영역보다 크거나, Minor GC후에도 공간이 없으면 : Old 영역으로 바로 Promotion을 진행한다.
          3. 생성하고자 하는 Object가 Old 영역보다 작고, Old 영역에 여유가 있다면  :  정상적으로 생성하고 진행한다.
          4. 생성하고자 하는 Object가 Old 영역보다 작고, Old 영역에 여유가 없다면  :  Full GC를 수행하고 저장을 시도한다.
          5. Full GC후에도 Old 영역에 여유가 없다면 : OOM 발생하고 객체 생성에 실패한다.
          6. 생성하고자 하는 Object가 Old 영역보다 크면 : OOM 발생하고 객체 생성에 실패한다.
          7. 주의사항
            1. !! OOM이 발생해도 이론상 JVM이 깨지거나 문제가 발생해서는 않된다.(해당 APP의 Exception발생은 정상적인것임)
            2. !! OOM이 발생하면서 JVM에 무한 Full GC가 나거나 Hang 상태로 보이는 이유는 우리가 본 시점의 OOM이 문제가 아니라 OOM이 발생되도록 메모리를 점유하고 있는 그 무엇인가가 문제이다.  (로그를 보고 OOM발생 Exception의 APP를 무조건 의심하면 안된다.)
        2. Object가 지속적으로 Heap을 점유하는 경우
          1. 생성해야 할 Obj의 크기가 크지 않더라도 절대적인 Heap의 여유 공간이 없다면 OOM이 지속적으로 발생한다.
          2. 대표적인 OOM 발생 원인은
            1. Static 객체에 연결한 대량의 정보
              1. 코드상에 Static final로 정의한 사용자 Obj
              2. 세션 객체에 저장한 대용량 Obj
            2. WAS 연계 시스템의 지연
              1. DB Query가 무겁거나 DB에 문제가 있어 응답이 느리면 해당 처리를 위해 Thread가 대기하고 Thread가 사용중이던 Heap의 Object들은 Refere가 유지되므로 OOM 발생이 될 수 있다.
              2. 기타 원격지 연계시스템(결제, 승인, 실명확인 등)의 경우에도 동일한 증상으로 인하여 OOM 발생위험이 있다.
            3. 마구잡이 개발
              1. DB Cache 객체를 사용하는데 적절한 통제 없이 마구 저장할 경우 절대적인 heap 사이즈가 부족해진다.
              2. 잘못된 코드로 대량 객체를 생성하고 해당 객체를 JSP등에서 세션 범위에서 사용하는 경우 사용자가 늘어나면 OOM이 발생한다.
    3. Promotion 이란  
        1. New 영역은 사용자 호출에 의해 처음으로 생성된 객체(Object = 실 메모리를 점유하는)가 만들어지는 1차 작업 공간입니다.
        2. 이 공간의 영역은 제한적(-Xmn)이므로 지속적으로 사용될 것 같은 Object들은 절차에 따라 Old 영역으로 넘어가게 되며 이 절차를 Promotion이라고 합니다.
        3. GC에서 사용되는 단어 설명
          1. Mark : Object가 현재 사용되고 있는지에 대한 검사, 기준은 Referrer가 있는가, 즉 이 Object가 Applicaiton Code상에서 연결된 것이 아직 사용되고 있는가 (Minor GC)
          2. Sweep : Mark 대상이 된 Object를 불용처리합니다, 실제 메모리를 지우는 작업은 아니고 File 삭제시 FAT에서 정보만 지우듯이 Object 메모리 주소번지만 제거됩니다. (Minor GC)
          3. Compact
            1. 조각모음이라고 보시면 됩니다. 이 작업은 평소에는 수행 되지 않으며 Full GC 시에 수행됩니다. 이 작업의 기본컨셉은 STW(Stop The World)
            2. sweep 된 Object들이 차지하던 공간을 다른 Object들을 이동시켜 메꾸어 단편화를 정리합니다.
            3. JVM의 Heap 공간의 메모리 관리는 Object가 생성 될때 해당 Object가 차지 하는 공간이 연속된 주소공간으로 확보되어야 합니다.
            4. 100M의 여유공간이 있더라도 단편화 되어 연속된 빈 공간이 없다면 Compact를 통하여 정리하게 됩니다.  (Major GC)
        4. Promotion의 진행 순서는 아래와 같이 진행됩니다.  (GC 알고리즘에 따라 조금씩 다르지만 기본 사항으로 이해 하시면 됩니다. G1은 완전 다름...)

          1. 그림은 처음 영역을 표현 합니다 Eden(NEW) 영역에 각자 다른 크기의 Object들이 존재합니다.
            From, To 영역은 Eden 영역의 작은 Object가 OLD로 바로 Promotion이 되지 않고 몇 번의 이동 작업(MaxTenuringThreshold)을 거치다가 sweep 되도록 유도합니다.
            그림에서는 Eden에 있던 일부 객체들은 From 영역으로 이동 되어 있습니다.
        5. 마이너 GC가 발생 되는 순간의 그림입니다.
          1. Yonung 영역에서 Referer가 없는 object는 제거 되고 사용 중인 경우 Survivor space로 이동 됩니다. (From,To의 이동은 통째로 이동 됩니다.  그래서 두 개의 영역의 사이즈는 동일하고, survivor로 들어가는 Obj도 이번 차수에 이동될 영역으로 들어갑니다.)
          2. From 영역에서 Referer가 없는 객체가 제거 됩니다.
          3. From, to를 수 회 왔다 갔다(-XX:MaxTenuringThreshold=32) 한 Obj가 아직 referer가 살아 있다면 Old로 넘어갑니다.
          4. From에 저장되어 있던 obj 중에서 아직 Old로 넘어갈 카운트가 안된 경우 To로 이동 됩니다. (MaxTenuringThreshold 수치까지 왔다리 갔다리 합니다.)
          5. Old에는 앞서 단계를 거치고 살아남은 Obj가 저장되어 있습니다.
        6. 마이너 GC가 수행 되고 나면 다음과 같이 정리 된 상태가 됩니다.

        7. 아래는 Compaction(Full GC)의 그림입니다.
          1. Referer가 없는 Obj는 Mark 됩니다.
          2. Mark 된 Obj는 Sweep 됩니다.  (실제 삭제 작업은 이루어 지지 않으나 Stack에 정보를 삭제)
          3. 주변의 Obj를 순차적으로 이동하여 fragment를 제거합니다.
          4. 이 작업이 수행되는 동안은 STW 입니다.
  5. Full GC & GC Type
    1. 란?
      1. Old 영역 부족, Perm 영역 부족에 의하여 발생
      2. JVM이 상대적으로 느린 것은 어쩔 수 없고, 결국 STW(Stop The World)의 최소화가 관건이다.
    2. 가 일어나면?
      1. 처리 되는 기간 동안 JVM은 동작을 멈춘다 
      2. 일반적인 기준으로 JVM의 가용율에서 STW는 5% 미만으로 통제하여야 한다. 
      3. 24시간 운영시 ( 86400초 * 0.05 = 4320초 ) 최대 72분 내로 통제 (웹서비스 에서는 이것도 너무 러프 하다)
      4. 다만 연속적이면 무조건 안 된다. (말도 안되기는 하지만 72분 동안 WAS가 정지하면 누가 이해 하겠어?)
      5. 간격으로 이야기 하자면 허용 Duratiuon Time이 5Sec 라면  되도록 균등해야 하므로 
        1. 하루의 5%를 GC허용 시간으로 가정하면 = 72분 
        2. GC허용 시간을 GC수행 허용 시간(duration) 나누면 =  864회(72분 / 허용시간 = 4320sec / 5sec) 이하 발생해야 하므로
        3. 1일 기준 가용시간 = 86400sec - 4320sec  =  859680sec ( = 1일 - 허용GC시간)  
        4. 허용 발생회수를 나누면  = 859680sec / 864회 = 995초(약 17분) 간격을 평균 간격으로 이야기 할 수 있다.
    3. 실패하면
      1. VM입장에서는 메모리를 정리해야 다음 처리가 가능하므로 무한 Full GC가 반복된다. =지속적 STW
      2. APP 입장에서는 Out Of Memory Exception이 발생하고 처리가 중지된다.
      3. 간혹 JVM이 죽어버리는 경우도 발생한다. 
      4. 결과적으로 Full GC가 발생하는 것은 인정하지만 실패는 발생하면 안된다.
    4. CMS에서의 Full GC(CMS는 Full  GC를 예방하는 방식이지만 한번 발생하면 대책이 없다...)
      1. CMS는 기본 구조에서 Old 영역에 대한 Compaction 작업을 수행하지 않습니다. (메모리 단편화가 증가함)
      2. JAVA의 Heap 구조에서 Obj는 연속된 메모리 주소공간이 확보 되지 않으면 객체 생성에 실패합니다.  (단편화 되어 100M가 있어봐야 Obj는 생성에 실패할 수 있다)
      3. 이러한 이유로 Old 영역이 실 사용량 보다 적거나 너무 타이트하게 할당될 경우 CMS 무한 Full GC가 발생할 수 있습니다.
      4. 해결하기 위한 컨셉은 아래와 같은 옵션으로 접근한다.
        1. -XX:SurvivorRatio : From, To 영역의 사이즈를 키워서 작은 obj(단편화 원인)를 Old로 Promotion 되지 않도록 유도(From, To 에서 GC 되기를 기대할 뿐 늘린다고 해결 되지 않는다)
        2. -XX:MaxTenuringThreshold : Promotion 조건인 From, To 영역의 이동 카운트값을 늘려서 더 많이 이동(왔다리 갔다리)하게 만들어서 Old로 Promotion 되지 않도록 유도
        3. -XX:CMSInitiatingOccupancyFraction : CMS 동작의 트리거를 좀 더 빨리 동작하도록 한다, 예를 들어 사용율 60%부터 동작한다면 30%로 줄여서 미리 CMS를 구동해서 단편화를 제거한다(compact를 하는것이 아니기때문에)
        4. -XX:+UseCMSInitiatingOccupancyOnly :항상 CMS를 점진적으로 사용하도록 합니다. 
    5. STW 개선방안은?  (GC 알고리즘)
      1. JVM의 GC에서 메모리를 정리하는 것은 JVM 내에 있는 APP(HotSpot)이다. 이 APP는 Thread로 동작한다.
        1. Serial GC(-XX:+UseSerialGC) : 기본적은 GC는 1개의 Core가 있는 시스템등에 적용하기 위한 GC로 PC Application등에는 가능하나 서버에는 적용해서는 안된다.
        2. Parallel GC(-XX:+UseParallelGC) : JDK6에서는 기본 GC, N 개의 GC Thread가 있으면 전체 STW Time은 1/n 이다 (이론적으로 하지만 좀 더 걸린다.) 
        3. Parallel Old GC(-XX+UseParallelOldGC) :  JDK5 update 6부터 제공되었으며 Parallel GC와 동일하지만 Old 영역 GC 구조가 변경되어  Mark-Summary-Compaction 단계를 거친다. (XX:+UseParallelGC를 적용하면 기본 활성화 됨)
        4. Concurrent Mark&Sweep GC(-XX:+UseConcMarkSweepGC) : N개의 Thread + 계속적인 GC를 통하여 STW이 발생하지 않도록 최소화 하는 방법도 있다. (CMS라고 부른다)
        5. Minor GC발생시 Old도 덤으로 GC하는 Train GC(-Xincgc) = Incremental GC 도 있다.  (컨셉은 훌륭한데....거의 사용 안함), JDK8에서 Deprecate 됨
        6. G1 (Garbage First)GC(-XX:+UseG1GC) : JDK 6에서 early access로 제공했으며 JDK 7 update4 에서 정식으로 적용되었다. Server style GC라고 부른단다 ^^
          http://www.oracle.com/technetwork/java/javase/tech/g1-intro-jsp-135488.html
          1. CMS가 Old 영역의 Fragement에 대응하지 못하고 무한 Full GC를 수행하는 문제점이 있고 이를 해결 하기 위한 방안으로 제시되었다  
          2. Multi Process + Lage Memory 시스템을 대상으로 한다.  (Heap 1~2G 시스템에 적용하면 Overhead로 오히려 성능 문제가 발생할 수 도 있을 듯....이건 추정임)
          3. New,Old 영역에 연속된 메모리 주소(물리적) 에 대한 구조적 개념을 버리고 메모리 영역을 통으로 관리 함으로써 프로모션이라는 것 자체가 없어졌다. 
          4. 전체 메모리를 Region(지방,부문) 이라고 부르는 대략 1Mbyte단위(-XX:G1HeapRegionSize=size)의 블럭형식 단위로 분할 하고 이 영역에 객체를 생성한다. 
            1. JDK 8 기본 사이즈는 JVM이 상황 봐서 정의 한답니다. The default region size is determined ergonomically based on the heap size.
            2. JDK 6 u26에서는  init heap size / 2048 이였다.  (아마도 JDK8도 동일할 듯)
          5. New,Old 가 없으므로 Promotion이 없으며 메모리 할당 제어를 Evacuation(이바큐에이션-소개,비우다) 이라고 부른다. (개념은 비슷함)
          6. 내부적으로 GC동작에 대한 기준은 STW 시간에 대한 목표치를 가지고 동작한다.  –XX:MaxGCPauseMillis=<n>, default value = 200ms.  (거의 실시간으로 봐야할 듯)
          7. 목표치 시간에 대한 GC가 될 수 있도록 내부적으로 추정해서 동작한다.(알고리즘은 잘 모르겠어요....) 즉 짧게 지정할 수 록 GC가 빨리 동작하고 = 자원을 많이 먹는다
          8. 기존 Old 영역에서 참조하는 New 영역의 객체 정보(referrer)를 관리하던 Card Table이 전체 region에 대한 객체 referrer에 대한 관리형태로 변경되었다.(Remembered Sets 이라고 한다)
          9. 2014년 Q1 현재 G1을 공식적으로 지원하는 JVM은 ORACLE JDK(Sun JDK) 뿐이다.
          10. 현재 G1 GC로그를 분석할 수 있는 툴은 개발되어 있지 않다. log를 보고 직접 분석해야 한다. (-XX:+UnlockExperimentalVMOptions -XX:+UseG1GC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps  -XX:+PrintHeapAtGC)
            1. -XX:+UnlockExperimentalVMOptions 옵션은 JVM에 실험적 옵션을 활성화 하는 옵션이다.
            2. JDK7 update4 부터는 위 옵션을 넣지 않아도 된다.  (jdk6, jdk7 u3이하에 사용)
          11. Option and Default Value
            Description
            -XX:+UseG1GCUse the Garbage First (G1) Collector
            -XX:MaxGCPauseMillis=nSets a target for the maximum GC pause time. This is a soft goal, and the JVM will make its best effort to achieve it.
            -XX:InitiatingHeapOccupancyPercent=nPercentage of the (entire) heap occupancy to start a concurrent GC cycle. It is used by GCs that trigger a concurrent GC cycle based on the occupancy of the entire heap, not just one of the generations (e.g., G1). A value of 0 denotes 'do constant GC cycles'. The default value is 45.
            -XX:NewRatio=nRatio of old/new generation sizes. The default value is 2.
            -XX:SurvivorRatio=nRatio of eden/survivor space size. The default value is 8.
            -XX:MaxTenuringThreshold=nMaximum value for tenuring threshold. The default value is 15.
            -XX:ParallelGCThreads=nSets the number of threads used during parallel phases of the garbage collectors. The default value varies with the platform on which the JVM is running.
            -XX:ConcGCThreads=nNumber of threads concurrent garbage collectors will use. The default value varies with the platform on which the JVM is running.
            -XX:G1ReservePercent=nSets the amount of heap that is reserved as a false ceiling to reduce the possibility of promotion failure. The default value is 10.
            -XX:G1HeapRegionSize=nWith G1 the Java heap is subdivided into uniformly sized regions. This sets the size of the individual sub-divisions. The default value of this parameter is determined ergonomically based upon heap size. The minimum value is 1Mb and the maximum value is 32Mb.
          12. G1의 동작 (기존과 다르게 G1은 GC가 시작되면 Young region 정리(MinorGC)후 Evacuation 과 Compaction(MajorGC)가 연속으로 진행된다.)
            1. 기동
              1. G1으로 설정한 JVM은 New/SS/Old 로 구분되는 물리적 메모리 구분 없이 region으로 불리는 메모리 블럭을 구성하면서 기동 된다.
              2. 논리적으로 New/SS/Old는 존재 하지만 물리적으로 주소번지로 구분 되지 않는다.
              3. 초기 Object들은 임의의 region에 생성되며 해당 obj의 referrer 정보는 Remember set(전체 Heap에서 5%수준을 사용)에 저장된다.
              4. region 크기보다 큰 obj가 생성되어야 한다면 몇 개의 region에 걸쳐서 Object를 생성하게 되고(인접해 있는) 이러한 region 집합을 Humongos라고 부른다. 이 정보도 remember set에 저장된다.
            2. ᅟYoung GC = Minor GC
              1. 수행단계 (Marking -> Remarking -> Evacuation )
                1. Concurrent Mark : Single Thread로 진행, 정지없음, remember set의 referrer 정보를 참조하여 live가 아닌것만 빠르게 마킹한다.
                2. Remarking : 병렬로 진행, 정지 없음, Region마다 live obj의 밀도(전체 Obj중에서 Live 비율)를 계산하고 만약 UnReachable Obj만 있을 경우 Region 자체를 폐기한다.
                3. Evacuation : 병렬로 진행, 정지시간 있음. region의 live obj 밀도가 낮은 region에 대하여 Evacuation을 실행한다.
                  1. 정리 대상 region에서 live obj는 새로운 region(Promotion age에 따라 ss 또는 old region) 으로 복사 된다.
                  2. 논리적으로 Serviver 영역(SS)인 다른 region으로 복사 거나 Live Obj만 있는 region(논리적으로 Old영역)으로 복사된다.
                  3. 이동 후에 unReachable obj만 있는 region은 폐기된다.
                  Icon
                  Marking 작업은 snapshopt-at-the-begining(SATB) Marking 알고리즘을 사용한다. 
                  1. GC 실행시 remember set의 reference 정보를 기준으로 모든 Live Obj의 reference를 추적하고, referrrer가 없는 Obj를 mark한다.
                  2. 이때 Mark 작업은 병행수행(Concurrent)되므로 remember set이 지속적으로 변경된다(비교기준이 없다) 그렇기 때문에 GC 시작시의 remeber set의 snapshot을 기준으로 변경된 내용에 대해서 Marking 작업을 수행하게 된다.(전체 Scan이 아니므로 빠르다)
              2. 설명
                1. 시간이 지나면 referrer가 없는 obj들이 증가 되게 된다. (remeber set을 참고하여 지속적으로 region에 대하여 Concurrent Mark가 수행됨)
                2. Minor GC는 실시간으로 지속적으로 수행 되나 전체에 대한 GC는 아니고 region단위로 수행되며 Live Obj가 없는 region은 폐기함으로써 메모리를 정리하게 된다.  (전체적으로는 메모리가 정리되지만 단편화가 증가한다.)
            3. Old GC = Major GC
              1. 수행단계 (Evacuation -> Compaction)
                1. Evacuation
                  1. yong GC의 Evacuation과 동일한 방식으로 시작한다.
                    1. 앞서 Scan한 정보를 기반으로 region의 live obj 밀도가 낮은 region에 대하여 Evacuation을 실행한다.
                    2. 정리 대상 region에서 live obj는 새로운 region(Promotion age에 따라 ss 또는 old region) 으로 복사 된다.
                    3. 논리적으로 Serviver 영역(SS)인 다른 region으로 복사 거나 Live Obj만 있는 region(논리적으로 Old영역)으로 복사된다.
                    4. 이동 후에 unReachable obj만 있는 region은 폐기된다.
                  2. 이때 앞서 진행하면서 Survivor region으로 지정된 영역과 Old region으로 지정된 영역이 이동 되어 메모리 앞쪽으로 정리된다.
                2. Compaction
                  1. Evacuation을 거치고 나면 전체 메모리에서 Live Obj가 있는 young region에 해당하는 영역들이 듬성듬성(단편화) 존재하게 된다.(위의 그림 우측)
                  2. 메모리가 부족하거나 GC 수행시간이 설정보다 길어질 것으로 판단되면 GC를 다시 수행하면서 region들을 앞쪽으로 이동 시켜 정리하게 된다.
              2. 설명
                1. Evacuation작업은 Minor(yongGC)와 동일한 작업을 수행하지만 정리된 region을 이동시키는 부분이 조금 다르다.
                2. G1의 Compaction 작업은 region 단위로 이루어지며
                3. 해당 region을 참조하는 Thread가 잠시 느려지기는 하지만  
                4. 전체적으로 서비스는 진행 중이므로 STW은 발생하지 않는다. (아주 짧은 정지는 있다)
  6. Garbge Collection strategy
    1. Throughput VS Response Time trade-off
      1. 단위 시간당 일량(Throughput)을 증가시키려면 GC소요시간=횟수를 줄여야 하고 GC를 줄이기 위해 CMS나 병렬GC를 사용하는 경우 CPU자원을 더 사용하게 되고 
      2. 정해진 자원에서 더 많은 CPU를 사용한다는 것은 응답시간의 증가와 같으므로 Response time과 반비례 하게 된다.(라고 문서상에 표현한다.)
        1. 하지만 최근에는 워낙 장비의 CPU Power들이 좋기 때문에 GC를 줄이기 위해 복잡한 GC 알고리즘을 사용한다고 Response time과 반비례 하지는 않는다.
        2. GC를 실시간으로 처리하는 경우  비교적(GC를 한꺼번에 하는 것 보다는) Response Time이 증가하지만 성능상 영향은 미미하므로 무시할 수준이라고 판단하면 됩니다.
      3. 쓰루풋 중심 튜닝 (WEB Service는 요고이 중요하다)
        1. 응답시간을 조금 늘이더라도 GC가 최대한 발생하지 않도록 한다.
        2. Parallel Algorithm 
          1. 여러 개 Thread 가 Full GC 를 최대한 빨리 끝낸다.
          2. CMS에 비하여 안정성 높음 
        3. Concurrent Algorithm (CMS)
          1. 여러 Thread + 실시간으로 Mark & Sweep = Full GC 최대한 방지
          2. CPU 자원 가장 많이 사용
          3. Parallel과 Serial에 비하여 안정성에 문제가 있다. Object Type(small or big size)JVM 및 OS 마다 조금씩 다르다
        4. G1
          1. 메모리 영역을 순차적으로 관리하지 않고 1Mbyte 단위의 Region이라는 블럭들을 사용하고 Compact를 배제 시킴으로써
          2. GC의 발생을 줄이는 것 과 함께 GC 수행시간을 개선시킴
          3. 메모리상의 region에 대한 연관관계(referrer)를 관리하기 위한 Overhead가 있으므로  작은 heap 영역을 사용하는 경우 오히려 좋지 않을 수 도 있다(Xmx 2G 이하 등)
      4. 응답성능 중심 튜닝 
        1. Default(Serial) Algorithm
          1. Full GC가 발생하더라도 속도가 중요하다.
          2. 단독 APP의 경우 기본이 차라리 나을때가 있다.
    2. 업무 형태에 따른 튜닝
      1. 포털 VS 업무시스템
        1. 포털
          1. 다수의 사용자가 짧은 방문시간을 유지하며 많은 페이지를 호출한다.
          2. 이 경우 JVM에서는 Old 보다는 New영역에 대한 객체 생성 관리가 중요하다.
          3. 최대한 Old영역으로의 Promotion을 적게 하도록 하여 Full GC로 인한 정지시간이 작아지도록 하고
          4. 작은 Obj들이 old에 저장됨으로써 발생하는 단편화가 작아지도록 적용해야 한다.
          5. 관련 옵션
            1. -XX:NewRatio=3 (default 2) : heap에서 New영역에 대한 비율 정의,  New 영역을 크게(Old보다는 작아야 한다)하여 더 많은 객체를 저장하도록 하여 Old Promotion을 줄인다.(Ratio 가 아닌 -Xms= -Xmx= -XX:NewSize= -XX:MaxNewSize= -XX:SurvivorRatio=  를 조합해도 된다.)
            2. -XX:SurvivorRatio=2 (default 8): New영역에서 Survivor 영역에 대한 비율, 기본 사이즈보다 크게 해서 Old Promotion을 줄인다.
            3. -XX:TargetSurvivorRatio=90 : SS 영역정리 기준을 기존 50%에서 90%로 올려 Old Promotion을 줄인다.
            4. -XX:MaxTenuringThreshold=64 (default 15/CMS = 4): SS에서 새로 만들어졌고 , 작은 크기의 Obj들이 SS1,SS2를 더 많이 채류하도록 하여 Old Promotion을 줄인다.
        2. 원장조회, 매출실적 조회
          1. 정해진 인원이 오랜시간동안 대량의 데이터를 조회
          2. 일반적으로 비정형화 된 데이터에 대한 조회를 수행하는 경우 New 영역의 사용빈도가 낮다.
          3. New 영역보다 큰 데이터 사이즈가 빈번하게 저장되므로 주로 Old로 바로 프로모션되는 케이스가 많다.
          4. 이러한 경우 실시간 계열의 GC는 큰 효용성이 없다.
          5. Old 영역을 크게 잡아주고 GC는 단순하게 하는것이 좋다(그래도 single 보다는 Para를 적용한다. CMS는 비추천)
          6. 대량 장표 조회는 WAS에서는 어렵고 최근에는 BI로 거의 넘어갔으며  Bigdata 쪽으로 트렌드를 가지고 간다.
  7. CASE Study
    1. Mass traffic web site Heap Tuning 
      1. JVM Option
        Icon
        Open Market Front Web Site Heap
        -server / 서버운영에 맞도록 자동설정, 최대한 class loading이 처리 된 다음 구동 되도록 한다. 부팅 시간은 오래 걸리지만 서비스 aging time이 짧다
        -Xms2700m / 최소 Heap
        -Xmx2700m / 최대 Heap
        -XX:NewRatio=3 / Heap에서 NEW의 비율
        -Xss128k / 스텍사이즈
        -XX:SurvivorRatio=2 / Edne에서 SS영역의 비율
        -XX:TargetSurvivorRatio=90 / SS 영역의 90%까지만 유지하도록 노력
        -XX:InitialCodeCacheSize=64m / JIT 코드케쉬영역 지정(Native Area)
        -XX:ReservedCodeCacheSize=128M / JIT 코드케쉬영역 최대사이즈 할당 (Native Area)
        -XX:PermSize=350m / Perm사이즈
        -XX:MaxPermSize=400m /최대사이즈 (일반적으로 PermSize와 동일하게 하지만 지속적인 증가를 모니터링하기 위해 좀 더 크게 잡았음)
        -XX:MaxTenuringThreshold=64 64회 SS1,2를 이동하면 OLD로 프로모션
        -XX:+UseParallelGC : 병렬GC
        -XX:ParallelGCThreads=6 : Thread수
        -XX:-UseAdaptiveSizePolicy : New/SS 비율 자동변경 중지
        -XX:+DisableExplicitGC : System.gc()를 통한 수동 GC 트리거 방지  -XX:+ExplicitGCInvokesConcurrent 도 있다. CMS에서 GC 트리거를 방지한다.
        아래 것들은 덤프 분석을 위한
        -XX:+HeapDumpOnCtrlBreak
        -XX:+HeapDumpOnOutOfMemoryError
        -verbosegc
        -XX:+PrintGCDetails
        -XX:+PrintGCTimeStamps
        -XX:+DisableExplicitGC
        -Xloggc:/log/weblogics/${SERVER_NAME}/${SERVER_NAME}_gc_`date +'%y%m%d%H%M%S'`"
      2. 설명
        New Old 비율은 성능에 큰 영향을 줍니다. 일반적으로 비율은 2, 3 에서 이론적 수치가 가장 잘 나옵니다.
        다만 실제 Production에서는 다양한 형태의 Object들이 생성되기 때문에 이론적 TEST결과와 부합되지 않으므로 비율 설정에 따른 모니터링 결과를 반영해야 합니다. 
        Icon
        NEW영역 과 OLD영역 의 계산
        NewRatio 3 = NEW Generation : Old Generation = 1:3
        2700M 이면 2700 / 4 = 675M(NEW) : 2025M(OLD)
        SurvivorRatio 2 = New에서 Eden 의 SS1,2와의 비율 = SS1 : SS2 : Eden = (1:1):2
        675M 이면 675 / 4 = 168M 168M : 504M = (84M:84M):504M

    2. Back Office 에서 Full GC
      1. 기업의 back office applicaiton이라 함은 ERP나 벌크성 데이터를 수집 가공하는 업무가 많음
      2. 이런 경우 너무 많은 SQL 결과값에 의하여 Heap 영역이 부족함으로 인한 문제가 종종 발생함
      3. Full GC가 일어나는 순서는 아래와 같다.
        1. 너무 많은 SQL 결과값 조회
        2. New 영역에 저장 되기에도 크다 OLD로 그냥 프로모션 된다.
        3. 아직 처리가 안 끝났다 = 레퍼런스가 살아 있다. GC대상이 되지 못한다.
        4. Full GC
      4. 해결방안은
        1. Heap 크기를 늘려서는 대부분 이 문제가 해결 되지 않는다.(늘리면 늘리는대로 더 많이 조회함)
        2. Application에서 조회 조건을 추가하여 한번에 조회 되는 데이터량을 제한하고 
        3. 꼭 필요한 대량의 조회건이 필요하다고 한다면 해당 조회에 따르는 데이터량(결과값을 받아서 저장하고 크기를 확인하고 * 동시 사용예상 인원 + 30%)
    3. Permanent 영역의 Full GC
      1. 서비스의 필요에 의하여 지속적으로 JSP를 배포하는 경우가 있다
      2. 그리고 JSP의 변경을 즉시 반영하도록 (hotdeploy) 설정한 경우 해당 class의 메타데이터가 permanent에 지속적으로 추가되며
      3. Perm 영역은 기본 컨셉이 GC를 하지 않도록 구성되어 있으므로 결국 가득 차면서 GC가 발생된다.
      4. JSP가 바뀌면 기존 JSP 정보가 unload 되면 좋겠지만 jsp가 컴파일된 class 파일은 상위 contextLoader가(WAR Context) referrer를 가지고 있기 때문에 Context의 unload(즉 이건 WAR를 내렸다가 올린다는 말이다...WAS재구동해도 되고 WAR만 내렸다 올릴 수 도 있다.)가 되지 않으면 해결이 안된다.
      5.  hotDeploy로 인한 Perm 영역의 누수는 대부분 기존 referrer가 활성 상태로 체크 되어 GC 대상이 못 되는 경우가 많아서 해결이 되지 않는다.
      6. Full GC가 일어나는 순서는 아래와 같다.
        1. JSP를 지속적으로 배포한다.
        2. JSP 안에는 많은 Method가 포함된다. 기존 정보는 그대로 있으면서 
        3. 바뀐 JSP정보가 Permanent 로딩 된다.
        4. 계속 바뀐다. Perm이 점점 줄어든다. 결국은 없다.
        5. Full GC (Unloading 이라고 한다)
    4. Applicaiton이 느린 경우 Full GC
      1. 순서는 이러하다
        1. APP가 객체를 만든다.
        2. APP가 계속 돌고 있다 = GC 대상이 아니다.
        3. APP가 바보라 처리가 끝이 않난다.
        4. 해당 APP 호출이 계속있다 = GC는 안되는 메모리에 객체가 계속 생성된다
        5. Full GC
    5. SQL이 느린 경우 Full GC
      1. 순서는 이러하다.
        1. SQL이 느리다 
        2. 1개당 5초 걸린다.  (getConnection  부터 recordSet 사용 완료까지)
        3. 해당 APP의 요청량이 50TPS 이라면 초당 50개 요청인데 DB Pool 꽉 찬다.  (Pool 갯수를 늘려봐야 필요없다. 조금 느리게 발생할 뿐)
        4. DB Pool이 꽉차면 모든 APP는 Connection을 대기한다.
        5. 모든 대기중인 APP가 메모리를 점유한다 = 아직 끝나지 않았다= GC 대상이 아니다.
        6. Full GC
  8. What's new JDK 8
    1. 2014년 Q1 JDK8이 출시되고 바뀐것이 무엇일까 해서 보았습니다.
    2. 개발환경 부분에서 새로운 코드스타일과 객체에 대한 지원등에 대한 내용이 추가되어 있습니다만.. 우리(미들웨어 제품)와 큰 관계 없는 이야기로 링크만 추가합니다.
    3. http://www.oracle.com/technetwork/java/javase/8-whats-new-2157071.html
    4. 툴 부분에서
      1. jedps(정적 의존성 검색-can understand the static dependencies of their applications and libraries) 도구 추가
        1. pkg(jar,class)의 단순한 포함 내용
        2. pkg와 연관(참조)된 다른 pkg와 해당 pkg의 내용까지 검색하여 출력
        3. pkg 의존성을 찾아볼때 사용하면 좋을 것 같음
          1. a.jar 라는 파일이 있는데 이 jar와 같이 넣어둬야 하는 다른 jar 파일을 찾을때 등
    5. HotSpot (http://docs.oracle.com/javase/8/docs/technotes/guides/vm/)
      1. AES 하드웨어 암호화 지원을 위한 함수지원....별관계 없는
      2. -Xincgc  (incremental gc) 더 이상 지원 안함
      3. -XX:MaxPermSize 설정이 사라지고 -XX:MaxMetaspaceSize  로 변경되었습니다.
      4. -XX:PermSize 설정이 사라지고 -XX:MetaspaceSize  로 변경되었습니다.
        Icon
        JDK 8 Deprecated and Removed Options
        -Xincgc
        Enables incremental garbage collection. This option was deprecated in JDK 8 with no replacement.
        -Xrunlibname
        Loads the specified debugging/profiling library. This option was superseded by the -agentlib option.
        -XX:CMSIncrementalDutyCycle=percent
        Sets the percentage of time (0 to 100) between minor collections that the concurrent collector is allowed to run. This option was deprecated in JDK 8 with no replacement, following the deprecation of the -XX:+CMSIncrementalMode option.
        -XX:CMSIncrementalDutyCycleMin=percent
        Sets the percentage of time (0 to 100) between minor collections that is the lower bound for the duty cycle when -XX:+CMSIncrementalPacing is enabled. This option was deprecated in JDK 8 with no replacement, following the deprecation of the -XX:+CMSIncrementalMode option.
        -XX:+CMSIncrementalMode
        Enables the incremental mode for the CMS collector. This option was deprecated in JDK 8 with no replacement, along with other options that start with CMSIncremental.
        -XX:CMSIncrementalOffset=percent
        Sets the percentage of time (0 to 100) by which the incremental mode duty cycle is shifted to the right within the period between minor collections. This option was deprecated in JDK 8 with no replacement, following the deprecation of the -XX:+CMSIncrementalMode option.
        -XX:+CMSIncrementalPacing
        Enables automatic adjustment of the incremental mode duty cycle based on statistics collected while the JVM is running. This option was deprecated in JDK 8 with no replacement, following the deprecation of the -XX:+CMSIncrementalMode option.
        -XX:CMSIncrementalSafetyFactor=percent
        Sets the percentage of time (0 to 100) used to add conservatism when computing the duty cycle. This option was deprecated in JDK 8 with no replacement, following the deprecation of the -XX:+CMSIncrementalMode option.
        -XX:CMSInitiatingPermOccupancyFraction=percent
        Sets the percentage of the permanent generation occupancy (0 to 100) at which to start a GC. This option was deprecated in JDK 8 with no replacement.
        -XX:MaxPermSize=size
        Sets the maximum permanent generation space size (in bytes). This option was deprecated in JDK 8, and superseded by the -XX:MaxMetaspaceSizeoption.
        -XX:PermSize=size
        Sets the space (in bytes) allocated to the permanent generation that triggers a garbage collection if it is exceeded. This option was deprecated un JDK 8, and superseded by the -XX:MetaspaceSize option.
        -XX:+UseSplitVerifier
        Enables splitting of the verification process. By default, this option was enabled in the previous releases, and verification was split into two phases: type referencing (performed by the compiler) and type checking (performed by the JVM runtime). This option was deprecated in JDK 8, and verification is now split by default without a way to disable it.
        -XX:+UseStringCache
        Enables caching of commonly allocated strings. This option was removed from JDK 8 with no replacement.
이상.

2014년 3월 13일 목요일

JBoss EAP6.2 Standalone Install

  1. 용어정의
    1. Instance = Server : WAS (Web Application Server)의 실질적인 서비스를 처리하는 Process
    2. 비용(총소유비용 TCO) : 도입을 위한 직접비용(CApex)외 변경,관리, 운영을 위한 관리비용 등(Opex) 통칭
    3. Domain : EAP 6 Domain 구성 기본자료  참고
    4. Standalone (독립실행형 서버, 이하 std)
      1. WAS의 관리상의 구성방법으로 구분하자면 아래와 같다
        1. Domain
          1. WAS Instance들을 관리상의 개념으로 묶어서 관리하는 구성(weblogic, webspher, JBoss EAP6 등이 Managed Domain 지원)
        2. Standalone
          1. WAS Instance를 각각 독립적으로 관리하는 구성  (일반적인 여타 tomcat, resin 등 OSS WAS)
      2. recommend
        1. Domain Concept : 대용량 사이트에서 하나의 서비스에 다수의 Instance를 관리하는 곳, 또는 HA가 필요한 작은 서비스가 여러개 있어 전체 Instance가 많을때  Domain 형태가 권장됨
          1. 장점
            1. Web APP Deploy를 통합하여 관리하는 장점(한번의 Deploy, 타켓팅 추가로 WAS Instance에 반영가능)
            2. WAS Config의 형상관리 장점(한번의 수정으로 다수의 WAS에 적용, 물론 모든 속성이 다 되는것이 아니다. 일부)
            3. Logical한 구조를 형상화 했을때 관리적면에서 직관적임(장애, 서비스검토시 장점)
            4. HA 구성시 편의성
          2. 단점
            1. Std 보다 초기 구축에 노력이 더 필요함 (Domain 구조 설계, Domain Controller 구성, HostController 구성 등 엔지니어의 구축비용)
            2. Domain 관리 구조에 대한 이해가 필요(운영자의 초기 교육을 위한 비용)
            3. 추가 system resource 점유(std에 없는 관리를 위한 추가 process 구동필요,  운영상 영향이 있을 정도로 많지는 않음)
            4. Config가 공유되므로(WAS Booting시 Domain에서 Config를 참조하여 구동된다.) 잘못된 Config는 전체에 영향을 미칠 수 있다.
              ■ JBoss EAP6 초기 기동시 메모리 점유
              JVM옵션은 기본값 설정에서 RSS 기준
              아래값은 절대 값이 아님. JVM 옵션에 따라 변동이 있을 수 있음
              (예를들어 Xms와 Xmx를 동일하게 하는경우 설정된 값으로 RSS 소모됨)

              Process Controller : 50M (큰 변동 없을듯???)
              Domain Controller(MASTER) : 156M (관리대상 Slave가 많아지면 늘어날 수 있음)
              Host Controller(SLAVE) : 139M (관리 Instance가 많아지면 늘어날 수 있음)
              Instance : 417M (이놈은 서비스를 위해 지정한 대로 복불복임, 좌측 값은 설치시 만들어지는 sample instance의 점유값 임)
              top - 17:50:25 up 1 day, 7:47, 5 users, load average: 1.75, 0.54, 0.25
              Tasks: 108 total, 1 running, 105 sleeping, 2 stopped, 0 zombie
              Cpu(s): 62.9%us, 3.3%sy, 0.0%ni, 33.4%id, 0.3%wa, 0.0%hi, 0.0%si, 0.0%st
              Mem: 1922488k total, 1626496k used, 295992k free, 56976k buffers
              Swap: 835576k total, 1112k used, 834464k free, 291484k cached
              PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
              11970 jboss 20 0 2392m 417m 16m S 1.7 22.3 0:10.29 /jboss/jdk/bin/java -D[Server:server-one] -XX:PermSize=256m -XX:MaxPermSize=256m -Xms1303m -Xmx1303m -server -Djbo
              11997 jboss 20 0 2405m 353m 16m S 63.1 18.8 0:10.18 /jboss/jdk/bin/java -D[Server:server-two] -XX:PermSize=256m -XX:MaxPermSize=256m -Xms1303m -Xmx1303m -server -Djbo
              10589 jboss 20 0 1137m 156m 15m S 0.3 8.4 0:16.15 /jboss/jdk/bin/java -D[Host Controller] -Dorg.jboss.boot.log.file=/jboss/domains/master/log/host-controller.log -D
              11936 jboss 20 0 1098m 139m 14m S 0.3 7.4 0:05.40 /jboss/jdk/bin/java -D[Host Controller] -Dorg.jboss.boot.log.file=/jboss/domains/slave1/log/host-controller.log -D
              10575 jboss 20 0 1098m 51m 9908 S 0.7 2.8 0:03.31 /jboss/jdk/bin/java -D[Process Controller] -server -Xms64m -Xmx128m -XX:MaxPermSize=256m -XX:+PrintGCTimeStamps -X
              11922 jboss 20 0 1090m 50m 9952 S 0.7 2.7 0:00.85 /jboss/jdk/bin/java -D[Process Controller] -server -Xms64m -Xmx128m -XX:MaxPermSize=256m -Xss256k -XX:+PrintGCTime

        2. Standalone concept : 개발장비, 검증장비, 적은 사용량을 가지는  단순한 사이트, 포털, 쇼핑몰과 같이 대량의 WAS를 Clustering(HA)없이 flat하게 펼칠 경우 오히려 단독형으로 구성하는 것이 관리상 권장될 수 있음
          1. 장점
            1. 초기 구성이 단순하여 노력비용이 상대적으로 낮음 (긴급 증설시  WAS 구성을 잘 정리해 놓는다면 빠르게 작업 가능)
            2. 잘못된 Config등(실수) 으로 인한 문제 발생시 장애 확산범위가 적음  (Config등이 다른 장비나 Instance와 독립적이므로 해당 장비에만 국한됨)
            3. Domain으로 구성하지 않더라도 HA등 구성가능함 (기존의 EAP5 이하 버젼에서 하던 방식으로 구성하면 됨)
          2. 단점
            1. 각각 서버에 대한 관리를 수행해야 하므로 운영시 관리비용이 상대적으로 높음(ex : 10개의 인스턴스는 10번의 작업필요, 1개 APP 10회 배포)
              1. 독립서버를 선호하는 고객사의 특징은 해당 서비스를 오래 운영하여 노하우 및 숙련도가 높은 경우이다.(쉽게말해 손가락이 빠른사람)
              2. 인력중심으로 운영되는 사이트의 경우 Std 형태를 선호할 수 있고 
              3. 생산성을 중요시하는 사이트의 경우 Domain형태를 선호할 수 있다. 
              4. 결국 정답이 없으므로 가이드는 하되 고객사 원하는 방향으로 진행한다.  (Domain이냐 Std냐에 따라 안되지 않는다..다만 수족이 고생할 뿐)
            2. 숙련도에 따라 human fault 발생 위험이 존재하며 발생시 찾기가 쉽지 않다
              1. domain 역시 한번의 실수로 여러 서버에 장애를 유발시킬 위험은 상존한다. 다만 그만큼 찾기도 용의하다
              2. 독립서버에의 경우 실수한곳을 찾기 위한 시간이 숙련도에 따라 아주 작거나(장애아님으로 판단)  엄청나게 오래(장애로 판단)걸 릴 수 있다. 관리적으로 보았을때 어짜피 둘다 장애임
  2. 설치준비
    1. EAP6 설치본  (StandAlone 용 별도 버젼이 있는것이 아니다. Domain 구성할때와 같은 바이너리를 사용하면 된다.)
      1. jboss ORG http://www.jboss.org/products/eap ) org에서도 EAP 버젼 다운로드 가능함, 로그인 필요
      2. Redhat https://access.redhat.com/site/downloads/  (파트너 사이트)
    2. StandAlone 용 스크립트 (rockplace 미들웨어컨설팅본부에 요청)
    3. JDK 1.6 또는 1.7 (http://www.oracle.com/technetwork/java/index.html)
    4. Web Server 연동시 (이 문서에서는 WAS구성만 진행함, WEB Connection은 별도 문서 작성예정)
      1. WebServer(EWS 또는 ApacheORG) (http://apache.org/)
      2. WebServer Connector (Redhat https://access.redhat.com/site/downloads/ )
  3. 환경준비 (Domain 설치시 준비와 별반 차이 없음)
    1.  /etc/hosts 
      1. Loadbalance(web)/Cluster(was) 대상 서버가 많은경우 webserver/was 서버의 hosts에 등록하면 IP로 해깔리기 보다는 이름으로 지정하는것이 정책상 유리(고객사 선호도에 따라 다르므로 협의)

      1. 설치정보 제공 (고객사에 의사결정 요청)
        1. Basic
          1.  
        2. Account
          1. jboss 계정 및 그룹
          2. 필요시 sudo 구성 관련 협의 (1024Port 이하로 서비스 할 경우 root로 구동해야 하나 정책상 sudo 적용이 필요한 경우)
          3. Web GUI Admin ID 및 Password
        3. PATH
          1. EAP 설치위치
          2. log 파일 위치
          3. Deploy Document 위치 (NAS Mount Point 등)
        4. Port 정보 (가이드 제공후 확인받음, 구성전에 해당 포트들에 대한 테스트는 지원인력의 역할)
          1. Web server
            1. http port
            2. ssl port
          2. WEB <-->WAS Proxy
            1. ajp port or httpd port or 연결을 위한 포트 정보
          3. WAS
            JBoss는 기본 domain.xml에 정의된 서비스에 서버의 Off set 값을 더하여 서비스 Port가 결정됨
            인터뷰 전에 기본 설정값을 정의하고 협의
            1. http service 
            2. Admin httpd service
            3. ajp port 
            4. Multicast port
            5. 기타
              1. JMS 등 JBOSS External service(jboss에서는 subsystem이라고 부름) 사용시 
        5. Network
          1. /etc/hosts 등록확인 (필요시 요청, root제공시 직접 등록 등)
          2. Multicast 관련  (WAS Clustering 및 Web-WAS Proxy(mod_cluster) 구성시 필요
            1. UDP Multicast 사용가능 여부 (가이드 제공하여 확인받음)
              1. 고객이 모를 가능성 90%, WAS들이 같은 subnet 인지확인, 같은 subnet에 다른 Multicast사용 솔루션 존재 여부 등 인터뷰를 통하여 확인 필요
            2. Multicast 주소 확인(가이드 제공하여 확인받음
          3. Layer4 LB가 있을 경우
            1. VIP 확인 (고객사 담당 또는 N/W 담당에게 확인)
            2. VIP를 통한 HTTP, HTTPS 서비스 LB 정책 등록 확인(정책 등록이 안되면 웹서버 설치하고 접속이 안되고....여하간 테스트가 번거로움)
              1. Web Server 구성 후 Server Local에서 telnet으로 확인 후  (80, 443 telnet test)
              2. VIP로 접속하여 정상 접속 확인  (Web Server Accesslog를 tail 해 놓으면 어느 서버로 들어오는지 확인가능)
          4. Firewall 정책확인
            설치 후 테스트 진행시 접속이 안되서 웹페이지 확인이 안되거나 , DB 연결 테스트를 못하는 경우가 있음
            되도록 사전에 확인하는것이 좋기는 하나 일일이 챙기기 힘들면 방문시 이야기해서 해결
            1. External --> F/W --> WEB Zone : HTTP, HTTPS Port 정책 확인 (Web Zone 외부에서 Port TEST)
            2. WEB Zone --> F/W --> WAS Zone
              1. mod_jk, mod_Proxy 등은 TCP Port 접근 가능한지 여부 확인 
              2. mod_cluster의 경우 Multicast인 경우 정책상 안될 가능성 높으므로 TCP로 LB할 방안 필요
            3. WAS Zone --> F/W --> DB Zone
              1. WAS 장비에서 DB 장비의 LISTENER의 접속 포트테스트
  4. 설치순서
    1. JDK 설치
      1. 알아서 잘....
    2.  EAP 압축해제 (/jboss/jboss-eap-6.2)
      #unzip jboss-eap-6.2.0.zip
    3. Domain 폴더 복사 ( 독립실행형 서버의 껍대기 만들기)
      1. WAS 정보를 구성할 폴더, 필요하면 협의해서 임의지정  (문서 작성시 임의로 domains 폴더에 아래쪽에 구성하기는 하나 임의 지정가능함)
        #mkdir /jboss/domains
      2. 설치본에 있는 Template 폴더(/jboss/jboss-eap-6.2/standalone)를 복사하여 필요한만큼 생성한다.  (이 문서에서는 1개의 단독실행형 서버 구성까지만 다룬다.)
        [jboss@kwonHost jboss-eap-6.2]$ pwd
        /jboss/jboss-eap-6.2
        [jboss@kwonHost jboss-eap-6.2]$ cp -r ./standalone /jboss/domains/standalone1
        [jboss@kwonHost jboss-eap-6.2]$ cp -r ./standalone /jboss/domains/standalone2  (필요한 만큼)

        물리적인 장비와 가상화장비에서 WAS Instance의 갯수
        물리적 장비와 가상화 장비의 차이는 결국 장비에 보유/할당 된 CPU Processor (processor는 CPU를 의미한다)의 갯수에 따른 
        적정한 Process(WAS 구동시 ps 명령어로 확인되는)갯수에 대한 논의이다.
        과거 multi-core가 없던 시절 또는 Sun(Sparc), HP(PA-RISC), IBM(POWER) 등 RISC칩에서는 일반적으로 1Processor(CPU) 당 1Process(WAS Instance1개)가 정론 이였다.
        하지만 multi-core 기술이 발전하면서 의미가 복잡해 졌다. 아래와 같은 질문에 의견을 제시해본다.

        Q : CPU가 N개 입니다. WAS 인스턴스 몇 개나 띄워야 하나(또는 띄울수 있는가)
        기본적으로 대부분의 솔루션 Process의 구동은 물리적 CPU (Core, HT 논외) 당 1개의를 권장합니다.(WAS 역시 Java Process 이므로 동일함)
        하지만 이것은 Software 개발사 입장에서 러프하게(잘못되도 책임이 없을정도로....)잡은것이고
        운영자 입장에서는 이런 가이드를 그대로 따라했다가는 Over Sizing때문에 비용낭비가 발생합니다.
        하지만....사실 틀린말도 아니니 각자의 입장에서야 어쩔 수 없죠.... ^^;;

        멀티코어 기술이 발전하면 요즘은 1Core = 예전의 1CPU 로 생각하기때문에
        논리적으로 Processor(CPU) 2개 각 Processor 당 Core 4 인 1U 장비의 경우 
        기본은 2개(엔지니어입장), Core를 감안하여 최대 8개(운영자입장) 까지 가능 하겠다고 말할 수 있습니다.
        하지만
        최대 Core수의 70% (8Core * 0.7 = 5.6) 인 6개 Process를 최대로 권장합니다.

        이렇게 권장하는 근거는 1CPU와 Dual Core CPU 간의 성능 향상은 CPU 연산으로는 2배 수가 맞으나 
        Core의 증가로 인하여 core와 Memory 구간의 통신 bandwidth bottleneck(병목구간)이 증가합니다. 
        (H/W적으로 지속적인 개선이 되고 있으나 장비에 따라 다르므로 software측인 WAS입장에서 정확한 수치는 제공하기 어렵다)
        이에 따라 일반적으로 전체 Core수 만큰 WAS Process를 구동하는것은 권장되지 않습니다. (장비의 성능에 따라 모니터링을 통하여 관리 되어야 할 문제)
        특히나 GC 성능을 향상 시키기 위해 병렬(Para) 또는 실시간(CMS) 등의 GC 알고리즘을 적용하면 
        기본값은 OS상에서 확인되는 CPU 개수(=시스템의 Core개수)만큼의 Thread가 JVM 메모리 정리를 위하여 구동되므로(JVM Option으로 수동 조정가능)
        전체 Core 수의 70% 수준으로 WAS Process를 구동시킬 것을 권장합니다.

        Q : 2CPU 장비인 Dell 장비가 있다. CPU당 Core가 8개 짜리인데 인스턴스는 몇 개나 띄워야 하나
        위에서 말했듯이  8 * 2 = 16core
        16core * 0,7 = 11.2 으로 최대 11개정도가 가능하겠습니다. (메모리가 가능하다면...사실 이런 장비는 닥치고 가상화 하는겁니다.)
        튜닝 값에 절대 값은 없습니다. 운영상태를 모니터링해서 더 띄워도 됩니다만.... 
        역설적으로 더 구동해도 된다는것은 그만큼 트래픽이 적다는 의미 이므로
        차라리 서버수를 줄이는 통합 작업을 거치는 것이 좋은 방향일 수 있습니다.

        Q: Hyper-Threading(HT)을 켜면 CPU가 2배 많아진다.(보기에...) 그만큼 WAS를 더 띄워도 되나
        Hyper-Threading(이하 HT)는 로지컬하게 CPU로 들어오는 명령어를 CPU에 Mapping 하는것이 아니라
        가상의 Thread를(LWP : light-weight process 등으로 부름) CPU 같이 보이도록 하여 CPU를 최대한 활용하고자 하는 노력입니다.
        이러한 컨셉은 1개의 요청이 단순하다는 전제를 가집니다.
        일반 PC가 아닌 서버장비에서는 양적으로 엄청나게 많고... 복잡도 면에서 단순부터 복잡까지 다양한 형태의 작업이 수행됩니다.
        이로 인하여 CPU에서 작업을 처리하기 위한 요청이 많고 이는 잦은 Context Switching(이하 CTX)을 유발합니다.
        ctx는 1개의 CPU에 여러개의 작업이 순서대로 들어가 수행되기 위해 작업을 그때그때 교체하여 처리 하는것으로
        많아지면 전체적인 처리성능의 저하를 유발합니다. (EDPS 수업에서 CPU는 시분할 처리 방식이라고 했던 기억을 생각해 보시면....)

        예를 들어 내가 작업 세가지를 동시에 하는데 각 작업을 수행할때 책상을 정리해야 한다면
        몇개의 작업을 동시에 처리할때는 책상을 정리하는 시간이 큰 문제가 아니고 세가지를 순서대로 하는것 보다
        빨리 처리될 수 도 있겟지만 동시 작업량이 점점 늘어나 무한대로 진행하면
        결국 전체 작업시간에서 대부분을 책상을 정리하는 시간으로 소모하게 됩니다.(Over head라고 부르는)
        이러한 기본적인 상식선상에서
        WAS 장비에서 Hyper-Threading은 오히려 성능을 떨어트릴 수 있고
        일반적으로 Server 장비에서는 HT Off를 기본 권장하기도 합니다.
        (HT에 대한 지식수준에 따라 이 부분은 사람들 마다 다르게 생각합니다.... 결국은 고객사이트가 원하는대로 해주는게 진리)

        Q. 서버 가상화 환경에서 4Core를 할당한 VM에는 WAS를 몇개나 만들면 됩니까? (Production환경)
        기본은 위 연산과 동일하게 생각하면 됩니다.
        4 * 0.7 = 2.8 = 3개 이하로 운영하는겁니다.
        다만 가상화 장비에서 CPU를 Over Commit 하는등 Production에 어울리지 않게(?) 운영하고 있다면
        모니터링을 통해서 Bare-metal(물리적인 장비)의 CTX 값이나 CPU 상태를 보고 판단해야 합니다.
        예를들어
        32Core 장비에 WAS VM만 바쁘고 다른 VM이 다 놀고 있다면 전혀 이상이 없겠으나
        Load Avr이 50% 이상인 장비에서 WAS VM이 바쁘게 동작한다면 가상화 장비의 성능에 영향을 받을 수 있습니다.

        Software인 WAS입장에서 Physical 장비의 멀티코어, HT에 대한 가이드는 장비 특성에 너무 많이 의존적이라 사실 가이드를 하면 안됩니다.
        (약은 약사에게 병의 의사에게...를 기억합시다)
        거기다 가상화까지 해 놓는다면 이를 가이드 할 수 는 없습니다.
        다만 기준을 제시 할 수 있으나 절대적이지 않음을 주지시키면서 가이드를 제공해야 합니다.

        .....아.... 울 호갱님들이 내 사이트에 얼마나 들어올지
        일시킨 개발자가 짜놓은 APP 성능이 어떨지
        SQL이 얼마나 빨리 반응할지
        알!수!가! 없다!!
        대체 WAS가 얼마나 부하가 발생할지 사실 알게 무어냐!
        Open전 스트레스테스트와 모니터링만이 살길이다

      3. 구동 정지및 모니터링을 위한 쉡 스크립트를 복사하여 넣는다
        스크립트에 실행권한 추가 및 복사
        [jboss@kwonHost slave]$ pwd
        /jboss/EAP6_Standalone_Script
        [jboss@kwonHost slave]$ chmod +x ./*.sh
        [jboss@kwonHost slave]$ cp /jboss/EAP6_Standalone_Script/* /jboss/domains/standalone1

      4. 로그가 저장될 공간을 만들어준다. 폴더가 없으면 쌓이지 않는다. (스크립트 개선필요)
        cd /jboss/domains/standalone1
        mkdir -p ./log/controllerlog
        mkdir -p ./log/gclog
        mkdir -p ./log/nohup

    4. Standalone(독립실행형) 서버 구성
      1. env.sh 수정
        [jboss@kwonHost standalone1]$ cat env.sh
        #!/bin/sh
        DATE=`date +%Y%m%d%H%M%S`
        export JAVA_HOME=/jboss/jdk
        ##### JBOSS Directory Setup #####
        export JBOSS_HOME=/jboss/jboss-eap-6.2
        export DOMAIN_BASE=/jboss/domains
        export SERVER_NAME=standalone1

        ##### Configration File #####
        #Standalone으로 구성하되 프로파일에 따라 지원이 다름
        #standalone.xml : 지정하지 않으면 기본 적용되는 설정, HA나 추가 subsystem(JMS같은) 미포함
        #standalone-ha.xml : Cluster 및 Loadbalance 을 포함하여 구동됨, subsystem 미포함 <== Cluster 구성시 보통 이거
        #standalone-full.xml : HA는 미포함 sybsystem만 포함하여 구동
        #standalone-full-ha.xml : subsystem과 HA를 모두 포함하여 구동됨
        export CONFIG_FILE=standalone-ha.xml
        export HOST_NAME=standalone1
        export NODE_NAME=$SERVER_NAMEexport PORT_OFFSET=10
        export JBOSS_USER=jboss
        #WAS의 서비스 Port
        ##### Bind Address #####
        export BIND_ADDR=0.0.0.0
        export MGMT_ADDR=0.0.0.0
        #export MGMT_ADDR=127.0.0.1
        #Cluster 구성시 필요한 Muticast 정보
        #export MULTICAST_ADDR=230.1.0.1
        #export JMS_MULTICAST_ADDR=231.7.0.1
        #export MODCLUSTER_MULTICAST_ADDR=224.0.1.105

        #Admin GUI 접속을 위한 정보 (이 부분 검토해서 MGMT 부분하고 스크립트 통합 필요)
        #export CONTROLLER_IP=$MGMT_ADDR
        export CONTROLLER_IP=127.0.0.1
        let CONTROLLER_PORT=9999+$PORT_OFFSET
        export CONTROLLER_PORT
        export LAUNCH_JBOSS_IN_BACKGROUND=true
        export LOG_HOME=$DOMAIN_BASE/$SERVER_NAME/log
        #export LOG_HOME=/ctmsap_log
        ##### JBoss System module and User module directory #####
        export JBOSS_MODULEPATH=$JBOSS_HOME/modules:$JBOSS_HOME/modules.ext

        # JVM Options : Server
        export JAVA_OPTS="-server $JAVA_OPTS"
        # JVM Options : Memory
        export JAVA_OPTS=" $JAVA_OPTS -Xms2048m -Xmx2048m -XX:MaxPermSize=256m"
        export JAVA_OPTS=" $JAVA_OPTS -XX:+PrintGCTimeStamps "
        export JAVA_OPTS=" $JAVA_OPTS -XX:+PrintGCDetails "
        export JAVA_OPTS=" $JAVA_OPTS -Xloggc:$LOG_HOME/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=$LOG_HOME/gclog/java_pid.hprof"
        #JAVA_OPTS="$JAVA_OPTS -Djboss.jvmRoute=jvm1"
        # mod_cluster.jvmroute
        #JAVA_OPTS="$JAVA_OPTS -Djboss.mod_cluster.jvmRoute=node1"
        # Linux Large Page Setting
        #export JAVA_OPTS=" $JAVA_OPTS -XX:+UseLargePages "
        export JAVA_OPTS=" $JAVA_OPTS -verbose:gc"
        export JAVA_OPTS=" $JAVA_OPTS -Xloggc:$LOG_HOME/gclog/gc.log"
        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"
        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.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.bind_addr=$MULTICAST_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 -Dserver.mode=local"
        # Use log4j in application
        export JAVA_OPTS=" $JAVA_OPTS -Dorg.jboss.as.logging.per-deployment=false "
        export JAVA_OPTS=" $JAVA_OPTS -Djboss.server.log.dir=$LOG_HOME"
        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 "================================================"

    5. Admin Console User 생성
      1. Standalone mode로 기동하면 Admin Console(GUI)가 Instance 상에서 기동된다.
      2. 계정을 아래와 같이 생성합니다.
        #add-user.sh [id] [password]
        !! Password가 너무 쉬운경우 생성안됨. 아래쪽 볼드체 부분이 출력되는지 꼭 확인할것 (8자이상 & 영문자 1개이상 & 특수문자1개이상 )
        [jboss@kwonHost standalone1]$ ./add-user.sh admin 123456a!
        ================================================
        JBOSS_HOME=/jboss/jboss-eap-6.2
        DOMAIN_BASE=/jboss/domains
        SERVER_NAME=standalone1
        CONFIG_FILE=standalone-ha.xml
        BIND_ADDR=0.0.0.0
        PORT_OFFSET=10
        MULTICAST_ADDR=
        CONTROLLER=127.0.0.1:10009
        ================================================
        Added user 'admin' to file '/jboss/domains/standalone1/configuration/mgmt-users.properties'
        Added user 'admin' to file '/jboss/jboss-eap-6.2/domain/configuration/mgmt-users.properties'



    6. 기동 스크립트 실행
      /jboss/domains/standalone1/start.sh

      [jboss@kwonHost standalone1]$ ./start.sh
      ================================================
      JBOSS_HOME=/jboss/jboss-eap-6.2
      DOMAIN_BASE=/jboss/domains
      SERVER_NAME=standalone1
      CONFIG_FILE=standalone-ha.xml
      BIND_ADDR=0.0.0.0
      PORT_OFFSET=10
      MULTICAST_ADDR=
      CONTROLLER=127.0.0.1:10009
      ================================================
      -server -Xms256m -Xmx512m -XX:MaxPermSize=128m -XX:+PrintGCTimeStamps -XX:+PrintGCDetails -Xloggc:/jboss/domains/standalone1/log/gclog/gc_20140313013825.log -XX:+UseParallelGC -XX:+ExplicitGCInvokesConcurrent -XX:-HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/jboss/domains/standalone1/log/gclog/java_pid.hprof -verbose:gc -Xloggc:/jboss/domains/standalone1/log/gclog/gc.log -Djava.net.preferIPv4Stack=true -Dorg.jboss.resolver.warning=true -Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000 -Djboss.modules.system.pkgs=org.jboss.byteman -Djava.awt.headless=true -Djboss.server.base.dir=/jboss/domains/standalone1 -Djboss.socket.binding.port-offset=10 -Djboss.node.name=standalone1 -Djboss.bind.address.management=0.0.0.0 -Djboss.bind.address=0.0.0.0 -Djboss.default.multicast.address= -Djboss.messaging.group.address= -Djboss.modcluster.multicast.address= -Dserver.mode=local -Dorg.jboss.as.logging.per-deployment=false -Djboss.server.log.dir=/jboss/domains/standalone1/log
      01:36:08,665 INFO [org.jboss.as] (Controller Boot Thread) JBAS015951: Admin console listening on http://0.0.0.0:10000
      01:36:08,665 INFO [org.jboss.as] (Controller Boot Thread) JBAS015874: JBoss EAP 6.2.0.GA (AS 7.3.0.Final-redhat-14) started in 8681ms - Started 131 of 247 services (115 services are passive or on-demand)
      01:38:17,163 INFO [org.apache.coyote.http11] (MSC service thread 1-1) JBWEB003075: Coyote HTTP/1.1 pausing on: http-/0.0.0.0:8090
      01:38:17,164 INFO [org.apache.coyote.http11] (MSC service thread 1-1) JBWEB003077: Coyote HTTP/1.1 stopping on : http-/0.0.0.0:8090
      01:38:17,281 INFO [org.apache.catalina.core] (MSC service thread 1-2) JBWEB001079: Container org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/] has not been started
      01:38:17,270 INFO [org.jboss.modcluster] (ServerService Thread Pool -- 54) MODCLUSTER000002: Initiating mod_cluster shutdown
      01:38:17,287 INFO [org.jboss.as.connector.subsystems.datasources] (MSC service thread 1-1) JBAS010409: Unbound data source [java:jboss/datasources/ExampleDS]
      01:38:17,304 INFO [org.apache.coyote.ajp] (MSC service thread 1-2) JBWEB003048: Pausing Coyote AJP/1.3 on ajp-/0.0.0.0:8019
      01:38:17,305 INFO [org.apache.coyote.ajp] (MSC service thread 1-2) JBWEB003051: Stopping Coyote AJP/1.3 on ajp-/0.0.0.0:8019
      01:38:17,350 INFO [org.jboss.as] (MSC service thread 1-2) JBAS015950: JBoss EAP 6.2.0.GA (AS 7.3.0.Final-redhat-14) stopped in 160ms
      nohup: redirecting stderr to stdout
      01:38:26,531 INFO [org.jboss.modules] (main) JBoss Modules version 1.3.0.Final-redhat-2
      01:38:27,096 INFO [org.jboss.msc] (main) JBoss MSC version 1.0.4.GA-redhat-1
      01:38:27,277 INFO [org.jboss.as] (MSC service thread 1-2) JBAS015899: JBoss EAP 6.2.0.GA (AS 7.3.0.Final-redhat-14) starting
      01:38:27,287 DEBUG [org.jboss.as.config] (MSC service thread 1-2) Configured system properties:
      SERVER = standalone1
      [Standalone] =
      file.encoding = UTF-8
      file.encoding.pkg = sun.io
      file.separator = /
      java.awt.graphicsenv = sun.awt.X11GraphicsEnvironment
      java.awt.headless = true
      java.awt.printerjob = sun.print.PSPrinterJob
      java.class.path = /jboss/jboss-eap-6.2/jboss-modules.jar
      java.class.version = 50.0
      java.endorsed.dirs = /jboss/jdk1.6.0_45/jre/lib/endorsed
      java.ext.dirs = /jboss/jdk1.6.0_45/jre/lib/ext:/usr/java/packages/lib/ext
      java.home = /jboss/jdk1.6.0_45/jre
      java.io.tmpdir = /tmp
      java.library.path = /jboss/jdk1.6.0_45/jre/lib/amd64/server:/jboss/jdk1.6.0_45/jre/lib/amd64:/jboss/jdk1.6.0_45/jre/../lib/amd64:/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib
      java.net.preferIPv4Stack = true
      java.runtime.name = Java(TM) SE Runtime Environment
      java.runtime.version = 1.6.0_45-b06
      java.specification.name = Java Platform API Specification
      java.specification.vendor = Sun Microsystems Inc.
      java.specification.version = 1.6
      java.util.logging.manager = org.jboss.logmanager.LogManager
      java.vendor = Sun Microsystems Inc.
      java.vendor.url = http://java.sun.com/
      java.vendor.url.bug = http://java.sun.com/cgi-bin/bugreport.cgi
      java.version = 1.6.0_45
      java.vm.info = mixed mode
      java.vm.name = Java HotSpot(TM) 64-Bit Server VM
      java.vm.specification.name = Java Virtual Machine Specification
      java.vm.specification.vendor = Sun Microsystems Inc.
      java.vm.specification.version = 1.0
      java.vm.vendor = Sun Microsystems Inc.
      java.vm.version = 20.45-b01
      javax.management.builder.initial = org.jboss.as.jmx.PluggableMBeanServerBuilder
      javax.xml.datatype.DatatypeFactory = __redirected.__DatatypeFactory
      javax.xml.parsers.DocumentBuilderFactory = __redirected.__DocumentBuilderFactory
      javax.xml.parsers.SAXParserFactory = __redirected.__SAXParserFactory
      javax.xml.stream.XMLEventFactory = __redirected.__XMLEventFactory
      javax.xml.stream.XMLInputFactory = __redirected.__XMLInputFactory
      javax.xml.stream.XMLOutputFactory = __redirected.__XMLOutputFactory
      javax.xml.transform.TransformerFactory = __redirected.__TransformerFactory
      javax.xml.validation.SchemaFactory:http://www.w3.org/2001/XMLSchema = __redirected.__SchemaFactory
      javax.xml.xpath.XPathFactory:http://java.sun.com/jaxp/xpath/dom = __redirected.__XPathFactory
      jboss.bind.address = 0.0.0.0
      jboss.bind.address.management = 0.0.0.0
      jboss.default.multicast.address =
      jboss.home.dir = /jboss/jboss-eap-6.2
      jboss.host.name = kwonhost
      jboss.messaging.group.address =
      jboss.modcluster.multicast.address =
      jboss.modules.dir = /jboss/jboss-eap-6.2/modules
      jboss.modules.system.pkgs = org.jboss.byteman
      jboss.node.name = standalone1
      jboss.qualified.host.name = kwonhost
      jboss.server.base.dir = /jboss/domains/standalone1
      jboss.server.config.dir = /jboss/domains/standalone1/configuration
      jboss.server.data.dir = /jboss/domains/standalone1/data
      jboss.server.deploy.dir = /jboss/domains/standalone1/data/content
      jboss.server.log.dir = /jboss/domains/standalone1/log
      jboss.server.name = kwonhost
      jboss.server.persist.config = true
      jboss.server.temp.dir = /jboss/domains/standalone1/tmp
      jboss.socket.binding.port-offset = 10
      line.separator =
      logging.configuration = file:/jboss/domains/standalone1/configuration/logging.properties
      module.path = /jboss/jboss-eap-6.2/modules:/jboss/jboss-eap-6.2/modules.ext
      org.apache.catalina.connector.URI_ENCODING = UTF-8
      org.apache.catalina.connector.USE_BODY_ENCODING_FOR_QUERY_STRING = true
      org.apache.coyote.ajp.DEFAULT_CONNECTION_TIMEOUT = 60000
      org.apache.coyote.http11.DEFAULT_CONNECTION_TIMEOUT = 60000
      org.apache.coyote.http11.Http11Protocol.MAX_HEADER_SIZE = 8192
      org.jboss.as.logging.per-deployment = false
      org.jboss.boot.log.file = /jboss/domains/standalone1/log/server.log
      org.jboss.resolver.warning = true
      org.xml.sax.driver = __redirected.__XMLReaderFactory
      os.arch = amd64
      os.name = Linux
      os.version = 2.6.32-431.el6.x86_64
      path.separator = :
      server.mode = local
      sun.arch.data.model = 64
      sun.boot.class.path = /jboss/jdk1.6.0_45/jre/lib/resources.jar:/jboss/jdk1.6.0_45/jre/lib/rt.jar:/jboss/jdk1.6.0_45/jre/lib/sunrsasign.jar:/jboss/jdk1.6.0_45/jre/lib/jsse.jar:/jboss/jdk1.6.0_45/jre/lib/jce.jar:/jboss/jdk1.6.0_45/jre/lib/charsets.jar:/jboss/jdk1.6.0_45/jre/lib/modules/jdk.boot.jar:/jboss/jdk1.6.0_45/jre/classes
      sun.boot.library.path = /jboss/jdk1.6.0_45/jre/lib/amd64
      sun.cpu.endian = little
      sun.cpu.isalist =
      sun.io.unicode.encoding = UnicodeLittle
      sun.java.command = /jboss/jboss-eap-6.2/jboss-modules.jar -mp /jboss/jboss-eap-6.2/modules:/jboss/jboss-eap-6.2/modules.ext -jaxpmodule javax.xml.jaxp-provider org.jboss.as.standalone -Djboss.home.dir=/jboss/jboss-eap-6.2 -Djboss.server.base.dir=/jboss/domains/standalone1 -DSERVER=standalone1 -P=/jboss/domains/standalone1/env.properties -c standalone-ha.xml
      sun.java.launcher = SUN_STANDARD
      sun.jnu.encoding = UTF-8
      sun.management.compiler = HotSpot 64-Bit Tiered Compilers
      sun.os.patch.level = unknown
      sun.rmi.dgc.client.gcInterval = 3600000
      sun.rmi.dgc.server.gcInterval = 3600000
      user.country = KR
      user.dir = /jboss/domains/standalone1
      user.home = /jboss
      user.language = ko
      user.name = jboss
      user.timezone = ROK
      01:38:27,293 DEBUG [org.jboss.as.config] (MSC service thread 1-2) VM Arguments: -D[Standalone] -XX:+UseCompressedOops -Xms256m -Xmx512m -XX:MaxPermSize=128m -XX:+PrintGCTimeStamps -XX:+PrintGCDetails -Xloggc:/jboss/domains/standalone1/log/gclog/gc_20140313013825.log -XX:+UseParallelGC -XX:+ExplicitGCInvokesConcurrent -XX:-HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/jboss/domains/standalone1/log/gclog/java_pid.hprof -verbose:gc -Xloggc:/jboss/domains/standalone1/log/gclog/gc.log -Djava.net.preferIPv4Stack=true -Dorg.jboss.resolver.warning=true -Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000 -Djboss.modules.system.pkgs=org.jboss.byteman -Djava.awt.headless=true -Djboss.server.base.dir=/jboss/domains/standalone1 -Djboss.socket.binding.port-offset=10 -Djboss.node.name=standalone1 -Djboss.bind.address.management=0.0.0.0 -Djboss.bind.address=0.0.0.0 -Djboss.default.multicast.address= -Djboss.messaging.group.address= -Djboss.modcluster.multicast.address= -Dserver.mode=local -Dorg.jboss.as.logging.per-deployment=false -Djboss.server.log.dir=/jboss/domains/standalone1/log -Dorg.jboss.boot.log.file=/jboss/domains/standalone1/log/server.log -Dlogging.configuration=file:/jboss/domains/standalone1/configuration/logging.properties
      01:38:29,941 INFO [org.xnio] (MSC service thread 1-1) XNIO Version 3.0.7.GA-redhat-1
      01:38:29,960 INFO [org.jboss.as.server] (Controller Boot Thread) JBAS015888: Creating http management service using socket-binding (management-http)
      01:38:29,962 INFO [org.xnio.nio] (MSC service thread 1-1) XNIO NIO Implementation Version 3.0.7.GA-redhat-1
      01:38:29,988 INFO [org.jboss.remoting] (MSC service thread 1-1) JBoss Remoting version 3.2.18.GA-redhat-1
      01:38:30,037 ERROR [org.jboss.as.controller.management-operation] (Controller Boot Thread) JBAS014613: Operation ("add") failed - address: ([
      ("socket-binding-group" => "standard-sockets"),
      ("socket-binding" => "jgroups-mping")
      ]) - failure description: "JBAS014704: '' is an invalid value for parameter multicast-address. Values must have a minimum length of 1 characters"
      01:38:30,042 ERROR [org.jboss.as.controller.management-operation] (Controller Boot Thread) JBAS014613: Operation ("add") failed - address: ([
      ("socket-binding-group" => "standard-sockets"),
      ("socket-binding" => "jgroups-udp")
      ]) - failure description: "JBAS014704: '' is an invalid value for parameter multicast-address. Values must have a minimum length of 1 characters"
      01:38:30,094 INFO [org.jboss.as.clustering.infinispan] (ServerService Thread Pool -- 31) JBAS010280: Activating Infinispan subsystem.
      01:38:30,116 INFO [org.jboss.as.clustering.jgroups] (ServerService Thread Pool -- 35) JBAS010260: Activating JGroups subsystem.
      01:38:30,186 INFO [org.jboss.as.naming] (ServerService Thread Pool -- 41) JBAS011800: Activating Naming Subsystem
      01:38:30,169 INFO [org.jboss.as.jsf] (ServerService Thread Pool -- 38) JBAS012605: Activated the following JSF Implementations: [main, 1.2]
      01:38:30,247 INFO [org.jboss.as.security] (ServerService Thread Pool -- 46) JBAS013171: Activating Security Subsystem
      01:38:30,300 INFO [org.jboss.as.webservices] (ServerService Thread Pool -- 50) JBAS015537: Activating WebServices Extension
      01:38:30,548 INFO [org.jboss.as.connector.logging] (MSC service thread 1-2) JBAS010408: Starting JCA Subsystem (IronJacamar 1.0.23.Final-redhat-1)
      01:38:30,664 INFO [org.jboss.as.connector.subsystems.datasources] (ServerService Thread Pool -- 27) JBAS010403: Deploying JDBC-compliant driver class org.h2.Driver (version 1.3)
      01:38:30,718 INFO [org.jboss.as.naming] (MSC service thread 1-2) JBAS011802: Starting Naming Service
      01:38:30,722 INFO [org.jboss.as.security] (MSC service thread 1-1) JBAS013170: Current PicketBox version=4.0.19.SP2-redhat-1
      01:38:30,980 INFO [org.jboss.as.mail.extension] (MSC service thread 1-1) JBAS015400: Bound mail session [java:jboss/mail/Default]
      01:38:31,580 INFO [org.apache.coyote.ajp] (MSC service thread 1-1) JBWEB003046: Starting Coyote AJP/1.3 on ajp-/0.0.0.0:8019
      01:38:31,573 INFO [org.apache.coyote.http11] (MSC service thread 1-2) JBWEB003001: Coyote HTTP/1.1 initializing on : http-/0.0.0.0:8090
      01:38:31,598 INFO [org.apache.coyote.http11] (MSC service thread 1-2) JBWEB003000: Coyote HTTP/1.1 starting on: http-/0.0.0.0:8090
      01:38:32,134 INFO [org.jboss.modcluster] (ServerService Thread Pool -- 52) MODCLUSTER000001: Initializing mod_cluster ${project.version}
      01:38:32,297 INFO [org.jboss.modcluster] (ServerService Thread Pool -- 52) MODCLUSTER000032: Listening to proxy advertisements on /224.0.1.105:23364
      01:38:32,395 INFO [org.infinispan.configuration.cache.EvictionConfigurationBuilder] (ServerService Thread Pool -- 31) ISPN000152: Passivation configured without an eviction policy being selected. Only manually evicted entities will be passivated.
      01:38:32,504 INFO [org.infinispan.configuration.cache.EvictionConfigurationBuilder] (ServerService Thread Pool -- 31) ISPN000152: Passivation configured without an eviction policy being selected. Only manually evicted entities will be passivated.
      01:38:33,038 INFO [org.jboss.ws.common.management] (MSC service thread 1-1) JBWS022052: Starting JBoss Web Services - Stack CXF Server 4.2.3.Final-redhat-1
      01:38:33,397 INFO [org.jboss.as.connector.subsystems.datasources] (MSC service thread 1-1) JBAS010400: Bound data source [java:jboss/datasources/ExampleDS]
      01:38:33,755 INFO [org.jboss.as.remoting] (MSC service thread 1-2) JBAS017100: Listening on 0.0.0.0:10009
      01:38:33,820 INFO [org.jboss.as.server.deployment.scanner] (MSC service thread 1-2) JBAS015012: Started FileSystemDeploymentService for directory /jboss/domains/standalone1/deployments
      01:38:33,828 INFO [org.jboss.as.remoting] (MSC service thread 1-2) JBAS017100: Listening on 0.0.0.0:4457
      01:38:34,177 INFO [org.jboss.as] (Controller Boot Thread) JBAS015961: Http management interface listening on http://0.0.0.0:10000/management
      01:38:34,178 INFO [org.jboss.as] (Controller Boot Thread) JBAS015951: Admin console listening on http://0.0.0.0:10000
      01:38:34,182 INFO [org.jboss.as] (Controller Boot Thread) JBAS015874: JBoss EAP 6.2.0.GA (AS 7.3.0.Final-redhat-14) started in 8244ms - Started 131 of 247 services (115 services are passive or on-demand)

    7. 확인
    8. 웹 콘솔에 접속
    9. 서비스 포트에 접속

여기 까지 했다면 


2014년 3월 12일 수요일

EAP6 Domain 구성으로 설치

  1. 용어정의 (이 문서를 볼때 참조)
    1. EAP : Enterprise Application Platform  라고 쓰고 제이보스 와스라고 한다.
    2. AP : EAP의 커뮤니티버젼 (지원 없음, 무료로 사용하는 버젼)
      1. Icon
        AP는 Version 7 까지 http://jboss.org로 진행되었으며
        2013년 11월 WildFly로 별도 분리됨 (http://wildfly.org/)
        2014년 WildFly 8 버젼을 발표로 본격적으로 EAP 와 AP는 분리되어 진행
    3. EWS : Enterprise Web Server 라고 쓰고 제이보스 웹서버 라고 한다. 내부적으로 Apache + HA가 제거된 tomcat 과 Proxy Module이 공식적으로 제공된다.
    4. Master = DomainController = Admin Server  : 도메인내의 slave들과 통신하면서 통합 관리함 (설치는 임의의 서버 한곳에 구성, 필요시 HA 구성 가능함)
    5. Slave = HostController : 서버 벌로 구성되며 상위 Master와 통신하며 하위 Server들을 관리한다. (Production의 경우 일반적으로 서버당 하나)
    6. server = Instance : 실제 WAS 서비스를 제공하는 Process
    7. proxy module : web Server에 인입된 사용자 요청을 WAS에 LoadBalance(LB) 하거나 WAS 장애시 Fail Over 하는 기능을 담당하는 모듈(mod_jk, mod_proxy, mod_cluster)을 통칭
       
  2. 설치준비
    1. EAP6 설치본 
      1. jboss ORG http://www.jboss.org/products/eap ) org에서도 EAP 버젼 다운로드 가능함, 로그인 필요
      2. Redhat https://access.redhat.com/site/downloads/  (파트너사 사이트)
    2. Domain, Std 용 스크립트 
    3. JDK 1.6 또는 1.7 (http://www.oracle.com/technetwork/java/index.html)

  1. 설치순서
    1. JDK 설치
      1. 알아서 잘....
    2.  EAP 압축해제 (/jboss/jboss-eap-6.2)
      #unzip jboss-eap-6.2.0.zip
    3. 2.3 Domain 폴더 복사 (DomainController와 HostContoller 껍대기 만들기)
      1. 도메인 정보를 구성할 폴더, 필요하면 협의해서 임의지정
        #mkdir /jboss/domains 
      2. 설치본에 있는 Template 폴더(/jboss/jboss-eap-6.2/domain)를 복사하여 필요한만큼 생성한다.
        #cp -R /jboss/jboss-eap-6.2/domain /jboss/domains/master (Domain Controller이므로 Domain중 1개만 구성한다. HA가능)
        #cp -R /jboss/jboss-eap-6.2/domain /jboss/domains/slave (HostController 는 서버당 1개씩 구성한다.)
        Icon
        master 또는 DomainController 라고 부르는 서버는
        같은 도메인내의 Slave(Host Controller)와 통신하며
        정책 및 배포 등을 중앙집중적으로 관리할 수 있도록 한다. (Weblogic의 AdminServer와 유사함)
        바이너리는 Master나 Slave나 차이가 없으나(설치본에서 domain 이라는 폴더를 복사하여 사용한다)
        폴더안에 host-master.xml 과 host-slave.xml중 어떤 config를 사용하느냐에 따라 동작이 결정된다.

        slave 또는 HostController 라고 부르는 서버는 
        물리서버(또는 가상화서버)당 1개를 구성하고 
        해당 Slave HostController에 설정파일에 구성정보를 추가함으로써
        하위에 Server(Weblogic의 Managed Server)를 구성하는 형태이다. 
        Weblogic은 Admin - Instance(Managed Server), 
        Jboss는 Master(DomainContoller) - Slave(HostController) - Instance(Server) 구조
        Instance 부분이 weblogic에서 Managed Server이다. ( Jboss는 hostController Process가 각각 서버에 하나씩 추가된다)
      3. 구동 정지및 모니터링을 위한 쉡 스크립트(rockplace 자체제작)를 복사하여 넣는다
        스크립트에 실행권한 추가
        #chmod +x /jboss/EAP6_Domain_Script/master/*
        #chmod +x /jboss/EAP6_Domain_Script/slave/*
      4. master 폴더의 스크립트 : domain Cotroller용으로 사전준비된 스크립트
        slave 폴더의 스크립트 : Managed Server용으로 사전준비된 스크립트
        stendalone 폴더의 스크립트 : Domain이 구성없이 단독 서버 구성용으로 사전준비된 스크립트

        #cp /jboss/EAP6_Domain_Script/master/* /jboss/domain/master
        #cp /jboss/EAP6_Domain_Script/slave/* /jboss/domains/slave

      5. 로그가 저장될 공간을 만들어준다. 폴더가 없으면 쌓이지 않는다. (스크립트 개선필요)
        cd /jboss/domains/master
        mkdir -p ./log/controllerlog
        mkdir -p ./log/gclog

    4. 2.4 Master(DomainController) 구성
      1. 2.4.1 Domain env.sh 수정 
        env.sh는 domain.xml 및 host-master.xml에 분산된 설정정보를 환경변수에 넣어주는 역할을 한다.
        여기저기 흩어진 config를 하나의 환경변수에서 수정함으로써 관리편의를 높이기 위해서이다.

        domain.xml에 정의 되어 있더라도 java -D 옵션으로 추가되는 env.sh의 정보가 우선순위가 높다.

        ex : setenv.sh HOST_NAME 은 host-master.xml 의 <host name="master" xmlns="urn:jboss:domain:1.5"> 에서 name attr에 대응된다.

        Jboss 기동시 환경변수를 지정하는곳이다. JDK 및 Master 또는 Slave Config 위치등을 지정한다.
        /jboss/domains/master/env.sh
        Icon
        [jboss@kwonHost master]$ cat env.sh
        #!/bin/sh
        DATE=`date +%Y%m%d%H%M%S`
        ##### JBOSS Directory Setup #####
        #JDK의 위치
        export JAVA_HOME=/jboss/java/jdk1.6.0_45#JBoss 설치본의 위치 (모듈 및 공통 Jar등의 위치참조시 이곳이 필요)
        export JBOSS_HOME=/jboss/jboss-eap-6.2#Domain 즉 Domain Controller나 HostController 등을 구성한 Home위치를 지정
        #설치 후에는 실제 이곳에서 기동 및 정지 작업을 수행한다.
        export DOMAIN_BASE=/jboss/domains#서버 Name을 지정한다. 이곳에 지정한 이름은 환경변수에 포함되며 하위 Config인 host-master.xml에 정의된 server name보다 우선한다.
        export SERVER_NAME=DomainController
        export DOMAIN_BASE_DIR=$DOMAIN_BASE/$SERVER_NAME
        #log파일의 위치를 지정한다.
        export LOG_HOME=$DOMAIN_BASE_DIR/log#Application Deploy 위치를 지정한다. 폴더 없으면 안뜬다.
        export DEPLOY= /jboss/deploy
        ##### Configration File ######Domain Controller의 경우 아래와 같이 domain.xml과 host-mater.xml을 참고하도록 한다.
        export DOMAIN_CONFIG_FILE=domain.xmlexport HOST_CONFIG_FILE= host-master.xml
        # 서버의 이름
        export HOST_NAME=master
        #노드의이름
        export NODE_NAME= $SERVER_NAME
        #jboss를 기동 정지 할 계정을 지정한다. 다른 계정으로 구동/정지 되지 않도록 체크한다.
        export JBOSS_USER= jboss
        ##### Bind Address #####
        #Listener의 바인드 IP를 지정한다 0.0.0.0 이면 모든 NIC IP에 매핑되어 서비스 된다.
        #간혹 OS특성이나 NIC구성차이로 접속이 되지않는 경우
        (NIC가 여러개 이고 OS 구성이 잘못되어 요청에 대합 답이 이상한 NIC로 돌아 나오는 경우가 있음)
        #서버의 특정 IP로만 서비스하고자 하는 경우 IP를 지정할 수 있다.
        export BIND_ADDR=0.0.0.0
        # Cluster구성시 JBoss가 다른 WAS를 찾아내거나 JMS 메시지 분산등을 위해사용하는 MiltiCast 주소대역정보
        # 멀티케스트는 224.0.1.0 ~ 238.255.255.255 까지 범위를 가진다.(TCP Specification)
        # 주의 : 서버에 여러 NIC가 있고 네트워크 구조상 망분리 형태라면 클러스터 구성시 문제가 될 수 있다.
        # 멀티케스트 처리는 보통 OS에 첫번째로 등록되는 NIC를 사용한다.
        # eth0는 web 스위치, eth1은 was 스위치 등 구분 될 경우 서버의 NIC 순서가 다를 경우 통신이 안될 수 있음
        #어떤놈은 WEB switch로 날리고 어떤놈은 WAS Switch로 멀티케스트할 경우 서로를 못찾을 수 있고
        #망분리의 목적이 트레픽을 분리하기 위한 것인데 클러스터 트레픽은 WAS 트레픽인데 WEB Switch를 타고 구성될 경우 관리상 복잡도가 상승할 수 있다.
        #멀티케스트 구성시에는 기본값이라고 그냥 버려두면 안되고 되도록 망관리자에게 어드바이스를 받거나 기본값 사용가능 여부를 확인 받아야 할 필요

        #WAS Clustering 시 사용할 멀티케스트 주소
        export MULTICAST_ADDR=230.1.0.1
        export MULTICAST_PORT= 55200
        #JMS 클러스터링용 멀티케스트 정보
        export JMS_MULTICAST_ADDR= 231.7.0.1#Apache mod_cluster 통신용 멀티케스트 주소
        #Apache mod_cluster.conf 설정시 같은 서비스끼리 잘 맞추어야 한다.
        #잘못하면 이상한 WAS로 서비스를 전달하여 오류발생가능
        export MODCLUSTER_MULTICAST_ADDR= 224.0.1.105
        #스스로도 DomainController(MASTER)에 접속할 수 있는 정보를 알아야 한다.
        #Domain 구성시에 MASTER를 담당하는 evn.sh 는 자신의 주소와 자신의 포트를 등록
        export DOMAIN_MASTER_ADDR= 127.0.0.1#CLI binding IP
        export DOMAIN_MASTER_PORT= 9999 #CLI binding port (브라우져로 접속하면 파일 다운로드 됨 지정 포트 9990에접속
        #Local HostController 바인드용 IP / 0.0.0.0 전체 IP에 바인딩 / 자기자신을 제어하는것이므로 궂이 IP를 박을 필요 없다는
        #127.0.0.1로 바인딩하면 slave들 뿐 아니라 자기자신도(domainIP를 지정한경우) 접속이 안될 수 있으므로 주의
        #DomainContoller는 역할일뿐 자기자신이 HostController역할을 수행한다. (바이너리는 동일하다 역할만 다를뿐)
        export MGMT_ADDR=0.0.0.0
        # Master(DomainController)설정에서는 DomainController이자 HostController이다.
        export HOST_CONTROLLER_PORT= 9999
        export LAUNCH_JBOSS_IN_BACKGROUND= true
        ##### JBoss System module and User module directory #####
        export JBOSS_MODULEPATH= $JBOSS_HOME/modules:$JBOSS_HOME/modules.ext
        # JVM Options : Server
        export JAVA_OPTS= "-server $JAVA_OPTS"
        # Domain Controller의 메모리 설정이다. 관리대상 서버가 늘어나면 모니터링후 조정 필요
        # JVM Options : Memory
        export JAVA_OPTS=" $JAVA_OPTS -Xms64m -Xmx128m -XX:MaxPermSize= 256m"
        export JAVA_OPTS=" $JAVA_OPTS -XX:+PrintGCTimeStamps "
        export JAVA_OPTS=" $JAVA_OPTS -XX:+PrintGCDetails "
        export JAVA_OPTS=" $JAVA_OPTS -Xloggc:log/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 "
        # 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"
        export JAVA_OPTS=" $JAVA_OPTS -Djava.awt.headless= true"
        export JAVA_OPTS=" $JAVA_OPTS -Djboss.domain.default.config=$DOMAIN_CONFIG_FILE"
        export JAVA_OPTS=" $JAVA_OPTS -Djboss.host.default.config=$HOST_CONFIG_FILE"
        export JAVA_OPTS=" $JAVA_OPTS -Djboss.domain.base.dir=$DOMAIN_BASE_DIR"
        export JAVA_OPTS=" $JAVA_OPTS -Djboss.domain.master.address=$DOMAIN_MASTER_ADDR"
        export JAVA_OPTS=" $JAVA_OPTS -Djboss.domain.master.port=$DOMAIN_MASTER_PORT"
        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.management.native.port=$HOST_CONTROLLER_PORT"
        #export JAVA_OPTS=" $JAVA_OPTS -Djava.nio.channels.spi.SelectorProvider=sun.nio.ch.KQueueSelectorProvider"
        export JAVA_OPTS=" $JAVA_OPTS -Djboss.default.multicast.address=$MULTICAST_ADDR"
        export JAVA_OPTS=" $JAVA_OPTS -Djboss.default.multicast.port=$MULTICAST_PORT"
        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 -Djboss.default.jgroups.stack= tcp"< BR> # Use log4j in application
        export JAVA_OPTS=" $JAVA_OPTS -Dorg.jboss.as.logging.per-deployment=false "
        export JAVA_OPTS=" $JAVA_OPTS -Djboss.server.log.dir= $LOG_HOME/serverlog "
        # Deploy Directory Setting
        export JAVA_OPTS=" $JAVA_OPTS -Djboss.domain.deployment.dir= $DEPLOY "

        echo "================================================"
        echo "JBOSS_HOME=$JBOSS_HOME"
        echo "DOMAIN_BASE=$DOMAIN_BASE"
        echo "SERVER_NAME=$SERVER_NAME"
        echo "DOMAIN_CONFIG_FILE=$DOMAIN_CONFIG_FILE"
        echo "HOST_CONFIG_FILE=$HOST_CONFIG_FILE"
        echo "DOMAIN_CONTROLLER=$DOMAIN_MASTER_ADDR:$DOMAIN_MASTER_PORT"
        echo "================================================"<  


    5. 2.4.2 Admin 계정 생성 (Admin Console에 접속하기 전에 꼭 계정을 만들고 접속한다.)
      1. Console 접속용 Admin 계정을 생성한다. 복사해 넣은 관리 스크립트 중에서 add-user.sh를 사용하면된다.
        #add-user.sh [id] [password]

      2. !! Password가 너무 쉬운경우 생성안됨. 아래쪽 볼드체 부분이 출력되는지 꼭 확인할것


        Icon
        [jboss@kwonHost master]$ ./add-user.sh admin P@ssw0rd
        ================================================
        JBOSS_HOME=/jboss/jboss-eap-6.2
        DOMAIN_BASE=/jboss/domains
        SERVER_NAME=master
        DOMAIN_CONFIG_FILE=domain.xml
        HOST_CONFIG_FILE=host-master.xml
        DOMAIN_CONTROLLER=192.168.56.101:9999
        ================================================
        JAVA_OPTS: -server -Xms64m -Xmx128m -XX:MaxPermSize=256m -XX:+PrintGCTimeStamps -XX:+PrintGCDetails -Xloggc:log/gclog/gc_20140311155028.log -XX:+UseParallelGC -XX:+ExplicitGCInvokesConcurrent -XX:-HeapDumpOnOutOfMemoryError -Djava.net.preferIPv4Stack=true -Dorg.jboss.resolver.warning=true -Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000 -Djboss.modules.system.pkgs=org.jboss.byteman -Djava.awt.headless=true -Djboss.domain.default.config=domain.xml -Djboss.host.default.config=host-master.xml -Djboss.domain.base.dir=/jboss/domains/master -Djboss.domain.master.address=192.168.56.101 -Djboss.domain.master.port=9999 -Djboss.node.name=master -Djboss.bind.address.management=0.0.0.0 -Djboss.bind.address=0.0.0.0 -Djboss.management.native.port=9999 -Djboss.default.multicast.address=230.1.0.1 -Djboss.default.multicast.port=55200 -Djboss.messaging.group.address=231.7.0.1 -Djboss.modcluster.multicast.address=224.0.1.105 -Dorg.jboss.as.logging.per-deployment=false -Djboss.server.log.dir=/jboss/domains/master/log/serverlog -Djboss.domain.deployment.dir=/jboss/deploy -Djboss.server.config.user.dir=/jboss/domains/master/configuration
        Updated user 'admin' to file '/jboss/domains/master/configuration/mgmt-users.properties'



    6. MASTER(Domain Controller) 구동 및 접속확인 
      1. /jboss/domains/master/start.sh 수행
        아래는 정상로그 출력
        Icon
        [jboss@kwonHost master]$ ./start.sh
        ================================================
        JBOSS_HOME=/jboss/jboss-eap-6.2
        DOMAIN_BASE=/jboss/domains
        SERVER_NAME=master
        DOMAIN_CONFIG_FILE=domain.xml
        HOST_CONFIG_FILE=host-master.xml
        DOMAIN_CONTROLLER=192.168.56.101:9999
        ================================================
        -server -Xms64m -Xmx128m -XX:MaxPermSize=256m -XX:+PrintGCTimeStamps -XX:+PrintGCDetails -Xloggc:log/gclog/gc_20140311155748.log -XX:+UseParallelGC -XX:+ExplicitGCIn vokesConcurrent -XX:-HeapDumpOnOutOfMemoryError -Djava.net.preferIPv4Stack=true -Dorg.jboss.resolver.warning=true -Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.d gc.server.gcInterval=3600000 -Djboss.modules.system.pkgs=org.jboss.byteman -Djava.awt.headless=true -Djboss.domain.default.config=domain.xml -Djboss.host.default.con fig=host-master.xml -Djboss.domain.base.dir=/jboss/domains/master -Djboss.domain.master.address=192.168.56.101 -Djboss.domain.master.port=9999 -Djboss.node.name=mast er -Djboss.bind.address.management=0.0.0.0 -Djboss.bind.address=0.0.0.0 -Djboss.management.native.port=9999 -Djboss.default.multicast.address=230.1.0.1 -Djboss.defau lt.multicast.port=55200 -Djboss.messaging.group.address=231.7.0.1 -Djboss.modcluster.multicast.address=224.0.1.105 -Dorg.jboss.as.logging.per-deployment=false -Djbos s.server.log.dir=/jboss/domains/master/log/serverlog -Djboss.domain.deployment.dir=/jboss/deploy
        mkdir: `nohup' 디렉토리를 만들 수 없습니다: 파일이 있습니다
        mv: cannot move `master.out' to `./log/nohup/master.out.20140311155748': 그런 파일이나 디렉터리가 없습니다
        nohup: redirecting stderr to stdout
        JBOSS_HOME: /jboss/jboss-eap-6.2
        JAVA: /jboss/jdk/bin/java
        JAVA_OPTS: -server -Xms64m -Xmx128m -XX:MaxPermSize=256m -XX:+PrintGCTimeStamps -XX:+PrintGCDetails -Xloggc:log/gclog/gc_2014031115 5748.log -XX:+UseParallelGC -XX:+ExplicitGCInvokesConcurrent -XX:-HeapDumpOnOutOfMemoryError -Djava.net.preferIPv4Stack=true -Dorg.jboss.resolver.warning=true -D sun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000 -Djboss.modules.system.pkgs=org.jboss.byteman -Djava.awt.headless=true -Djboss.domain. default.config=domain.xml -Djboss.host.default.config=host-master.xml -Djboss.domain.base.dir=/jboss/domains/master -Djboss.domain.master.address=192.168.56.101 -Djb oss.domain.master.port=9999 -Djboss.node.name=master -Djboss.bind.address.management=0.0.0.0 -Djboss.bind.address=0.0.0.0 -Djboss.management.native.port=9999 -Djboss .default.multicast.address=230.1.0.1 -Djboss.default.multicast.port=55200 -Djboss.messaging.group.address=231.7.0.1 -Djboss.modcluster.multicast.address=224.0.1.105 -Dorg.jboss.as.logging.per-deployment=false -Djboss.server.log.dir=/jboss/domains/master/log/serverlog -Djboss.domain.deployment.dir= /jboss/deploy
        =========================================================================
        15:57:49,328 INFO [org.jboss.modules] (main) JBoss Modules version 1.3.0.Final-redhat-2
        15:57:49,546 INFO [org.jboss.as.process.Host Controller.status] (main) JBAS012017: Starting process 'Host Controller'[Host Controller] 15:57:50,376 INFO [org.jboss.modules] (main) JBoss Modules version 1.3.0.Final-redhat-2
        [Host Controller] 15:57:50,517 INFO [org.jboss.msc] (main) JBoss MSC version 1.0.4.GA-redhat-1
        [Host Controller] 15:57:50,645 INFO [org.jboss.as] (MSC service thread 1-1) JBAS015899: JBoss EAP 6.2.0.GA (AS 7.3.0.Final-redhat-14) starting
        [Host Controller] 15:57:51,745 INFO [org.xnio] (MSC service thread 1-2) XNIO Version 3.0.7.GA-redhat-1
        [Host Controller] 15:57:51,767 INFO [org.xnio.nio] (MSC service thread 1-2) XNIO NIO Implementation Version 3.0.7.GA-redhat-1
        [Host Controller] 15:57:51,791 INFO [org.jboss.as] (Controller Boot Thread) JBAS010902: Creating http management service using network interface (management) port ( 9990) securePort (-1)
        [Host Controller] 15:57:51,825 INFO [org.jboss.remoting] (MSC service thread 1-2) JBoss Remoting version 3.2.18.GA-redhat-1
        [Host Controller] 15:57:51,973 INFO [org.jboss.as.remoting] (MSC service thread 1-2) JBAS017100: Listening on 0.0.0.0:9999[Host Controller] 15:57:54,411 INFO [org.jboss.as] (Controller Boot Thread) JBAS015961: Http management interface listening on http://0.0.0.0:9990/management
        [Host Controller] 15:57:54,413 INFO [org.jboss.as] (Controller Boot Thread) JBAS015951: Admin console listening on http://0.0.0.0:9990
        [Host Controller] 15:57:54,414 INFO [org.jboss.as] (Controller Boot Thread) JBAS015874: JBoss EAP 6.2.0.GA (AS 7.3.0.Final-redhat-14) (Host Controller) started in 4 797ms - Started 12 of 12 services (0 services are passive or on-demand)
      2. 접속확인
        http://192.168.56.101:9990/ (아래 로그인 창 안나오고 welcom 화면 나오면 계정이 없는것이므로 계정을 추가한다.)
      3. 정상 로그인 화면

    7. 2.5 Slave 설정
      1. 2.5.1 slave env.sh 수정 
        /jboss/domains/slave/env.sh
      2. DomainController(Master)의 env.sh와 거의 유사하나 조금다르다 볼드 부분주의
        Icon
        [jboss@kwonHost slave]$ cat env.sh
        #!/bin/sh
        DATE=`date +%Y%m%d%H%M%S`
        ##### JBOSS Directory Setup #####
        export JAVA_HOME=/jboss/java/jdk1.6.0_45
        export JBOSS_HOME=/jboss/jboss-eap-6.2
        export DOMAIN_BASE=/jboss/domains
        #아래 이름은 domain path정보와 연결된다. /jboss/domains/slave1 으로 구성해야함
        export SERVER_NAME=slave1 
        export DOMAIN_BASE_DIR=$DOMAIN_BASE/$SERVER_NAME
        ##### Configration File #####
        export HOST_CONFIG_FILE=host-slave.xml
        export HOST_NAME=slave1
        export NODE_NAME=$SERVER_NAME
        export JBOSS_USER=jboss
        ##### Bind Address #####
        export BIND_ADDR=0.0.0.0
        export MULTICAST_ADDR=230.1.0.1
        export JMS_MULTICAST_ADDR=231.7.0.1
        export MODCLUSTER_MULTICAST_ADDR=224.0.1.105
        #Domain Controller(Production이라면 원격)의 IP와 포트를 적어준다.
        export DOMAIN_MASTER_ADDR=192.168.56.101 #${jboss.domain.master.address}
        export DOMAIN_MASTER_PORT=9999 #${jboss.domain.master.port:9999}
        #Slave 역할인 HostController 자기자신에 접근하기위한 IP를 등록한다. 이건 사실 무엇때문에 속성을 관리하는지 모를일....
        #0.0.0.0 은 모든 소켓에 바인딩 되므로 서버에 할당된 모든 IP로 CLI 수행가능
        #x.x.x.x 특정 IP할당시 해당 IP로 접근하여 CLI 접속가능
        #127.0.0.1 은 Local 바인딩이므로 자기 서버에서만 CLI 수행 가능
        #remote에서 CLI를 수행해야 한다면 0.0.0.0 이나 IP를 지정해야한다.
        export MGMT_ADDR=127.0.0.1 #Local CLIIP# slave로 동작하는 서버 자기자신도 HostController를 가지고 있으므로 해당 포트를 넣어준다.
        export HOST_CONTROLLER_PORT= 19999 #Local CLI PORT
        export LAUNCH_JBOSS_IN_BACKGROUND=true
        ##### JBoss System module and User module directory #####
        export JBOSS_MODULEPATH=$JBOSS_HOME/modules:$JBOSS_HOME/modules.ext
        # JVM Options : Server
        export JAVA_OPTS="-server $JAVA_OPTS"
        # JVM Options : Memory
        export JAVA_OPTS=" $JAVA_OPTS -Xms64m -Xmx128m -XX:MaxPermSize=256m -Xss256k"
        export JAVA_OPTS=" $JAVA_OPTS -XX:+PrintGCTimeStamps "
        export JAVA_OPTS=" $JAVA_OPTS -XX:+PrintGCDetails "
        export JAVA_OPTS=" $JAVA_OPTS -Xloggc:log/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 "
        # 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"
        export JAVA_OPTS=" $JAVA_OPTS -Djava.awt.headless=true"
        export JAVA_OPTS=" $JAVA_OPTS -Djboss.domain.default.config=$DOMAIN_CONFIG_FILE"
        export JAVA_OPTS=" $JAVA_OPTS -Djboss.host.default.config=$HOST_CONFIG_FILE"
        export JAVA_OPTS=" $JAVA_OPTS -Djboss.domain.base.dir=$DOMAIN_BASE_DIR"
        export JAVA_OPTS=" $JAVA_OPTS -Djboss.domain.master.address=$DOMAIN_MASTER_ADDR"
        export JAVA_OPTS=" $JAVA_OPTS -Djboss.domain.master.port=$DOMAIN_MASTER_PORT"
        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.management.native.port=$HOST_CONTROLLER_PORT"
        #export JAVA_OPTS=" $JAVA_OPTS -Djava.nio.channels.spi.SelectorProvider=sun.nio.ch.KQueueSelectorProvider"
        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 -Djboss.default.jgroups.stack=tcp"
        # Use log4j in application
        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 "DOMAIN_CONFIG_FILE=$DOMAIN_CONFIG_FILE"
        echo "HOST_CONFIG_FILE=$HOST_CONFIG_FILE"
        echo "DOMAIN_CONTROLLER=$DOMAIN_MASTER_ADDR:$DOMAIN_MASTER_PORT"
        echo "================================================"
다 되었음
띄우고 Admin Console에서 서버들의 정보가 정상적으로 올라오는지 확인
아래 보면 
Master(Domain Controller)
kwonhost(Host Controller)  : 구성시 jboss.host.name 속성 (domains/master/configuration/host-master.xml 의 host Element) 이 없으면 OS $HOSTNAME을 들고 올라온다. 필요시 지정(스크립트에서 지정하도록 변경 예정임)
server-one(Instance) : 초기 제공되는 Config 파일에 sample로 등록되어 있는 Instance 삭제해도 무방하다
server-two(Instance) : 초기 제공되는 Config 파일에 sample로 등록되어 있는 Instance 삭제해도 무방하다
가 구성된 것을 확인할 수 있다.

끝.