이전 목차 색인 다음 |
Sun Java System Message Queue 3.5 SP1 관리 설명서

> ## 9장
> 메시지 서비스 분석 및 조정

> 이 장에서는 메시징 응용 프로그램의 성능을 최적화하기 위해 Message Queue 서비스를 분석하고 조정하는 방법에 대한 여러 항목을 다룹니다. 이 장은 다음 항목으로 구성되어 있습니다.

> - 성능 정보
> - 성능에 영향을 미치는 요소
> - 메시지 서버 모니터링
> - 성능 문제 해결
> - 성능 향상을 위한 구성 조정

> ##

> 성능 정보

> ### 성능 조정 프로세스

> 메시징 응용 프로그램의 성능은 응용 프로그램과 Message Queue 서비스 사이의 상호 작용에 따라 달라집니다. 따라서 성능을 최대화하려면 응용 프로그램 개발자와 관리자가 함께 노력해야 합니다.

> 성능 최적화 프로세스는 응용 프로그램 설계에서 시작되어 응용 프로그램 배포 이후의 메시지 서비스 조정에 이르기까지 계속됩니다. 성능 조정 프로세스에는 다음 단계가 포함됩니다.

> - 응용 프로그램의 성능 요구 사항 정의
> - 성능에 영향을 미치는 요소(특히 안정성과 성능 간의 균형)를 고려하여 응용 프로그램 설계
> - 기본 성능 측정 설정
> - 성능 최적화를 위해 메시지 서비스 조정 또는 재구성

> 위에서 설명한 프로세스는 자주 반복됩니다. 응용 프로그램 배포 중에 Message Queue 관리자는 메시지 서버가 응용 프로그램의 일반 성능 요구 사항에 적합한지 평가합니다. 벤치마크 테스트가 이러한 요구 사항을 충족시키는 경우 관리자는 이 장에서 설명한 대로 시스템을 조정할 수 있습니다. 하지만 벤치마크 테스트가 성능 요구 사항을 충족시키지 못하는 경우 응용 프로그램을 재설계하거나 배포 구조를 수정해야 합니다.

> ### 성능 요소

> 일반적으로 성능은 메시지 서비스가 생성자의 메시지를 사용자에게 전달하는 속도와 효율성에 대한 측정입니다. 하지만 사용자의 필요에 따라 중요할 수 있는 여러 다른 성능 요소가 있습니다.

> 연결 로드 메시지 생성자나 메시지 사용자 수 또는 시스템이 지원할 수 있는 동시 연결 수입니다.

> 메시지 처리량 메시징 시스템을 통해 전달될 수 있는 초당 메시지 수 또는 메시지 바이트입니다.

> 대기 시간 메시지 생성자로부터 메시지 사용자에게 특정 메시지를 전달하는 데 걸리는 시간입니다.

> 안정성 메시지 서비스의 전체적인 가용성 또는 로드량이 많거나 장애가 발생하는 경우 메시지 서비스 성능이 유연하게 감소되는 정도입니다.

> 효율성 메시지 전달의 효율성, 즉 사용된 계산 자원을 기준으로 메시지 처리량을 측정한 것입니다.

> 이러한 성능의 여러 요소들은 일반적으로 상호 연관됩니다. 메시지 처리량이 높으면 메시지가 메시지 서버에서 백로그될 가능성이 적어지므로 대기 시간이 낮아집니다(단일 메시지가 매우 빠르게 전달될 수 있음). 하지만 대기 시간은 통신 연결 속도, 메시지 서버 처리 속도, 클라이언트 처리 속도 등 많은 요소에 따라 달라질 수 있습니다.

> 어느 경우든 여러 다른 성능 요소가 있습니다. 어떤 성능 요소가 가장 중요한지는 일반적으로 특정 응용 프로그램의 요구 사항에 따라 달라집니다.

> ### 벤치마크

> 벤치마크는 메시징 응용 프로그램을 위한 테스트 프로그램을 만들고 이 테스트 프로그램의 메시지 처리량이나 기타 성능 요소를 측정하는 프로세스입니다.

> 예를 들어, 일정 수의 생성자 클라이언트가 일정 수의 연결, 세션 및 메시지 생성자를 사용하여 메시징 응용 프로그램 설계에 따라 일정 수의 대기열이나 주제에 표준 크기의 지속성 또는 비지속성 메시지를 지정된 속도로 보내는 테스트 프로그램을 만들 수 있습니다. 마찬가지로 테스트 프로그램에는 일정 수의 사용자 클라이언트가 포함되며, 이 사용자 클라이언트는 일정 수의 연결, 세션 및 특정 확인 모드로 테스트 프로그램의 대상에서 메시지를 사용하는 (특정 유형의) 메시지 사용자를 사용합니다.

> 표준 테스트 프로그램을 사용하면 메시지 생성에서 사용까지 걸리는 시간이나 평균 메시지 처리 속도를 측정할 수 있으며 시스템을 모니터하여 연결 스레드 사용, 메시지 저장소 데이터, 메시지 흐름 데이터 및 기타 관련 메트릭을 살펴볼 수 있습니다. 그런 다음 성능에 부정적인 영향을 미칠 때까지 메시지 생성 속도, 메시지 생성자 수 또는 기타 변수를 증가시켜볼 수 있습니다. 달성할 수 있는 최대 처리량이 메시지 서비스 구성에 대한 벤치마크입니다.

> 이 벤치마크를 사용하여 테스트 프로그램의 일부 특성을 수정할 수 있습니다. 성능에 영향을 미칠 수 있는 모든 요소("성능에 영향을 미치는 응용 프로그램 설계 요소" 참조)를 조심스럽게 제어하여 이러한 요소들 중 일부를 변경했을 때 벤치마크에 미치는 영향을 살펴볼 수 있습니다. 예를 들어, 연결 수나 메시지 크기를 5배나 10배 증가시켜 성능에 미치는 영향을 살펴볼 수 있습니다.

> 이와 반대로 응용 프로그램 기반 요소를 일정하게 유지하면서 제어 가능한 방식으로 브로커 구성을 변경하고(예: 연결 등록 정보, 스레드 풀 등록 정보, JVM 메모리 제한, 제한 동작, 기본 제공 지속성 대 플러그 인 지속성 등을 변경) 이러한 변경이 성능에 미치는 영향을 살펴볼 수 있습니다.

> 이러한 응용 프로그램 벤치마크는 메시지 서비스를 조정하여 배포된 응용 프로그램의 성능을 높이고자 할 때 유용한 정보를 제공합니다. 벤치마크를 사용하면 한 가지 변경 사항이나 일련의 변경 사항이 미치는 영향을 좀 더 정확하게 예상할 수 있습니다.

> 일반적으로 벤치마크는 제어된 테스트 환경에서 메시지 서비스가 안정될 정도의 충분한 기간 동안 실행해야 합니다. (Java 코드를 기계 코드로 변환하는 JIT (Just-In-Time) 컴파일에 의해 시작 시 성능에 부정적인 영향을 미칩니다.)

> ### 기본 사용 패턴

> 일단 메시징 응용 프로그램이 배포되어 실행 중이면 기본 사용 패턴을 설정하는 것이 중요합니다. 최대 수요가 발생하는 시기를 알아 해당 수요를 수량화할 수 있습니다. 예를 들어, 수요는 일반적으로 최종 사용자 수, 활동 수준, 시간 또는 이러한 모든 것에 의해 변동됩니다.

> 기본 사용 패턴을 설정하려면 메시지 서버를 오랫동안 모니터하여 연결 수, 브로커(또는 특정 대상)에 저장되어 있는 메시지 수, 브로커(또는 특정 대상)에 들어오고 나가는 메시지 흐름, 활성 사용자의 수 등의 데이터를 확인해야 합니다. 메트릭 데이터에서 제공하는 평균 값과 최대 값을 사용할 수도 있습니다.

> 이러한 기본 메트릭을 설계 예측과 비교하여 확인하는 것이 중요합니다. 이렇게 함으로써 클라이언트 코드가 제대로 작동하는지 확인할 수 있습니다. 예를 들어, 연결이 열려 있는 상태로 남아 있지 않은지 또는 사용된 메시지가 확인되지 않은 상태로 남아 있지 않은지 확인할 수 있습니다. 이러한 코딩 오류는 메시지 서버 자원을 사용하므로 성능에 상당한 영향을 미칠 수 있습니다.

> 기본 사용 패턴을 통해 최적 성능을 위해 시스템을 조정하는 방법을 결정할 수 있습니다. 예를 들어, 한 대상이 다른 대상에 비해 훨씬 더 많이 사용되는 경우 해당 대상에 다른 대상보다 더 높은 메시지 메모리 제한을 설정하거나 상황에 맞게 제한 동작을 조정할 수 있습니다. 필요한 연결 수가 최대 스레드 풀 크기에서 허용하는 연결 수보다 훨씬 더 큰 경우 스레드 풀 크기를 늘리거나 공유 스레드 모델을 적용할 수 있습니다. 최대 메시지 흐름이 평균 흐름보다 훨씬 큰 경우 메모리가 부족할 때 사용하는 제한 동작에 영향을 미칠 수 있습니다.

> 일반적으로 사용 패턴에 대해 더 많이 알수록 이러한 패턴에 맞춰 시스템을 조정하고 향후 요구에 더 잘 대비할 수 있습니다.

> ##

> 성능에 영향을 미치는 요소

> 두 가지 주요 성능 표시기인 메시지 대기 시간과 메시지 처리량은 일반 메시지가 메시지 전달 프로세스의 여러 단계를 완료하는 데 걸리는 시간에 따라 달라집니다. 아래에서 안정적으로 전달되는 지속성 메시지인 경우에 대해 이러한 단계를 보여 줍니다. 그 단계는 다음 그림과 같습니다.

> 그림 9-1 Message Queue 서비스를 통한 메시지 전달

> 1. 메시지가 생성자 클라이언트에서 메시지 서버로 전달됩니다.
> 2. 메시지 서버가 메시지를 읽습니다.
> 3. 안정성을 위해 메시지가 영구 저장소에 저장됩니다.
> 4. 안정성을 위해 메시지 서버가 메시지 수신을 확인합니다.
> 5. 메시지 서버가 메시지를 라우팅합니다.
> 6. 메시지 서버가 메시지를 씁니다.
> 7. 메시지가 메시지 서버에서 사용자 클라이언트로 전달됩니다.
> 8. 안정성을 위해 사용자 클라이언트가 메시지 수신을 확인합니다.
> 9. 안정성을 위해 메시지 서버가 클라이언트 확인을 처리합니다.
> 10. 메시지 서버가 클라이언트 확인이 처리되었는지 확인합니다.

> 이러한 단계는 순차적이므로 어느 단계든 생성자 클라이언트에서 사용자 클라이언트로 메시지를 전달할 때 병목 현상을 일으킬 수 있습니다. 이러한 단계들은 대부분 네트워크 대역폭, 컴퓨터 처리 속도, 메시지 서버 구조 등 메시징 시스템의 물리적 특성에 영향을 받습니다. 하지만 일부 단계는 메시징 응용 프로그램의 특성과 메시징 응용 프로그램이 요구하는 안정성 수준에 따라서도 달라집니다.

> 다음 하위 절에서는 응용 프로그램 설계 요소와 메시징 시스템 요소가 성능에 미치는 영향을 설명합니다. 응용 프로그램 설계와 메시징 시스템 요소가 메시지 전달에서 긴밀하게 상호 작용하지만 각 범주에 대해 별도로 고려합니다.

> ### 성능에 영향을 미치는 응용 프로그램 설계 요소

> 응용 프로그램 설계 결정은 전체 메시징 성능에 상당한 영향을 미칠 수 있습니다.

> 성능에 영향을 미치는 가장 중요한 요소는 메시지 전달의 안전성에 영향을 미치는 요소입니다. 이러한 요소는 다음과 같습니다.

> - 전달 모드(지속성/비지속성 메시지)
> - 트랜잭션 사용
> - 확인 모드
> - 영구 가입 및 비영구 가입

> 성능에 영향을 미치는 다른 응용 프로그램 설계 요소는 다음과 같습니다.

> - 선택기 사용(메시지 필터링)
> - 메시지 크기
> - 메시지 본문 유형

> 다음 절에서는 이러한 요소 각각이 메시징 성능에 미치는 영향을 설명합니다. 일반적으로 성능과 안정성은 동시에 얻을 수 없습니다. 즉, 안정성을 높이는 요소가 성능을 저하시키는 경향이 있습니다.

> 다음 표는 여러 응용 프로그램 설계 요소가 일반적으로 메시징 성능에 어떤 영향을 미치는지 보여 줍니다. 이 표에서는 두 가지 시나리오(높은 안정성/낮은 성능 시나리오와 높은 성능/낮은 안정성 시나리오)와 각각을 특징 지우는 응용 프로그램 설계 요소의 선택을 보여 줍니다. 이러한 양극단 사이에는 안정성과 성능 모두에 영향을 미치는 여러 선택 사항과 상충이 있습니다.

> 표 9-1 높은 안정성 및 높은 성능 시나리오 비교

> 응용 프로그램 설계 요소 | 높은 안정성 낮은 성능 시나리오 | 높은 성능 낮은 안정성 시나리오
> --- | --- | ---
> 전달 모드 | 지속성 메시지 | 비지속성 메시지
> 트랜잭션 사용 | 트랜잭션된 세션 | 트랜잭션 없음
> 확인 모드 | AUTO_ACKNOWLEDGE 또는 CLIENT_ACKNOWLEDGE | DUPS_OK_ACKNOWLEDGE
> 영구/비영구 가입 | 영구 가입 | 비영구 가입
> 선택기 사용 | 메시지 필터링 | 메시지 필터링 없음
> 메시지 크기 | 작은 메시지 | 큰 메시지
> 메시지 본문 유형 | 복합 본문 유형 | 단순 본문 유형

> 주 | 다음 그래프의 성능 데이터는 1002Mhz CPU가 두 개 있는 Solaris 8 시스템에서 파일 기반 지속성을 사용하여 생성되었습니다. 성능 테스트는 JIT (Just-In-Time) 컴파일러가 시스템을 최적화하고 지속성 데이터베이스를 사용할 수 있도록 먼저 Message Queue 브로커를 준비했습니다. 브로커가 준비되면 30초 동안 단일 생성자와 단일 사용자를 만들고 메시지를 생성했습니다. 사용자가 생성된 모든 메시지를 받는 데 필요한 시간을 기록했고 처리 속도(초당 메시지)를 계산했습니다. 표 9-1에 표시된 응용 프로그램 설계 요소의 다른 조합에 대해 이 시나리오를 반복했습니다.

> #### 전달 모드(지속성/비지속성 메시지)

> "안정적인 메시징"에서 설명한 대로 지속성 메시지는 메시지 서버에 오류가 발생하는 경우 메시지 전달을 보장합니다. 브로커는 의도된 모든 사용자가 메시지 사용을 확인할 때까지 메시지를 영구 저장소에 저장합니다.

> 다음과 같은 이유로 브로커의 지속성 메시지 처리가 비지속성 메시지 처리보다 느립니다.

> - 브로커는 브로커에 오류가 발생하더라도 지속성 메시지가 손실되지 않도록 안정적으로 메시지를 저장해야 합니다.
> - 브로커는 수신되는 각 지속성 메시지의 수신을 확인해야 합니다. 메시지를 생성하는 메소드가 예외 없이 반환되면 브로커로의 전달이 보장됩니다.
> - 클라이언트 확인 모드에 따라 브로커는 지속성 메시지를 사용자 클라이언트가 확인했는지 확인해야 할 수 있습니다.

> 지속성 및 비지속성 모드간 성능 차이가 상당할 수 있습니다. 그림 9-2는 두 가지 안정적 전달 사례(대기열과 영구 가입을 사용하는 주제 양쪽에 전달되는 10k 크기의 메시지)에서 지속성 메시지와 비지속성 메시지에 대한 처리량을 비교합니다. 두 가지 경우 모두 AUTO_ACKNOWLEDGE 확인 모드를 사용합니다.

> 그림 9-2 전달 모드의 성능 영향

> #### 트랜잭션 사용

> 트랜잭션은 트랜잭션된 세션에서 생성된 모든 메시지와 트랜잭션된 세션에서 사용된 모든 메시지가 하나의 단위로 처리되거나 처리되지 않도록(롤백되도록) 보장합니다.

> Message Queue는 로컬 트랜잭션과 분산 트랜잭션을 모두 지원합니다(자세한 내용은 각각 "로컬 트랜잭션" 및 "분산 트랜잭션" 참조).

> 트랜잭션된 세션에서의 메시지 생성이나 확인은 다음과 같은 이유 때문에 트랜잭션되지 않은 세션보다 느립니다.

> - 생성된 각 메시지와 함께 추가 정보를 저장해야 합니다.
> - 가입이 없는 주제 대상에 전달되는 지속성 메시지는 일반적으로 삭제되지만 트랜잭션이 시작될 때 가입에 대한 정보를 사용할 수 없는 경우와 같이 일반적으로는 그럴 수 없는데도 트랜잭션의 메시지가 저장되는 경우가 있습니다.
> - 트랜잭션이 완료될 때 트랜잭션 내의 메시지 사용과 확인에 대한 정보를 저장하고 처리해야 합니다.

> #### 확인 모드

> JMS 메시지 전달의 안정성을 보장하는 한 가지 방법은 Message Queue 메시지 서버가 클라이언트에 전달한 메시지의 사용을 클라이언트가 확인하는 것입니다("안정적인 전달: 확인 및 트랜잭션" 참조).

> 클라이언트의 메시지 확인 없이 세션이 닫히거나 확인이 처리되기 전에 메시지 서버에 오류가 발생하는 경우 브로커는 해당 메시지를 재전송하여 JMSRedelivered 플래그를 설정합니다.

> 트랜잭션되지 않은 세션의 경우 클라이언트는 각각 고유한 성능 특성을 가지는 다음과 같은 세 가지 확인 모드 중 하나를 선택할 수 있습니다.

> - AUTO_ACKNOWLEDGE. 사용자가 메시지를 처리하면 시스템이 자동으로 메시지를 확인합니다. 이 모드는 공급자 오류 후 최대 한 개의 재전송 메시지를 보장합니다.
> - CLIENT_ACKNOWLEDGE. 응용 프로그램이 메시지가 확인되는 시점을 제어합니다. 이전 확인 이후 해당 세션에서 처리된 모든 메시지가 확인됩니다. 일련의 확인을 처리하는 동안 메시지 서버가 실패하는 경우 해당 그룹에서 하나 이상의 메시지가 재전송될 수 있습니다.
> - DUPS_OK_ACKNOWLEDGE. 이 모드는 시스템에게 메시지를 느리게 확인하도록 명령합니다. 공급자 오류 후 여러 메시지가 재전송될 수 있습니다.

> (CLIENT_ACKNOWLEDGE 모드를 사용하는 것은 처리 중에 공급자 오류가 발생하는 경우 모든 확인이 함께 처리되도록 보장하지 않는다는 점을 제외하고는 트랜잭션 사용과 유사합니다.)

> 성능은 다음과 같은 이유로 확인 모드의 영향을 받습니다.

> - AUTO_ACKNOWLEDGE와 CLIENT_ACKNOWLEDGE 모드에서는 브로커와 클라이언트 사이에 추가 제어 메시지가 필요합니다. 추가 제어 메시지는 처리 오버헤드를 추가하고 JMS 페이로드 메시지를 방해할 수 있으므로 처리가 지연됩니다.
> - AUTO_ACKNOWLEDGE와 CLIENT_ACKNOWLEDGE 모드에서는 클라이언트가 추가 메시지를 사용할 수 있으려면 브로커가 클라이언트 확인을 처리했다고 확인할 때까지 대기해야 합니다. (이와 같은 브로커 확인은 브로커가 실수로 이 메시지를 재전송하지 않도록 보장합니다.)
> - 사용자가 받은 모든 지속성 메시지에 대한 확인 정보로 Message Queue 영구 저장소를 업데이트해야 하므로 성능이 감소됩니다.

> #### 영구 가입 및 비영구 가입

> 주제 대상의 가입자는 "게시/가입(주제 대상)"에 설명되어 있는 대로 영구 가입자와 비영구 가입자의 두 가지 범주로 구분됩니다.

> 영구 가입은 다음과 같은 이유 때문에 안정성은 높이지만 처리량은 떨어뜨립니다.

> - Message Queue 메시지 서버는 메시지 서버에 오류가 발생하더라도 복구 후 목록을 사용할 수 있도록 각 영구 가입에 할당된 메시지 목록을 영구 저장해야 합니다.
> - 메시지 서버에 오류가 발생하더라도 복구 후 해당 사용자가 활성화되면 메시지를 계속 전달할 수 있도록 영구 가입의 지속성 메시지가 영구적으로 저장됩니다. 반면 비영구 가입의 지속성 메시지는 영구 저장되지 않습니다. 메시지 서버에 오류가 발생하는 경우 해당 사용자 연결이 끊기며 메시지가 전달되지 않습니다.

> 그림 9-3은 지속성 및 비지속성 10k 크기 메시지의 두 가지 경우에서 영구 및 비영구 가입을 사용하는 주제 대상의 처리량을 비교합니다. 두 가지 경우 모두 AUTO_ACKNOWLEDGE 확인 모드를 사용합니다.

> 그림 9-3에서 지속성 메시지인 경우에만 영구 가입 사용의 성능 영향이 확연한 것을 알 수 있으며 그 이유는 위에서 설명한 대로 지속성 메시지가 영구 가입에 대해서만 영구 저장되기 때문입니다.

> 그림 9-3 가입 유형의 성능 영향

> #### 선택기 사용(메시지 필터링)

> 응용 프로그램 개발자가 특정 사용자들을 메시지 집합의 대상으로 지정할 수 있습니다. 이는 메시지 집합마다 고유 대상을 지정하거나, 단일 대상을 사용하여 각 사용자에 대해 하나 이상의 선택기를 등록하여 수행할 수 있습니다.

> 선택기는 해당 문자열과 일치하는 등록 정보 값("JMS 메시지 구조" 참조)을 갖는 메시지만 특정 사용자에게 전달되도록 요청하는 문자열입니다. 예를 들어 선택기 NumberOfOrders >1은 NumberOfOrders 등록 정보 값이 2이상인 메시지만 전달합니다.

> 선택기를 사용하여 사용자를 등록하면 각 메시지를 처리하는 데 추가 처리가 필요하므로 여러 대상을 사용하는 것에 비해 성능이 떨어집니다. 선택기를 사용하는 경우 선택기가 이후의 메시지와 일치될 수 있도록 구문 분석되어야 합니다. 또한 각 메시지가 라우팅될 때 각 메시지의 메시지 등록 정보를 검색하고 선택기와 비교해야 합니다. 그러나 선택기를 사용하면 메시징 응용 프로그램의 융통성이 증가합니다.

> #### 메시지 크기

> 생성자 클라이언트에서 브로커로 그리고 브로커에서 사용자 클라이언트로 더 많은 데이터가 전달되어야 하고 지속성 메시지의 경우 더 큰 메시지를 저장해야 하므로 메시지 크기는 성능에 영향을 미칩니다.

> 그러나 작은 메시지들을 단일 메시지로 일괄 처리하면 개별 메시지의 라우팅과 처리를 최소화하여 전체적 성능 향상을 제공할 수 있습니다. 이 경우 개별 메시지의 상태에 대한 정보는 손실됩니다.

> 그림 9-4는 지속성 및 비지속성 메시지의 두 가지 경우에서 1k, 10k 및 100k 크기의 메시지에 대한 처리량(초당 KB)을 비교합니다. 모든 경우에서 메시지를 대기열 대상으로 보내며 AUTO_ACKNOWLEDGE 확인 모드를 사용합니다.

> 그림 9-4는 두 경우 모두에서 작은 메시지보다 큰 메시지를 전달할 때 오버헤드가 적다는 것을 보여 줍니다. 또한 크기가 1k 및 10k인 메시지에서는 비지속성 메시지가 지속성 메시지보다 약 50%의 성능 향상을 보였지만 100k 크기의 메시지에서는 아마도 네트워크 대역폭 때문에 해당 경우의 메시지 처리량에 병목 현상이 발생하여 이러한 성능 향상이 유지되지 않았음을 알 수 있습니다.

> 그림 9-4 메시지 크기의 성능 영향

> #### 메시지 본문 유형

> JMS는 복잡성 순서에 따라 아래에 대략적으로 표시된 다섯 개의 메시지 본문 유형을 지원합니다.

> - BytesMessage: 응용 프로그램에서 지정하는 형식의 바이트 집합을 포함합니다.
> - TextMessage: 단순한 java.lang.String입니다.
> - StreamMessage: Java 프리미티브 값의 스트림을 포함합니다.
> - MapMessage: 일련의 이름-값 쌍을 포함합니다.
> - ObjectMessage: Java 일련화 객체를 포함합니다.

> 일반적으로 메시지 유형은 응용 프로그램의 필요에 따라 제어되지만 좀 더 복잡한 유형(MapMessage 및 ObjectMessage)은 성능 저하(데이터 일련화 및 일련화 해제로 인한 저하)를 수반합니다. 성능 저하는 데이터의 단순성이나 복잡성에 따라 달라집니다.

> ### 성능에 영향을 미치는 메시지 서비스 요소

> 메시징 응용 프로그램의 성능은 응용 프로그램 설계뿐만 아니라 메시지 라우팅 및 전달을 수행하는 메시지 서비스의 영향도 받습니다.

> 다음 절에서는 성능에 영향을 미칠 수 있는 여러 메시지 서비스 요소를 설명합니다. 이러한 요소의 영향을 이해하는 것은 메시지 서비스 크기를 지정하고 배포된 응용 프로그램에서 발생할 수 있는 성능 병목 현상을 진단하고 해결하는 데 중요합니다.

> Message Queue 서비스에서 성능에 영향을 미치는 가장 중요한 요소는 다음과 같습니다.

> - 하드웨어
> - 운영 체제
> - Java 가상 머신(JVM)
> - 연결
> - 브로커 제한 및 동작
> - 메시지 서비스 구조
> - 데이터 저장소 성능
> - 클라이언트 런타임 구성

> 아래의 절에서는 이러한 각 요소가 메시징 성능에 미치는 영향을 설명합니다.

> #### 하드웨어

> Message Queue 메시지 서버나 클라이언트 응용 프로그램 모두 CPU 처리 속도와 사용 가능한 메모리가 메시지 서비스 성능의 주요 결정 요소입니다. 처리량을 높이면 많은 소프트웨어 제한 사항을 제거할 수 있고 메모리를 추가하면 처리 속도와 용량을 모두 늘릴 수 있습니다. 그러나 하드웨어 업그레이드만으로 병목 현상을 극복하는 것은 일반적으로 비용이 높습니다.

> #### 운영 체제

> 하드웨어 플랫폼이 같은 경우라도 각기 다른 운영 체제의 효율성으로 인해 성능은 다양할 수 있습니다. 예를 들어, 운영 체제에서 사용하는 스레드 모델은 메시지 서버가 지원할 수 있는 동시 연결 수에 중요한 영향을 미칠 수 있습니다. 일반적으로 모든 하드웨어가 동일한 경우 Solaris가 Linux보다 빠르며 Linux가 Windows보다 빠릅니다.

> #### Java 가상 머신(JVM)

> 메시지 서버는 호스트 JVM에서 실행되고 지원되는 Java 프로세스입니다. 결과적으로 JVM 처리는 메시지 서버가 얼마나 빠르고 효율적으로 메시지를 라우팅하고 전달할 수 있는지 결정하는 중요 요소입니다.

> 특히 JVM의 메모리 자원 관리는 중요할 수 있습니다. 메모리 로드 증가를 수용하기 위해 충분한 메모리를 JVM에 할당해야 합니다. 또한 JVM은 주기적으로 사용되지 않은 메모리를 재생 이용하며 이러한 메모리 재생 이용은 메시지 처리를 지연시킬 수 있습니다. JVM 메모리 힙이 클수록 메모리 재생 이용 중에 경험할 수 있는 잠재적 지연은 더 길어집니다.

> #### 연결

> 클라이언트와 브로커간 연결의 수와 속도는 메시지 서버가 처리할 수 있는 메시지 수와 메시지 전달 속도에 영향을 미칠 수 있습니다.

> ##### 메시지 서버 연결 제한

> 메시지 서버에 대한 모든 액세스는 연결을 통해서 이루어집니다. 동시 연결 수에 대한 제한은 메시지 서버를 동시에 사용할 수 있는 생성자나 사용자 클라이언트 수에 영향을 미칠 수 있습니다.

> 일반적으로 메시지 서버에 대한 연결 수는 사용 가능한 스레드 수에 의해 제한됩니다. Message Queue는 전용 스레드 모델이나 공유 스레드 모델 중 하나를 지원하도록 구성할 수 있는 스레드 풀 관리자를 사용합니다("스레드 풀 관리자" 참조). 전용 스레드 모델은 각 연결이 전용 스레드를 가지므로 아주 빠르지만 연결 수가 사용 가능한 스레드 수에 의해 제한됩니다(연결당 하나의 입력 스레드와 하나의 출력 스레드 필요). 공유 스레드 모델은 연결 수에 대한 제한이 없지만 많은 연결 사이에서 스레드를 공유하며 이러한 연결이 사용 중인 경우에는 상당한 오버헤드와 처리량 지연이 발생합니다.

> ##### 전송 프로토콜

> Message Queue 소프트웨어를 사용하면 클라이언트가 다양한 저급 전송 프로토콜을 사용하여 메시지 서버와 통신할 수 있습니다. Message Queue는 "연결 서비스 지원"에 표시된 연결 서비스와 해당 프로토콜을 지원합니다. 프로토콜은 응용 프로그램 요구 사항(암호화, 방화벽을 통한 액세스 가능)을 기반으로 선택하지만 이 선택은 전체 성능에 영향을 미칩니다.

> 그림 9-5 전송 프로토콜 속도

> 그림 9-5는 다양한 프로토콜 기술의 성능 특성을 반영합니다.

> - TCP는 브로커와 통신할 수 있는 가장 빠른 방법을 제공합니다.
> - SSL은 메시지를 보내고 받을 때 TCP보다 50-70퍼센트 더 느립니다(지속성 메시지의 경우 50퍼센트, 비지속성 메시지의 경우 70퍼센트에 근접). 또한 클라이언트와 브로커(또는 HTTPS의 경우 Web Server)가 전송할 데이터를 암호화할 때 사용될 개인 키를 설정해야 하므로 SSL을 사용하면 초기 연결 설정이 더 느려집니다(몇 초 걸릴 수 있음). 각 저급 TCP 패킷을 암호화하고 해독하는 데 필요한 추가 처리에 의해 성능이 저하됩니다.

> 그림 9-6은 높은 안정성 시나리오(영구 가입이 있고 AUTO_ACKNOWLEDGE 확인 모드를 사용하는 주제 대상에 1k의 지속성 메시지를 보냄)와 높은 성능 시나리오(영구 가입이 없고 DUPS_OK_ACKNOWLEDGE 확인 모드를 사용하는 주제 대상에 1k의 비지속성 메시지를 보냄)의 두 가지 경우에 대해 TCP와 SSL의 처리량을 비교합니다.

> 그림 9-6은 프로토콜이 높은 안정성 사례에서 영향을 덜 미침을 보여 줍니다. 이는 아마도 높은 안정성 사례에서 필요한 지속성 오버헤드가 처리량을 제한하는 데 프로토콜 속도보다 더 중요한 요소이기 때문일 것입니다.

> 그림 9-6 전송 프로토콜의 성능 영향

> - HTTP는 TCP나 SSL보다 느립니다. HTTP는 Web Server에서 실행되는 서블릿을 클라이언트와 브로커 사이의 프록시로 사용합니다. 성능 오버헤드는 HTTP 요청의 패킷 캡슐화와 메시지가 브로커에 도달하기 위해 두 개의 홉(클라이언트에서 서블릿으로, 서블릿에서 브로커로)을 통과해야 한다는 점과 관련됩니다.
> - 클라이언트와 서블릿 사이 그리고 서블릿과 브로커 사이에서 패킷을 암호화하는 데 필요한 추가 오버헤드로 인해 HTTPS는 HTTP보다 더 느립니다.

> #### 메시지 서비스 구조

> Message Queue 메시지 서버는 단일 브로커로 구현되거나 다중 상호 연결 브로커 인스턴스, 즉 브로커 클러스터로 구현될 수 있습니다.

> 브로커에 연결된 클라이언트 수가 늘어나고 전달되는 메시지 수가 늘어나면 파일 설명자, 스레드, 메모리 제한 같은 브로커의 자원 제한 사항이 초과하게 됩니다. 늘어나는 로드를 수용하는 한 가지 방법은 Message Queue 메시지 서버에 브로커 인스턴스를 추가하여 클라이언트 연결과 메시지 라우팅 및 전달을 여러 브로커에 걸쳐 분산시키는 것입니다.

> 일반적으로 이러한 확장은 클라이언트, 특히 메시지 생성자 클라이언트가 클러스터 전체에 균등하게 분산되어 있는 경우에 가장 잘 작동합니다. 클러스터에 있는 브로커 사이의 메시지 전달과 관련된 오버헤드로 인해 제한된 연결 수나 메시지 전달 비율을 갖는 클러스터는 단일 브로커보다 더 낮은 성능을 보일 수 있습니다.

> 또한 브로커 클러스터를 사용하여 네트워크 대역폭을 최적화할 수 있습니다. 예를 들어, 클러스터 내의 원격 브로커들 사이에는 느린 장거리 네트워크 링크를 사용하고 클라이언트와 해당 브로커 인스턴스의 연결에는 고속 링크를 사용할 수 있습니다.

> 클러스터에 대한 자세한 내용은 "멀티 브로커 클러스터(엔터프라이즈판)" 및 "클러스터를 이용한 작업(엔터프라이즈판)"을 참조하십시오.

> #### 브로커 제한 및 동작

> 메시지 서버가 처리해야 하는 메시지 처리량은 메시지 서버가 지원하는 메시징 응용 프로그램의 사용 패턴에 달려 있습니다. 하지만 메시지 서버는 메모리, CPU 사이클 등 자원이 제한되어 있습니다. 따라서 메시지 서버가 넘치게 되어 응답하지 않거나 불안정하게 될 수 있습니다.

> Message Queue 메시지 서버에는 메모리 자원을 관리하고 브로커의 메모리 부족을 방지하기 위해 기본적으로 제공되는 메커니즘이 있습니다. 이러한 메키니즘은 브로커나 개별 대상이 보유할 수 있는 메시지 수나 메시지 바이트에 대한 구성 가능한 제한 및 대상 제한에 이르면 시작될 수 있는 동작 집합을 포함합니다("메모리 자원 및 메시지 흐름 관리" 참조).

> 이러한 구성 가능한 메커니즘은 세밀하게 모니터하고 조정하면 메시지 유입과 유출의 균형을 유지하여 시스템 과부하가 발생할 수 없도록 하는 데 사용할 수 있습니다. 이 메커니즘은 오버헤드를 사용하고 메시지 처리량을 제한할 순 있지만 운영 무결성을 유지합니다.

> #### 데이터 저장소 성능

> Message Queue는 기본 제공 및 플러그 인 지속성 모두를 지원합니다("지속성 관리자" 참조). 기본 제공 지속성은 파일 기반 데이터 저장소입니다. 플러그 인 지속성은 JDBC™(Java Database Connectivity) 인터페이스를 사용하며 JDBC 호환 데이터 저장소가 필요합니다.

> 기본 제공 지속성이 플러그 인 지속성보다 상당히 빠르지만 JDBC 호환 데이터베이스 시스템은 응용 프로그램에 필요한 중복, 보안 및 관리 기능을 제공할 수 있습니다.

> 기본 제공 지속성의 경우 지속성 작업이 메모리 상태에서 데이터 저장소와 동기화되도록 지정하여 안정성을 최대화할 수 있습니다. 이렇게 하면 시스템 중단으로 인한 데이터 손실을 방지할 수 있지만 성능은 저하됩니다.

> #### 클라이언트 런타임 구성

> Message Queue 클라이언트 런타임은 클라이언트 응용 프로그램에 Message Queue 메시지 서비스에 대한 인터페이스를 제공합니다. 클라이언트가 대상에게 메시지를 보내고 이러한 대상으로부터 메시지를 받는 데 필요한 모든 작업을 지원합니다. 클라이언트 런타임은 구성 가능하므로(연결 팩토리 속성 값을 설정하여) 일반적으로 성능과 메시지 처리량을 향상시킬 수 있는 등록 정보와 동작을 설정할 수 있습니다.

> 예를 들어 Message Queue 클라이언트 런타임은 다음과 같은 구성 가능한 동작을 지원합니다.

> - JMS 메시지와 Message Queue 제어 메시지가 동일한 연결을 통해 흐르기 때문에 발생하는 혼잡을 막는 데 도움을 주는 연결 흐름 측정(imqConnectionFlowCount)
> - 클라이언트 런타임 연결을 통해 전달될 수 있는 메시지 수와 사용 대기 중인 메시지 수를 제한하여 클라이언트 자원 제한을 피하는 데 도움을 주는 연결 흐름 제한(imqConnectionFlowLimit)
> - 다중 사용자 대기열 전달의 경우 사용자 간의 로드 균형 조정을 향상시킬 수 있고(한 사용자에게 보내는 메시지 수의 불균형 방지), 연결된 한 사용자가 다른 연결된 사용자에게 과도하게 메시지를 보내는 것을 방지하는 데 도움을 주는 사용자 흐름 제한(imqConsumerFlowLimit). 이 등록 정보는 클라이언트 런타임 연결을 통해 전달될 수 있고 사용 대기 중인 사용자당 메시지 수를 제한합니다. 또한 이 등록 정보는 대기열 대상 등록 정보(consumerFlowLimit)로 구성될 수 있습니다.

> 이러한 동작들과 그 구성에 사용되는 속성에 대한 자세한 내용은 "클라이언트 런타임 메시지 흐름 조정"을 참조하십시오.

> ##

> 메시지 서버 모니터링

> 성능을 모니터하는 데 사용할 수 있는 메트릭 정보를 제공하도록 Message Queue 서버를 구성할 수 있습니다. 이 절에서는 메시지 서버를 모니터하는 데 사용할 수 있는 여러 도구와 이러한 도구를 사용하여 얻을 수 있는 메트릭 데이터에 대해 설명합니다.

> 메트릭 데이터를 사용하여 성능 문제를 해결하거나 메시지 서버 성능을 분석하고 조정하는 방법에 대한 자세한 내용은 "성능 문제 해결"을 참조하십시오.

> ### 모니터링 도구

> 다음 도구를 사용하여 메트릭 정보를 얻을 수 있습니다.

> - Message Queue 명령 유틸리티(imqcmd)
> - Message Queue 브로커 로그 파일
> - 메시지 기반 모니터링 API

> 다음 절에서는 이러한 각 도구를 사용하여 메트릭 정보를 얻는 방법을 설명합니다. 다른 도구간 비교는 "올바른 모니터링 도구 선택"을 참조하십시오.

> #### Message Queue 명령 유틸리티(imqcmd)

> 명령 유틸리티(imqcmd)는 Message Queue의 기본 명령줄 관리 도구이며 물리적 대상, 영구 가입, 트랜잭션 등의 응용 프로그램 관련 자원뿐 아니라 브로커와 해당 연결 서비스를 관리할 수 있게 해 줍니다. imqcmd 명령에 대한 설명은 6장, "브로커 및 응용 프로그램 관리"를 참조하십시오.

> imqcmd 명령의 기능 중 하나는 브로커 전체, 개별 연결 서비스 및 개별 대상에 대한 메트릭 정보를 얻을 수 있는 기능입니다. 메트릭 데이터를 얻으려면 일반적으로 imqcmd의 metrics 하위 명령을 사용합니다. 메트릭 데이터는 지정한 간격이나 지정한 횟수에 콘솔 화면에 기록됩니다.

> 또한 query 하위 명령("imqcmd query" 참조)을 사용하여 더욱 제한된 하위 집합의 메트릭 데이터를 얻을 수 있습니다.

> ##### imqcmd metrics

> imqcmd metrics의 구문과 옵션은 각각 표 9-2와 표 9-3에 나타나 있습니다.

> 표 9-2 imqcmd metrics 하위 명령 구문

> 하위 명령 구문 | 제공되는 메트릭 데이터
> --- | ---
> metrics bkr [-b hostName:port] [-m metricType] [-int interval] [-msp numSamples] [-u userName [-p pasword | 기본 브로커 또는 지정한 호스트 및 포트의 브로커 메트릭을 표시합니다.
> 또는 |
> metrics svc -n serviceName [-b hostName:port] [-m metricType] [-int interval] [-msp numSamples] [-u userName [-p pasword | 기본 브로커 또는 지정한 호스트 및 포트의 브로커에서 지정된 서비스의 메트릭을 표시합니다.
> 또는 |
> metrics dst -t destType -n destName [-b hostName:port] [-m metricType] [-int interval] [-msp numSamples] [-u userName [-p pasword | 지정한 유형과 이름의 대상에 대한 메트릭 정보를 표시합니다.

> 표 9-3 imqcmd metrics 하위 명령 옵션

> 하위 명령 옵션 | 설명
> --- | ---
> -b hostName:port | 메트릭 데이터를 보고하는 브로커의 호스트 이름과 포트를 지정합니다. 기본값은 localhost:7676입니다.
> -int interval | 메트릭을 표시할 간격(초)을 지정합니다. 기본값은 5초입니다.
> -m metricType | 표시할 메트릭의 유형을 지정합니다. ttl 브로커에 유입되고 유출되는 메시지와 패킷에 대한 메트릭을 표시합니다(기본 메트릭 유형). rts 브로커에 유입되고 유출되는 메시지와 패킷의 흐름 속도에 대한 메트릭을 표시합니다(초당). cxn 연결, 가상 메모리 힙 및 스레드를 표시합니다(브로커 및 연결 서비스에만 해당). con 사용자 관련 메트릭을 표시합니다(대상에만 해당). dsk 디스크 사용 메트릭을 표시합니다(대상에만 해당).
> -msp numSamples | 출력에 표시되는 샘플 수를 지정합니다. 기본값은 무제한 수입니다(무한).
> -n destName | 메트릭 데이터가 보고되는 대상(있는 경우)의 대상 이름입니다. 기본값이 없습니다.
> -n serviceName | 메트릭 데이터가 보고되는 연결 서비스(있는 경우)를 지정합니다. 기본값이 없습니다.
> -t destTyp | 메트릭 데이터가 보고되는 대상(있는 경우)의 유형(대기열 또는 주제)을 지정합니다. 기본값이 없습니다.
> -u userName | 자신(관리자)의 이름을 지정합니다. 이 값을 생략하면 값을 묻는 메시지가 표시됩니다.
> -p password | 자신(관리자)의 비밀번호를 지정합니다. 이 값을 생략하면 값을 묻는 메시지가 표시됩니다.

> ##### 절차: 메트릭 하위 명령을 사용하여 메트릭 데이터 표시

> 이 절에서는 metrics 하위 명령을 사용하여 메트릭 정보를 보고하는 절차를 설명합니다.

> ##### 메트릭 하위 명령을 사용하는 방법

> 1. 메트릭 정보가 필요한 브로커를 시작합니다.

> "브로커 시작"을 참조하십시오.

> 2. 표 9-2와 표 9-3에 표시된 대로 적절한 imqcmd metrics 하위 명령과 옵션을 실행합니다.

> ##### 메트릭 출력: imqcmd metrics

> 이 절에서는 브로커 전체, 연결 서비스 및 대상 메트릭에 대한 metrics 하위 명령의 출력 예를 보여 줍니다.

> 브로커 전체 메트릭. 메시지와 패킷이 브로커에 유입 및 유출되는 속도를 10초 간격으로 구하려면 다음과 같이 metrics bkr 하위 명령을 사용합니다.

> imqcmd metrics bkr -m rts -int 10 -u admin -p admin

> 이 명령은 다음과 유사한 출력을 생성합니다(표 9-8의 데이터 설명 참조).

> --------------------------------------------------------
> Msgs/sec Msg Bytes/sec Pkts/sec Pkt Bytes/sec
> In Out In Out In Out In Out
> --------------------------------------------------------
> 0 0 27 56 0 0 38 66
> 10 0 7365 56 10 10 7457 1132
> 0 0 27 56 0 0 38 73
> 0 10 27 7402 10 20 1400 8459
> 0 0 27 56 0 0 38 73

> 연결 서비스 메트릭. jms 연결 서비스가 처리한 메시지와 패킷의 누적 총 수를 구하려면 다음과 같이 metrics svc 하위 명령을 사용합니다.

> imqcmd metrics svc -n jms -m ttl -u admin -p admin

> 이 명령은 다음과 유사한 출력을 생성합니다(표 9-9의 데이터 설명 참조).

> -------------------------------------------------
> Msgs Msg Bytes Pkts Pkt Bytes
> In Out In Out In Out In Out
> -------------------------------------------------
> 164 100 120704 73600 282 383 135967 102127
> 657 100 483552 73600 775 876 498815 149948

> 대상 메트릭 대상에 대한 메트릭 정보를 얻으려면 다음과 같이 metrics dst 하위 명령을 사용하십시오.

> imqcmd metrics dst -t q -n XQueue -m ttl -u admin -p admin

> 이 명령은 다음과 유사한 출력을 생성합니다(표 9-10의 데이터 설명 참조).

> -----------------------------------------------------------------------------
> Msgs Msg Bytes Msg Count Total Msg Bytes (k) Largest
> In Out In Out Current Peak Avg Current Peak Avg Msg (k)
> -----------------------------------------------------------------------------
> 200 200 147200 147200 0 200 0 0 143 71 0
> 300 200 220800 147200 100 200 10 71 143 64 0
> 300 300 220800 220800 0 200 0 0 143 59 0

> 대상의 사용자에 대한 정보를 얻으려면 다음과 같은 metrics dst 하위 명령을 사용합니다.

> imqcmd metrics dst -t q -n SimpleQueue -m con -u admin -p admin

> 이 명령은 다음과 유사한 출력을 생성합니다(표 9-10의 데이터 설명 참조).

> ------------------------------------------------------------------
> Active Consumers Backup Consumers Msg Count
> Current Peak Avg Current Peak Avg Current Peak Avg
> ------------------------------------------------------------------
> 1 1 0 0 0 0 944 1000 525

> ##### imqcmd query

> imqcmd query의 구문과 옵션은 이 명령이 제공하는 메트릭 데이터에 대한 설명과 함께 표 9-4에 나와 있습니다.

> 표 9-4 imqcmd query 하위 명령 구문

> 하위 명령 구문 | 제공되는 메트릭 데이터
> --- | ---
> query bkr [-b hostName:port] [-int interval] [-msp numSamples] | 브로커 메모리와 영구 저장소에 저장되어 있는 현재의 메시지 수와 메시지 바이트에 대한 정보("브로커 정보 표시" 참조)
> 또는 |
> metrics svc -n serviceName [-b hostName:port] [-int interval] [-msp numSamples] | 지정한 연결 서비스에 대한 현재의 할당된 스레드 수와 연결 수에 대한 정보("연결 서비스 정보 표시" 참조)
> 또는 |
> metrics dst -t destType -n destName [-b hostName:port] [-int interval] [-msp numSamples] | 지정한 대상의 메모리와 영구 저장소에 저장되어 있는 생성자, 활성 및 백업 사용자, 메시지 및 메시지 바이트의 현재 수에 대한 정보("대상 정보 표시" 참조)

> 주 | imqcmd query에서 제공하는 메트릭 데이터는 제한되어 있기 때문에 이 도구는 (more...)의 "메트릭 데이터 설명" 절에 제시된 표에 설명되어 있지 않습니다.

> #### Message Queue 브로커 로그 파일

> Message Queue 로거는 브로커 코드, 디버거, 메트릭 생성기에서 생성한 정보를 가져와서 이 정보를 표준 출력(콘솔), 로그 파일, syslog 데몬 프로세스(Solaris™플랫폼인 경우) 등과 같은 여러 출력 채널에 기록합니다. 로거에 대해서는 "로거"에서 설명합니다.

> 로거에서 수집된 정보의 유형과 각 출력 채널에 기록된 유형을 지정할 수 있습니다. 특히 메트릭 정보가 로그 파일에 기록되도록 지정할 수 있습니다.

> ##### 절차: 브로커 로그 파일을 사용하여 메트릭 데이터 보고

> 이 절에서는 브로커 로그 파일을 사용하여 메트릭 정보를 보고하는 절차를 설명합니다. 로거 구성에 대한 자세한 내용은 "로깅"을 참조하십시오.

> ##### 로그 파일을 사용하여 메트릭 정보를 보고하는 방법

> 1. 브로커의 메트릭 생성 기능을 구성합니다.
> 1. imq.metrics.enabled=true인지 확인합니다.

> 로깅을 위한 메트릭 생성은 기본적으로 설정되어 있습니다.

> 2. 메트릭 생성 간격을 원하는 시간(초)으로 설정합니다.

> imq.metrics.interval=interval

> 이 값은 config.properties 파일에서 설정하거나 브로커를 시작할 때
> -metrics interval 명령줄 옵션을 사용하여 설정할 수 있습니다.

> 2. 로거가 메트릭 정보를 수집하는지 확인합니다.

> imq.log.level=INFO

> 이것이 기본값입니다. 이 값은 config.properties 파일에서 설정하거나 브로커를 시작할 때 -loglevel level 명령줄 옵션을 사용하여 설정할 수 있습니다.

> 3. 로거가 메트릭 정보를 로그 파일에 기록하도록 설정되어 있는지 확인합니다.

> imq.log.file.output=INFO

> 이것이 기본값입니다. 이 값은 config.properties 파일에서 설정할 수 있습니다.

> 4. 브로커를 시작합니다.

> ##### 메트릭 출력: 로그 파일

> 다음에는 로그 파일로의 샘플 브로커 메트릭 출력이 나와 있습니다(표 9-7 및 표 9-8의 메트릭 데이터 설명 참조).

> [21/Jul/2003:11:21:18 PDT]
> Connections: 0 JVM Heap: 8323072 bytes (7226576 free) Threads: 0 (14-1010)
> In: 0 msgs (0bytes) 0 pkts (0 bytes)
> Out: 0 msgs (0bytes) 0 pkts (0 bytes)
> Rate In: 0 msgs/sec (0 bytes/sec) 0 pkts/sec (0 bytes/sec)
> Rate Out: 0 msgs/sec (0 bytes/sec) 0 pkts/sec (0 bytes/sec)

> #### 메시지 기반 모니터링 API

> Message Queue는 브로커가 메트릭 데이터를 JMS 메시지에 기록한 다음 메시지에 포함된 메트릭 정보 유형에 따라 여러 메트릭 주제 대상 중 하나에 보낼 수 있는 메트릭 모니터링 기능을 제공합니다.

> 메트릭 주제 대상에 가입하고 이러한 대상에서 메시지를 사용하며 메시지에 포함된 메트릭 정보를 처리하는 클라이언트 응용 프로그램을 작성하여 이러한 메트릭 정보에 액세스할 수 있습니다. 일반 체계가 "메트릭 메시지 생성자(엔터프라이즈판)"에 설명되어 있습니다.

> 다섯 개의 메트릭 주제 대상이 있으며 표 9-5에 그 이름과 함께 각 대상에 전달되는 메트릭 메시지 유형이 표시되어 있습니다.

> 표 9-5 메트릭 주제 대상

> 주제 이름 | 메트릭 메시지 유형
> --- | ---
> mq.metrics.broker | 브로커 메트릭
> mq.metrics.jvm | Java 가상 머신 메트릭
> mq.metrics.destination_list | 대상 및 해당 유형 목록
> mq.metrics.destination.queue. monitoredDestinationName | 지정된 이름의 대기열에 대한 대상 메트릭
> mq.metrics.destination.topic. monitoredDestinationName | 지정된 이름의 주제에 대한 대상 메트릭

> ##### 절차: 메시지 기반 모니터링 설정

> 이 절에서는 메시지 기반 모니터링 기능을 사용하여 메트릭 정보를 수집하는 절차를 설명합니다. 이 절차는 클라이언트 개발과 관리 작업을 모두 포함합니다.

> ##### 메시지 기반 모니터링을 설정하는 방법

> 1. 메트릭 모니터링 클라이언트를 작성합니다.

> 메트릭 주제 대상에 가입하고 메트릭 메시지를 사용하며 이러한 메시지에서 메트릭 데이터를 추출하는 클라이언트를 프로그래밍하는 데 대한 지침은 Message Queue Java Client Developer's Guide를 참조하십시오.

> 2. config.properties 파일에서 브로커 등록 정보 값을 설정하여 브로커의 메트릭 메시지 생성자를 구성합니다.
> 1. 메트릭 메시지 생성을 활성화합니다.

> imq.metrics.topic.enabled=true를 설정합니다.

> 기본값은 true입니다.

> 2. 메트릭 메시지가 생성되는 간격(초)을 설정합니다.

> imq.metrics.topic.interval=interval을 설정합니다.

> 기본값은 60초입니다.

> 3. 메트릭 메시지가 지속되는지(즉, 브로커에 오류가 발생해도 메시지가 보존되는지) 여부를 지정합니다.

> imq.metrics.topic.persist를 설정합니다.

> 기본값은 false입니다.

> 4. 메트릭 메시지가 삭제되기 전까지 해당 대상에 남아 있는 기간을 지정합니다.

> imq.metrics.topic.timetolive를 지정합니다.

> 기본값은 300초입니다.

> 3. 메트릭 주제 대상에 대한 액세스 제어가 필요한 경우 설정합니다.

> 아래의 "보안 및 액세스 고려 사항"에 있는 설명을 참조하십시오.

> 4. 메트릭 모니터링 클라이언트를 시작합니다.

> 사용자가 메트릭 주제에 가입하면 메트릭 주제 대상이 자동으로 만들어집니다. 메트릭 주제가 만들어지면 브로커 메트릭 메시지 생성자가 메트릭 메시지를 메트릭 주제로 보내기 시작합니다.

> ##### 보안 및 액세스 고려 사항

> 메트릭 주제 대상에 대한 액세스를 제한하는 이유는 두 가지입니다.

> - 메트릭 데이터에는 브로커와 그 자원에 대한 중요한 정보가 포함되어 있을 수 있습니다.
> - 메트릭 주제 대상에 대한 가입 수가 과도한 경우 브로커 오버헤드가 늘어나고 성능에 부정적인 영향을 미칠 수 있습니다.

> 이러한 사항을 고려할 때 메트릭 주제 대상에 대한 액세스를 제한하는 것이 좋습니다.

> 모니터링 클라이언트는 다른 클라이언트와 같은 인증 및 권한 부여 제어를 받습니다. Message Queue 사용자 저장소에서 유지 관리되는 사용자만 브로커에 연결할 수 있습니다.

> "사용자 권한 부여: 액세스 제어 등록 정보 파일"에 설명되어 있는 액세스 제어 등록 정보 파일을 통해 특정 메트릭 주제 대상에 대한 액세스를 제한하여 추가 보호를 제공할 수 있습니다.

> 예를 들어 accesscontrol.properties 파일의 다음 항목은 user1과 user2를 제외한 모든 사람에 대해 mq.metrics.broker 메트릭 주제에 대한 액세스를 거부합니다.

> topic.mq.metrics.broker.consume.deny.user=* topic.mq.metrics.broker.consume.allow.user=user1,user2

> 다음 항목은 사용자 user3만 주제 t1을 모니터할 수 있도록 합니다.

> topic.mq.metrics.destination.topic.t1.consume.deny.user=* topic.mq.metrics.destination.topic.t1.consume.allow.user=user3

> 메트릭 데이터의 중요도에 따라 암호화된 연결을 사용하여 메트릭 모니터링 클라이언트를 브로커에 연결할 수도 있습니다. 암호화된 연결 사용에 대한 자세한 내용은 "암호화: SSL 기반 서비스를 사용한 작업(엔터프라이즈판)"을 참조하십시오.

> ##### 메트릭 출력: 메트릭 메시지

> 메시지 기반 모니터링 API를 사용하여 얻는 메트릭 데이터 출력은 사용자가 어떤 메트릭 모니터링 클라이언트를 작성하는지에 따라 다릅니다. 단지 브로커의 메트릭 생성기에서 어떤 데이터를 제공하는지에 따라 제한을 받습니다. 이 데이터의 전체 목록을 보려면 "메트릭 데이터 설명"을 참조하십시오.

> #### 올바른 모니터링 도구 선택

> 앞 절에서 설명한 모니터링 도구마다 장점과 단점이 있습니다.

> 예를 들어 imqcmd metrics 명령을 사용하면 언제라도 요구에 맞는 정보를 빠르게 샘플링할 수 있지만 기록 정보를 살피거나 데이터를 프로그래밍 방식으로 조작하기가 다소 어렵습니다.

> 반면 로그 파일은 장기간의 메트릭 데이터 기록을 제공하지만 로그 파일의 정보를 의미 있는 정보로 구문 분석하기가 어렵습니다.

> 메시지 기반 모니터링 API를 사용하는 경우 필요한 정보 추출 및 처리, 데이터를 프로그래밍 방식으로 조작 또는 형식 지정, 그래프 표현, 경고 보내기 등을 쉽게 수행할 수 있지만 데이터를 캡처하고 분석하기 위한 사용자 정의 응용 프로그램을 작성해야 합니다.

> 또한 이러한 각 도구는 브로커가 생성한 메트릭 정보 중 약간씩 다른 하위 집합을 수집합니다. 각 모니터링 도구가 수집하는 메트릭 데이터에 대한 자세한 내용은 "메트릭 데이터 설명"을 참조하십시오.

> 표 9-6에서는 다른 도구 간의 장점과 단점을 제시하여 비교합니다.

> 표 9-6 메트릭 모니터링 도구의 장점 및 단점

> 메트릭 모니터링 도구 | 장점 | 단점
> --- | --- | ---
> imqcmd metrics | 원격 모니터링 스팟 체킹에 적합 명령 옵션에 설정된 보고 간격을 실행 중에 변경 가능 원하는 특정 데이터를 선택하기 쉬움 보기 쉬운 테이블 형식으로 데이터 제시 | 하나의 명령으로 모든 데이터를 얻을 수 없음 데이터를 프로그래밍 방식으로 분석하기 어려움 기록 레코드를 작성하지 않음 기록 추세를 보기 어려움
> 로그 파일 | 정기적인 샘플링 기록 레코드 작성 | 브로커 등록 정보를 구성해야 하며 적용하려면 브로커를 종료하고 다시 시작해야 함 로컬 모니터링 전용 데이터 형식이 읽거나 구문 분석하기가 아주 어려우며 구문 분석 도구 없음 보고 간격을 실행 중에 변경할 수 없으며 모든 메트릭 데이터도 마찬가지임 데이터 선택에 융통성이 없음 브로커 메트릭 전용이며 대상 및 연결 서비스 메트릭은 포함되어 있지 않음 간격을 너무 짧게 설정하면 성능에 악영향을 줄 수 있음
> 메시지 기반 모니터링 API | 원격 모니터링 원하는 특정 데이터를 선택하기 쉬움 데이터를 전자적으로 분석하고 모든 형식으로 표시할 수 있음 | 브로커 등록 정보를 구성해야 하며 적용하려면 브로커를 종료하고 다시 시작해야 함 사용자 고유의 메트릭 모니터링 클라이언트를 작성해야 함 보고 간격을 실행 중에 변경할 수 없으며 모든 메트릭 데이터도 마찬가지임

> ### 메트릭 데이터 설명

> 브로커가 보고하는 메트릭 정보는 다음과 같은 범주로 그룹화할 수 있습니다.

> - JVM (Java 가상 머신) 메트릭. JVM 힙 크기에 대한 정보
> - 브로커 전체 메트릭. 메시지 수 및 바이트 수(해당 수 및 속도)라는 측면에서 브로커에 저장되어 있는 메시지 및 브로커에 유입 및 유출되는 메시지 흐름에 대한 정보. 이 범주에는 메모리 사용에 대한 정보도 포함됩니다.
> - 연결 서비스 메트릭. 연결 및 연결 스레드 자원에 대한 정보 및 특정 연결 서비스의 메시지 흐름에 대한 정보
> - 대상 메트릭. 특정 대상에 유입하고 유출하는 메시지에 대한 정보, 대상 사용자에 대한 정보, 메모리 및 디스크 공간 사용에 대한 정보

> 다음 절에서는 이러한 각 범주에서 사용할 수 있는 메트릭 데이터를 설명합니다. 다음 표에서 설명하는 모니터링 도구에 대한 자세한 내용은 "모니터링 도구"를 참조하십시오.

> #### JVM 메트릭

> 표 9-7에서는 브로커가 브로커 프로세스 JVM 힙에 대해 생성하는 메트릭 데이터를 나열하고 설명하며 메트릭 모니터링 도구에 따라 어떤 데이터를 얻을 수 있는지 보여 줍니다.

> 표 9-7 JVM 메트릭

> 메트릭 개수 | 설명 | imqcmd metrics bkr (metricType) | 로그 파일 | 메트릭 메시지 (metrics topic)1
> --- | --- | --- | --- | ---
> JVM 힙: 사용 가능한 메모리 | JVM 힙에서 사용할 수 있는 사용 가능한 메모리 양 | 예 (cxn) | 예 | 예 (...jvm)
> JVM 힙: 전체 메모리 | 현재 JVM 힙 크기 | 예 (cxn) | 예 | 예 (...jvm)
> JVM 힙: 최대 메모리 | JVM 힙 크기가 늘어날 수 있는 최대값 | 아니요 | 예2 | 예 (...jvm)

> 1메트릭 주제 대상 이름에 대해서는 표 9-5를 참조하십시오. 2브로커 시작 시에만 표시됩니다.

> #### 브로커 전체 메트릭

> 표 9-8에서는 브로커 전체 메트릭 정보에 대해 브로커가 보고하는 데이터를 나열하고 설명합니다. 또한 메트릭 모니터링 도구에 따라 어떤 데이터를 얻을 수 있는지 보여 줍니다.

> 표 9-8 브로커 전체 메트릭

> 메트릭 개수 | 설명 | imqcmd metrics bkr (metricType) | 로그 파일 | 메트릭 메시지 (metrics topic)1
> --- | --- | --- | --- | ---
> 연결 데이터
> Num connections | 브로커에 대해 현재 열려 있는 연결 수 | 예 (cxn) | 예 | 예 (...broker)
> Num threads | 현재 사용 중인 스레드 수 | 예 (cxn) | 예 | 아니요
> Min threads | 이 스레드 수에 도달하면 스레드 풀에서 연결 서비스용으로 유지 관리되는 스레드 수 | 예 (cxn) | 예 | 아니요
> Max threads | 이 스레드 수를 초과하면 스레드 풀에 연결 서비스용으로 새 스레드가 더 이상 추가되지 않는 스레드 수 | 예 (cxn) | 예 | 아니요
> 저장된 메시지 데이터
> Num messages | 브로커 메모리와 영구 저장소에 현재 저장되어 있는 JMS 메시지 수 | 아니요 query bkr 사용 | 아니요 | 예 (...broker)
> Total message bytes | 브로커 메모리와 영구 저장소에 현재 저장되어 있는 JMS 메시지 바이트 수 | 아니요 query bkr 사용 | 아니요 | 예 (...broker)
> 메시지 흐름 데이터
> Num messages in | 브로커가 마지막으로 시작된 이후 브로커에 유입된 JMS 메시지 수 | 예 (ttl) | 예 | 예 (...broker)
> Message bytes in | 브로커가 마지막으로 시작된 이후 브로커에 유입된 JMS 메시지 바이트 수 | 예 (ttl) | 예 | 예 (...broker)
> Num packets in | 브로커가 마지막으로 시작된 이후 브로커에 유입된 패킷 수(JMS 메시지와 제어 메시지 모두 포함) | 예 (ttl) | 예 | 예 (...broker)
> Packet bytes in | 브로커가 마지막으로 시작된 이후 브로커에 유입된 패킷 바이트 수(JMS 메시지와 제어 메시지 모두 포함) | 예 (ttl) | 예 | 예 (...broker)
> Num messages out | 브로커가 마지막으로 시작된 이후 브로커에서 유출된 JMS 메시지 수 | 예 (ttl) | 예 | 예 (...broker)
> Message bytes out | 브로커가 마지막으로 시작된 이후 브로커에서 유출된 JMS 메시지 바이트 수 | 예 (ttl) | 예 | 예 (...broker)
> Num packets out | 브로커가 마지막으로 시작된 이후 브로커에서 유출된 패킷 수(JMS 메시지와 제어 메시지 모두 포함) | 예 (ttl) | 예 | 예 (...broker)
> Packet bytes out | 브로커가 마지막으로 시작된 이후 브로커에서 유출된 패킷 바이트 수(JMS 메시지와 제어 메시지 모두 포함) | 예 (ttl) | 예 | 예 (...broker)
> Rate messages in | 브로커로 JMS 메시지가 유입되는 현재 속도 | 예 (rts) | 예 | 아니요
> Rate message bytes in | 브로커로 JMS 메시지 바이트가 유입되는 현재 속도 | 예 (rts) | 예 | 아니요
> Rate packets in | 브로커로 패킷이 유입되는 현재 속도(JMS 메시지와 제어 메시지 모두 포함) | 예 (rts) | 예 | 아니요
> Rate packet bytes in | 브로커로 패킷 바이트가 유입되는 현재 속도(JMS 메시지와 제어 메시지 모두 포함) | 예 (rts) | 예 | 아니요
> Rate messages out | 브로커에서 JMS 메시지가 유출되는 현재 속도 | 예 (rts) | 예 | 아니요
> Rate message bytes out | 브로커에서 JMS 메시지 바이트가 유출되는 현재 속도 | 예 (rts) | 예 | 아니요
> Rate packets out | 브로커에서 패키지가 유출되는 현재 속도(JMS 메시지와 제어 메시지 모두 포함) | 예 (rts) | 예 | 아니요
> Rate packet bytes out | 브로커에서 패키지 바이트가 유출되는 현재 속도(JMS 메시지와 제어 메시지 모두 포함) | 예 (rts) | 예 | 아니요
> 대상 데이터
> Num destinations | 브로커에 있는 실제 대상 수 | 아니요 | 아니요 | 예 (...broker)

> 1메트릭 주제 대상 이름에 대해서는 표 9-5를 참조하십시오.

> #### 연결 서비스 메트릭

> 표 9-9에서는 개별 연결 서비스에 대해 브로커가 보고하는 메트릭 데이터를 나열하고 설명합니다. 또한 메트릭 모니터링 도구에 따라 어떤 데이터를 얻을 수 있는지 보여 줍니다.

> 표 9-9 연결 서비스 메트릭

> 메트릭 개수 | 설명 | imqcmd metrics svc (metricType) | 로그 파일 | 메트릭 메시지 (metrics topic)
> --- | --- | --- | --- | ---
> 연결 데이터
> Num connections | 현재 열려 있는 연결의 수 | 예 (cxn) 또는 query svc | 아니요 | 아니요
> Num threads | 현재 사용 중인 스레드 수(모든 연결 서비스에서 합산) | 예 (cxn) 또는 query svc | 아니요 | 아니요
> Min threads | 이 스레드 수에 도달하면 스레드 풀에서 연결 서비스용으로 유지 관리되는 스레드 수(전체 연결 서비스에서 합산) | 예 (cxn) | 아니요 | 아니요
> Max threads | 이 스레드 수를 초과하면 스레드 풀에 연결 서비스용으로 새 스레드가 더 이상 추가되지 않는 스레드 수(전체 연결 서비스에서 합산) | 예 (cxn) | 아니요 | 아니요
> 메시지 흐름 데이터
> Num messages in | 브로커가 마지막으로 시작된 이후 연결 서비스에 유입된 JMS 메시지의 수 | 예 (ttl) | 아니요 | 아니요
> Message bytes in | 브로커가 마지막으로 시작된 이후 연결 서비스에 유입된 JMS 메시지 바이트 수 | 예 (ttl) | 아니요 | 아니요
> Num packets in | 브로커가 마지막으로 시작된 이후 연결 서비스에 유입된 패킷 수(JMS 메시지와 제어 메시지 모두 포함) | 예 (ttl) | 아니요 | 아니요
> Packet bytes in | 브로커가 마지막으로 시작된 이후 연결 서비스에 유입된 패킷 바이트 수(JMS 메시지와 제어 메시지 모두 포함) | 예 (ttl) | 아니요 | 아니요
> Num messages out | 브로커가 마지막으로 시작된 이후 연결 서비스에서 유출된 JMS 메시지 수 | 예 (ttl) | 아니요 | 아니요
> Message bytes out | 브로커가 마지막으로 시작된 이후 연결 서비스에서 유출된 JMS 메시지 바이트 수 | 예 (ttl) | 아니요 | 아니요
> Num packets out | 브로커가 마지막으로 시작된 이후 연결 서비스에서 유출된 패킷 수(JMS 메시지와 제어 메시지 모두 포함) | 예 (ttl) | 아니요 | 아니요
> Packet bytes out | 브로커가 마지막으로 시작된 이후 연결 서비스에서 유출된 패킷 바이트 수(JMS 메시지와 제어 메시지 모두 포함) | 예 (ttl) | 아니요 | 아니요
> Rate messages in | 연결 서비스를 통해 JMS 메시지가 브로커로 유입되는 현재 속도 | 예 (rts) | 아니요 | 아니요
> Rate message bytes in | 연결 서비스로 JMS 메시지 바이트가 유입되는 현재 속도 | 예 (rts) | 아니요 | 아니요
> Rate packets in | 연결 서비스로 패킷이 유입되는 현재 속도(JMS 메시지와 제어 메시지 모두 포함) | 예 (rts) | 아니요 | 아니요
> Rate packet bytes in | 연결 서비스로 패킷 바이트가 유입되는 현재 속도(JMS 메시지와 제어 메시지 모두 포함) | 예 (rts) | 아니요 | 아니요
> Rate messages out | 연결 서비스에서 JMS 메시지가 유출되는 현재 속도 | 예 (rts) | 아니요 | 아니요
> Rate message bytes out | 연결 서비스에서 JMS 메시지 바이트가 유출되는 현재 속도 | 예 (rts) | 아니요 | 아니요
> Rate packets out | 연결 서비스에서 패킷이 유출되는 현재 속도(JMS 메시지와 제어 메시지 모두 포함) | 예 (rts) | 아니요 | 아니요
> Rate packet bytes out | 연결 서비스에서 패킷 바이트가 유출되는 현재 속도(JMS 메시지와 제어 메시지 모두 포함) | 예 (rts) | 아니요 | 아니요

> #### 대상 메트릭

> 표 9-9에서는 개별 대상에 대해 브로커가 보고하는 메트릭 데이터를 나열하고 설명합니다. 또한 메트릭 모니터링 도구에 따라 어떤 데이터를 얻을 수 있는지 보여 줍니다.

> 표 9-10 대상 메트릭

> 메트릭 개수 | 설명 | imqcmd metrics dst (metricType) | 로그 파일 | 메트릭 메시지 (metrics topic)1
> --- | --- | --- | --- | ---
> 사용자 데이터
> Num active consumers | 현재 활성 사용자의 수 | 예 (con) | 아니요 | 예 (...destName)
> Avg num active consumers | 브로커가 마지막으로 시작된 이후 평균 활성 사용자 수 | 예 (con) | 아니요 | 예 (...destName)
> Peak num active consumers | 브로커가 마지막으로 시작된 이후 최대 활성 사용자 수 | 예 (con) | 아니요 | 예 (...destName)
> Num backup consumers | 현재 백업 사용자 수(대기열에만 적용) | 예 (con) | 아니요 | 예 (...destName)
> Avg num backup consumers | 브로커가 마지막으로 시작된 이후 평균 백업 사용자 수(대기열에만 적용) | 예 (con) | 아니요 | 예 (...destName)
> Peak num backup consumers | 브로커가 마지막으로 시작된 이후 최대 백업 사용자 수(대기열에만 적용) | 예 (con) | 아니요 | 예 (...destName)
> 저장된 메시지 데이터
> Num messages | 대상 메모리와 영구 저장소에 현재 저장되어 있는 JMS 메시지 수 | 예 (con) (ttl) (rts) 또는 query dst | 아니요 | 예 (...destName)
> Avg num messages | 브로커가 마지막으로 시작된 이후 대상 메모리와 영구 저장소에 저장되어 있는 평균 JMS 메시지 수 | 예 (con) (ttl) (rts) | 아니요 | 예 (...destName)
> Peak num messages | 브로커가 마지막으로 시작된 이후 대상 메모리와 영구 저장소에 저장되어 있는 최대 JMS 메시지 수 | 예 (con) (ttl) (rts) | 아니요 | 예 (...destName)
> Total message bytes | 대상 메모리와 영구 저장소에 현재 저장되어 있는 JMS 메시지 바이트 수 | 예 (ttl) (rts) 또는 query dst | 아니요 | 예 (...destName)
> Avg total message bytes | 브로커가 마지막으로 시작된 이후 대상 메모리와 영구 저장소에 저장되어 있는 평균 JMS 메시지 바이트 수 | 예 (ttl) (rts) | 아니요 | 예 (...destName)
> Peak total message bytes | 브로커가 마지막으로 시작된 이후 대상 메모리와 영구 저장소에 저장되어 있는 최대 JMS 메시지 바이트 수 | 예 (ttl) (rts) | 아니요 | 예 (...destName)
> Peak message bytes | 브로커가 마지막으로 시작된 이후 대상에서 수신한 단일 메시지에 있는 최대 JMS 메시지 바이트 수 | 예 (ttl) (rts) | 아니요 | 예 (...destName)
> 메시지 흐름 데이터
> Num messages in | 브로커가 마지막으로 시작된 이후 이 대상에 유입된 JMS 메시지 수 | 예 (ttl) | 아니요 | 예 (...destName)
> Msg bytes in | 브로커가 마지막으로 시작된 이후 이 대상에 유입된 JMS 메시지 바이트 수 | 예 (ttl) | 아니요 | 예 (...destName)
> Num messages out | 브로커가 마지막으로 시작된 이후 이 대상에서 유출된 JMS 메시지 수 | 예 (ttl) | 아니요 | 예 (...destName)
> Msg bytes out | 브로커가 마지막으로 시작된 이후 이 대상에서 유출된 JMS 메시지 바이트 수 | 예 (ttl) | 아니요 | 예 (...destName)
> Rate num messages in | JMS 메시지가 대상에 유입되는 현재 속도 | 예 (rts) | 아니요 | 아니요
> Rate num messages out | JMS 메시지가 대상에서 유출되는 현재 속도 | 예 (rts) | 아니요 | 아니요
> Rate msg bytes in | JMS 메시지 바이트가 대상에 유입되는 현재 속도 | 예 (rts) | 아니요 | 아니요
> Rate Msg bytes out | JMS 메시지가 대상에서 유출되는 현재 속도 | 예 (rts) | 아니요 | 아니요
> 디스크 사용률 데이터
> Disk reserved | 대상 파일 기반 저장소에서 모든 메시지 레코드(활성 및 사용 가능)가 사용하는 디스크 공간(바이트) | 예 (dsk) | 아니요 | 예 (...destName)
> Disk used | 대상 파일 기반 저장소에서 활성 메시지 레코드가 사용하는 디스크 공간(바이트) | 예 (dsk) | 아니요 | 예 (...destName)
> Disk utilization ratio | 예약된 디스크 공간에 대한 사용 중인 디스크 공간의 비율. 비율이 높을수록 더 많은 디스크 공간이 활성 메시지를 보관하는 데 사용되고 있는 것입니다. | 예 (dsk) | 아니요 | 예 (...destName)

> 1메트릭 주제 대상 이름에 대해서는 표 9-5를 참조하십시오.

> ##

> 성능 문제 해결

> 응용 프로그램을 지원하기 위해 Message Queue 서비스를 사용할 때 여러 성능 문제가 발생할 수 있습니다. 이러한 문제는 다음과 같습니다.

> - 문제: 클라이언트가 연결을 설정할 수 없음
> - 문제: 연결 처리량이 너무 느림
> - 문제: 클라이언트가 메시지 생성자를 만들 수 없음
> - 문제: 메시지 생성이 지연되거나 느림
> - 문제: 메시지가 메시지 서버에서 백로그됨
> - 문제: 메시지 서버 처리량이 일정하지 않음
> - 문제: 메시지가 사용자에게 도달하지 않음

> 아래에서 이러한 각 문제 대해 가능한 원인 및 해결책과 함께 설명합니다.

> ### 문제: 클라이언트가 연결을 설정할 수 없음

> #### 증상:

> - 클라이언트가 새 연결을 설정할 수 없습니다.
> - 클라이언트가 실패한 연결을 자동으로 다시 연결할 수 없습니다.

> #### 가능한 원인:

> - 클라이언트 응용 프로그램이 연결을 닫을 수 없어 연결 수가 자원 제한을 초과합니다.

> 문제의 원인을 확인하려면 다음 작업을 수행합니다.

> 브로커에 대한 연결을 모두 나열합니다.

> imqcmd list cxn

> 출력에 모든 연결과 각 연결이 설정된 호스트가 나열되고 특정 클라이언트에 비정상적인 수의 연결이 열려 있는 것으로 표시됩니다.

> 문제를 해결하려면 다음 작업을 수행합니다.

> 문제가 있는 클라이언트를 다시 작성하여 사용되지 않는 연결을 닫습니다.

> - 브로커가 실행 중이지 않거나 네트워크 연결에 문제가 있습니다.

> 문제의 원인을 확인하려면 다음 작업을 수행합니다.

> - 브로커의 기본 포트(예: 기본값 7676)로 텔넷하고 브로커가 포트 매퍼 출력으로 응답하는지 확인합니다.
> - 브로커 프로세스가 호스트에서 실행 중인지 확인합니다.

> 문제를 해결하려면 다음 작업을 수행합니다.

> - 브로커를 시작합니다.
> - 네트워크 연결 문제를 해결합니다.
> - 연결 서비스가 비활성 상태이거나 일시 중지되어 있습니다.

> 문제의 원인을 확인하려면 다음 작업을 수행합니다.

> 모든 연결 서비스의 상태를 확인합니다.

> imqcmd list svc

> 연결 서비스 상태가 unknown 또는 paused로 표시되어 있는 경우 클라이언트가 해당 서비스를 사용하여 연결을 설정할 수 없습니다.

> 문제를 해결하려면 다음 작업을 수행합니다.

> - 연결 서비스의 상태가 unknown으로 표시되어 있는 경우 활성 서비스 목록(imq.service.active)에서 빠진 것입니다. SSL 기반 서비스의 경우 서비스가 잘못 구성되어 있을 수도 있습니다. 이로 인해 브로커가 브로커 로그에 ERROR [B3009]: Unable to start service ssljms: [B4001]: Unable to open protocol tls for ssljms service... 라는 항목과 이 예외의 근본 원인에 대한 설명을 포함시키게 됩니다.

> SSL 서비스를 올바르게 구성하려면 "TCP/IP에서 SSL 기반 서비스 설정"을 참조하십시오.

> - 연결 서비스의 상태가 paused로 표시되어 있는 경우 서비스를 다시 시작합니다("연결 서비스 일시 중지 및 다시 시작" 참조).
> - 필요한 연결 수에 비해 사용 가능한 스레드 수가 너무 적습니다.

> 문제의 원인을 확인하려면 다음 작업을 수행합니다.

> 브로커 로그에서 WARNING [B3004]: No threads are available to process a new connection on service ... Closing the new connection. 항목이 있는지 확인합니다.

> 또한 연결 서비스의 연결 수와 현재 사용 중인 스레드 수를 확인합니다.

> imqcmd query svc -n serviceName
> 또는
> imqcmd metrics svc -n serviceName -m cxn

> 각 연결에는 받는 메시지와 보내는 메시지에 하나씩 두 개의 스레드가 필요합니다("스레드 풀 관리자" 참조).

> 문제를 해결하려면 다음 작업을 수행합니다.

> - 전용 스레드 풀 모델을 사용하고 있는 경우(imq.service_name. threadpool_model=dedicated), 최대 연결 수는 스레드 풀의 최대 스레드 수의 반입니다. 따라서 연결 수를 늘리려면 스레드 풀의 크기를 늘리거나(imq.service_name.max_threads) 공유 스레드 풀 모델로 전환합니다.
> - 공유 스레드 풀 모델을 사용 중인 경우(imq.service_name. threadpool_model=shared), 최대 연결 수는 연결 모니터 제한(imq.service_name.connectionMonitor_limit)과 최대 스레드 수(imq.service_name.max_threads)의 두 가지 등록 정보를 곱한 수의 반입니다.
>   따라서 연결 수를 늘리려면 스레드 풀의 크기를 늘리거나 연결 모니터 제한을 늘립니다.
> - 결국 지원 가능한 연결 수(또는 연결의 처리량)가 입출력 제한에 도달합니다. 그런 경우 다중 브로커 클러스터("클러스터를 이용한 작업(엔터프라이즈판)" 참조)를 사용하여 클러스터 내의 브로커 인스턴스로 연결을 분산합니다.
> - Solaris나 Linux 플랫폼에서 필요한 연결 수에 비해 파일 설명자가 너무 적습니다("OS 정의 파일 설명자 제한" 참조).

> 문제의 원인을 확인하려면 다음 작업을 수행합니다.

> 브로커 로그에 Too many open files와 유사한 항목이 있는지 검사합니다.

> 문제를 해결하려면 다음 작업을 수행합니다.

> ulimit 설명서 페이지에 설명되어 있는 대로 파일 설명자 제한을 늘립니다.

> - TCP 백로그가 동시에 설정할 수 있는 새 연결 요청 수를 제한합니다.

> TCP 백로그는 포트 매퍼가 추가 요청을 거부하기 전에 시스템 백로그(imq.portmapper.backlog)에 저장할 수 있는 동시 연결 요청 수를 제한합니다 (Windows 플랫폼의 경우 하드 코드된 백로그 제한이 있으며 Windows 데스크탑의 경우 5이고 Windows 서버의 경우 200임).

> 백로그 제한으로 인한 요청 거부는 비정상적으로 많은 동시 연결 요청 수로 인해 발생하는 일시적인 현상입니다.

> 문제의 원인을 확인하려면 다음 작업을 수행합니다.

> 브로커 로그에서 거의 같은 시간에 받아들여지는 연결 요청이 있는 반면 거부되는 연결 요청도 있는지 확인합니다. 거부된 연결 요청은 java.net.ConnectException: Connection refused를 반환합니다.

> 문제를 해결하려면 다음 작업을 수행합니다.

> 다음 방법을 사용하여 TCP 백로그 제한을 해결할 수 있습니다.

> - 클라이언트가 시도했던 연결을 잠시 후에 다시 시도하도록 프로그래밍합니다(이 문제가 본래 임시적이기 때문에 이렇게 하면 대개 제대로 작동됨).
> - imq.portmapper.backlog 값을 늘립니다.
> - 클라이언트가 너무 자주 연결을 닫은 다음 열고 있지는 않은지 확인합니다.
> - 운영 체제가 동시 연결 수를 제한합니다.

> Windows 운영 체제 사용권에서는 지원되는 동시 원격 연결 수를 제한합니다.

> 문제의 원인을 확인하려면 다음 작업을 수행합니다.

> 연결에 사용할 수 있는 스레드가 충분한지 확인하고(imqcmd query svc 사용) Windows 사용권 계약 조항을 확인합니다. 로컬 클라이언트에서는 연결할 수 있지만 원격 클라이언트에서는 연결할 수 없는 경우 운영 체제 제한이 문제의 원인일 수 있습니다.

> 문제를 해결하려면 다음 작업을 수행합니다.

> - 더 많은 연결을 허용하도록 Windows 사용권을 업그레이드합니다.
> - 다중 브로커 클러스터를 설정하여 연결을 여러 브로커 인스턴스에 분산합니다.
> - 사용자의 인증 또는 권한 부여가 실패합니다.

> 사용자 저장소에 사용자에 대한 항목이 없거나 사용자가 연결 서비스에 대한 액세스 권한이 없기 때문에 잘못된 비밀번호로 인해 인증이 실패할 수 있습니다.

> 문제의 원인을 확인하려면 다음 작업을 수행합니다.

> 브로커 로그의 항목에 Forbidden 오류 메시지가 있는지 확인합니다. 이 메시지는 인증 오류를 나타낼 뿐 그 원인은 나타내지 않습니다.

> - 파일 기반 사용자 저장소를 사용하는 경우 다음 명령을 입력합니다.

> imqusermgr list -i instanceName -u userName

> 출력에 사용자가 표시되는 경우 잘못된 비밀번호가 제출된 것일 수 있습니다. 출력에 Error [B3048]: User does not exist in the password file이 표시되는 경우 사용자 저장소에 항목이 없는 것입니다.

> - LDAP 서버 사용자 저장소를 사용 중인 경우 적절한 도구를 사용하여 사용자 항목이 있는지 확인합니다.
> - 액세스 제어 등록 정보에 연결 서비스 액세스에 대한 제한이 있는지 확인합니다.

> 문제를 해결하려면 다음 작업을 수행합니다.

> - 사용자 저장소에 사용자 항목이 없는 경우 사용자 저장소에 사용자를 추가합니다("사용자 저장소 채우기 및 관리" 참조).
> - 잘못된 비밀번호가 사용된 경우 올바른 비밀번호를 제공합니다.
> - 액세스 제어 등록 정보가 잘못 설정된 경우 액세스 제어 등록 정보 파일을 편집하여 연결 서비스 권한을 부여합니다("연결 액세스 제어" 참조).

> ### 문제: 연결 처리량이 너무 느림

> #### 증상:

> - 메시지 처리량이 기대에 미치지 못합니다.
> - 브로커에 대해 지원되는 연결 수가 "문제: 클라이언트가 연결을 설정할 수 없음"에 설명되어 있는 대로 제한되는 것이 아니라 메시지 입출력 속도에 의해 제한됩니다.

> #### 가능한 원인:

> - 네트워크 연결 또는 WAN이 너무 느립니다.

> 문제의 원인을 확인하려면 다음 작업을 수행합니다.

> 네트워크를 핑하여 핑이 반환되는 데 걸리는 시간을 확인한 다음 네트워크 관리자에게 문의합니다. 또는 로컬 클라이언트를 사용하여 메시지를 보내고 받은 다음 이 전달 시간을 네트워크 링크를 사용하는 원격 클라이언트의 전달 시간과 비교할 수 있습니다.

> 문제를 해결하려면 다음 작업을 수행합니다.

> 연결이 너무 느린 경우 네트워크 링크를 업그레이드합니다.

> - 연결 서비스 프로토콜이 기본적으로 TCP에 비해 느립니다. 예를 들어 SSL 기반 또는 HTTP 기반 프로토콜이 TCP보다 느립니다(그림 9-5 참조).

> 문제의 원인을 확인하려면 다음 작업을 수행합니다.

> SSL 기반 또는 HTTP 기반 프로토콜을 사용하는 경우 TCP를 사용해보고 전달 시간을 비교합니다.

> 문제를 해결하려면 다음 작업을 수행합니다.

> 일반적으로 응용 프로그램 요구 사항에 따라 사용되는 프로토콜이 지정되므로 "전송 프로토콜 조정"에 설명되어 있는 대로 프로토콜을 조정해보는 것 이외에 할 수 있는 작업이 거의 없습니다.

> - 연결 서비스 프로토콜이 최적으로 조정되어 있지 않습니다.

> 문제의 원인을 확인하려면 다음 작업을 수행합니다.

> 프로토콜을 조정해보고 차이가 있는지 확인합니다.

> 문제를 해결하려면 다음 작업을 수행합니다.

> "전송 프로토콜 조정"에 설명되어 있는 대로 프로토콜을 조정해봅니다.

> - 메시지가 너무 커서 너무 많은 대역폭을 사용합니다.

> 문제의 원인을 확인하려면 다음 작업을 수행합니다.

> 작은 크기의 메시지를 사용하여 벤치마크를 실행해 봅니다.

> 문제를 해결하려면 다음 작업을 수행합니다.

> - java.util.zip을 사용하여 메시지 본문을 압축합니다.
> - 메시지를 보낼 데이터의 알림으로 사용하고 데이터는 다른 프로토콜을 사용하여 이동합니다.
> - 느린 연결 처리량으로 보이는 것이 실제로는 메시지 전달 프로세스의 어떤 단계에 병목 현상이 있는 것입니다.

> 문제의 원인을 확인하려면 다음 작업을 수행합니다.

> 위의 항목 중 어떤 것도 느린 연결 처리량으로 보이는 문제의 원인이 아닌 것 같으면 그림 9-1을 참조하여 다른 병목 현상이 있을 수 있는지 확인하고 다음 문제와 관련된 증상이 있는지 확인합니다.

> - "문제: 메시지 생성이 지연되거나 느림"
> - "문제: 메시지가 메시지 서버에서 백로그됨"
> - "문제: 메시지 서버 처리량이 일정하지 않음"

> 문제를 해결하려면 다음 작업을 수행합니다.

> 위의 문제 해결 절에 제공되어 있는 문제 해결 지침을 따릅니다.

> ### 문제: 클라이언트가 메시지 생성자를 만들 수 없음

> #### 증상:

> - 대상에 대해 메시지 생성자를 만들 수 없기 때문에 클라이언트에서 예외가 발생합니다.

> #### 가능한 원인:

> - 대상이 제한된 생성자 수만 허용하도록 구성되었습니다.

> 대상에 메시지가 누적되는 것을 방지하는 방법 중 하나는 대상에서 지원할 수 있는 생성자의 수(maxNumProducers)를 제한하는 것입니다.

> 문제의 원인을 확인하려면 다음 작업을 수행합니다.

> 대상을 확인합니다("대상 정보 표시" 참조).

> imqcmd query dst

> 출력에 현재 생성자 수와 maxNumProducers 값이 표시됩니다. 두 값이 같은 경우 생성자의 수가 구성된 제한에 도달한 것입니다. 새 생성자가 브로커에서 거부되는 경우 브로커는 ResourceAllocationException [C4088]: A JMS destination limit was reached를 반환하고 브로커 로그에 [B4183]: Producer can not be added to destination이라는 항목을 만듭니다.

> 문제를 해결하려면 다음 작업을 수행합니다.

> maxNumProducers 속성 값을 늘립니다("대상 속성 업데이트" 참조).

> - 액세스 제어 등록 정보 파일의 설정으로 인해 사용자가 메시지 생성자를 만들 수 있는 권한이 없습니다.

> 문제의 원인을 확인하려면 다음 작업을 수행합니다.

> 새 생성자가 브로커에서 거부되는 경우 브로커는 JMSSecurityException [C4076]: Client does not have permission to create producer on destination을 반환하고 브로커 로그에 [B2041]: Producer on destination denied 및 [B4051]: Forbidden guest라는 항목을 만듭니다.

> 문제를 해결하려면 다음 작업을 수행합니다.

> 사용자가 메시지를 생성할 수 있도록 액세스 제어 등록 정보를 변경합니다("대상 액세스 제어" 참조).

> ### 문제: 메시지 생성이 지연되거나 느림

> #### 증상:

> - 지속성 메시지를 보낼 때 send() 메소드가 반환되지 않고 클라이언트가 차단됩니다.
> - 지속성 메시지를 보낼 때 클라이언트에 예외가 발생합니다.
> - 생성자 클라이언트가 느려집니다.

> #### 가능한 원인:

> - 메시지 서버가 백로그되고(메시지가 브로커 메모리에 누적) 느린 메시지 생성자로 응답했습니다.

> 대상 메모리의 메시지 수와 메시지 바이트 수가 구성된 제한에 도달하면 브로커가 지정된 제한 동작에 따라 메모리 자원을 절약하려고 합니다. 다음 제한 동작은 메시지 생성자를 느리게 만듭니다.

> - FLOW_CONTROL: 브로커가 지속성 메시지의 수신을 바로 확인하지 않습니다. 따라서 생성자 클라이언트가 차단됩니다.
> - REJECT_NEWEST: 브로커가 새 메시지를 거부합니다. 거부된 각 지속성 메시지에 대해 예외가 발생합니다.

> 마찬가지로 모든 대상의 브로커 전체 메모리에서 메시지 수나 메시지 바이트 수가 구성된 제한에 도달하면 브로커가 최신 메시지를 거부하여 메모리 자원을 절약하려고 합니다.

> 또한 대상이나 브로커 전체 제한이 제대로 설정되어 있지 않아 시스템 메모리 제한에 도달하면 브로커는 메시지 생성자를 억제하는 등 메모리 오버로드를 막기 위해 점점 더 중대한 조치를 취합니다.

> 이러한 메커니즘에 대한 자세한 내용은 "메모리 자원 및 메시지 흐름 관리"를 참조하십시오.

> 문제의 원인을 확인하려면 다음 작업을 수행합니다.

> 구성된 메시지 제한으로 인해 메시지가 브로커에서 거부되면 브로커는 JMSException [C4036]: A server error occurred를 반환하고 브로커 로그에 WARNING [B2011]: Storing of JMS message from IMQconn failed라는 항목을 만든 다음 제한에 도달했음을 나타내는 메시지를 표시합니다.

> - 메시지 제한이 대상에 있는 경우 브로커는 [B4120]: Can not store message on destination destName because capacity of maxNumMsgs would be exceeded와 같은 항목을 만듭니다.
> - 메시지 제한이 브로커 전체에 있는 경우 브로커는 [B4024]: The Maximum Number of messages currrently in the system has been exceeded, rejecting message와 같은 항목을 만듭니다.

> 좀 더 일반적으로는 대상과 브로커를 쿼리하여 각각에 구성된 메시지 제한 설정을 검사하고 적절한 imqcmd 명령을 사용하여 대상이나 브로커 전체에서 현재 메시지 수나 현재 메시지 바이트 수를 모니터링하여(각각 표 9-10 및 표 9-8 참조) 거부가 발생하기 전에 메시지 제한 조건을 확인할 수 있습니다.

> 문제를 해결하려면 다음 작업을 수행합니다.

> 메시지가 백로그되어 생성자가 느려지는 것을 해결하는 데에는 다음과 같은 몇 가지 방법이 있습니다.

> - 메모리 자원을 초과하지 않도록 주의하면서 대상(또는 브로커 전체)에 대한 메시지 제한을 수정합니다. 일반적으로는 브로커 전체 메시지 제한에 도달하는 일이 없도록 대상별로 메모리를 관리할 수 있습니다. 자세한 내용은 "브로커 조정"을 참조하십시오.
> - 메시지 제한에 도달하면 메시지 생성을 느리게 하기보다 메모리에서 메시지를 버리도록 대상의 제한 동작을 변경합니다. 예를 들어, 메모리에 누적되는 메시지를 삭제하는 REMOVE_OLDEST 및 REMOVE_LOW_PRIORITY 제한 동작을 지정할 수 있습니다(표 6-10 참조).
> - 브로커가 지속성 메시지를 데이터 저장소에 저장할 수 없습니다.

> 브로커가 데이터 저장소에 액세스할 수 없거나 지속성 메시지를 데이터 저장소에 기록할 수 없는 경우 생성자 클라이언트가 차단됩니다. 위에 설명되어 있는 대상 또는 브로커 전체 메시지 제한에 도달한 경우에도 이러한 상태가 발생할 수 있습니다.

> 문제의 원인을 확인하려면 다음 작업을 수행합니다.

> 브로커가 데이터 저장소에 기록할 수 없는 경우 브로커는 브로커 로그에 [B2011]: Storing of JMS message from connectionID failed...또는 [B4004]: Failed to persist message messageID...항목 중 하나를 만듭니다

> 문제를 해결하려면 다음 작업을 수행합니다.

> - 기본 제공 지속성의 경우 파일 기반 데이터 저장소의 디스크 공간을 늘립니다.
> - JDBC 호환 데이터 저장소의 경우 플러그 인 지속성이 제대로 구성되어 있는지 확인합니다(부록 B, "플러그 인 지속성 설정" 참조). 제대로 구성되어 있는 경우 데이터베이스 관리자에게 문의하여 다른 데이터베이스 문제를 해결합니다.
> - 브로커 확인 시간 초과가 너무 짧습니다.

> 느린 연결 또는 높은 CPU 사용률이나 부족한 메모리 자원 때문에 무기력해진 메시지 서버로 인해 브로커가 지속성 메시지의 수신을 확인하는 데 연결 팩토리의 imqAckTimeout 속성 값에서 허용하는 것보다 더 많은 시간이 필요할 수 있습니다.

> 문제의 원인을 확인하려면 다음 작업을 수행합니다.

> imqAckTimeout 값이 초과되는 경우 브로커는 JMSException [C4000]: Packet acknowledge failed를 반환합니다.

> 문제를 해결하려면 다음 작업을 수행합니다.

> imqAckTimeout 연결 팩토리 속성 값을 변경합니다("연결 팩토리 관리 대상 객체 속성" 참조).

> - 생성자 클라이언트에서 JVM 제한이 발생했습니다.

> 문제의 원인을 확인하려면 다음 작업을 수행합니다.

> - 클라이언트 응용 프로그램이 메모리 부족 오류를 수신하는지 확인합니다.
> - freeMemory(), MaxMemory(), totalMemory() 같은 런타임 메소드를 사용하여 JVM 힙에서 사용 가능한 메모리를 확인합니다.

> 문제를 해결하려면 다음 작업을 수행합니다.

> JVM을 조정합니다("Java 가상 머신 조정" 참조).

> ### 문제: 메시지가 메시지 서버에서 백로그됨

> #### 증상:

> - 브로커(또는 특정 대상)의 메시지나 메시지 바이트 수가 시간에 따라 꾸준하게 증가합니다.

> 메시지가 누적되고 있는지 확인하려면 브로커의 메시지나 메시지 바이트 수가 시간에 따라 어떻게 변하는지 확인하고 구성된 제한과 비교합니다. 먼저 구성된 제한을 확인합니다.

> imqcmd query bkr

> (주: imqcmd metrics bkr 하위 명령은 이 정보를 표시하지 않습니다.)

> 그런 다음 각 대상에서 메시지 누적을 확인합니다.

> imqcmd query dst -t destType -n destName
> 또는
> imqcmd metrics dst -t destType -n destName -m ttl

> 메시지가 대상이나 브로커 전체에 구성된 제한을 초과했는지 확인하려면 브로커 로그에서 WARNING [B2011]: Storing of JMS message from...failed라는 항목이 있는지 확인합니다. 이 항목 다음에는 초과된 제한에 대해 설명하는 다른 항목이 표시됩니다.

> - 메시지 생성이 지연되거나 생성된 메시지가 브로커에서 거부됩니다.
> - 메시지가 사용자에게 도달하기까지 비정상적으로 오래 걸립니다.

> #### 가능한 원인:

> - 클라이언트 코드에 결함이 있습니다. 사용자가 메시지를 확인하지 않습니다.

> 메시지는 메시지를 받은 모든 사용자가 확인할 때까지 대상에 보관됩니다. 따라서 클라이언트가 사용된 메시지를 확인하지 않는 경우 메시지는 삭제되지 않고 대상에 누적됩니다.

> 예를 들어, 클라이언트 코드에 다음 결함이 있을 수 있습니다.

> - CLIENT_ACKNOWLEDGEMENT 또는 트랜잭션된 세션을 사용하는 사용자가 Session.acknowledge() 또는 Session.commit()을 정기적으로 호출하고 있지 않을 수 있습니다.
> - AUTO_ACKNOWLEDGE 세션을 사용하는 사용자가 몇 가지 이유로 중지되어 있을 수 있습니다.

> 문제의 원인을 확인하려면 다음 작업을 수행합니다.

> 메시지 서버가 사용 중이지 않은 경우, 즉 대상에 메시지가 유입 및 유출되는 속도가 낮은 경우 메시지가 확인되지 않아 누적될 수 있습니다.

> 메시지가 브로커에 유입 및 유출되는 속도를 확인합니다.

> imqcmd metrics bkr -m rts

> 그런 다음 개별 대상 각각에 대한 흐름 속도를 확인합니다.

> imqcmd metrics bkr -t destType -n destName -m rts

> 또한 클라이언트 코드를 확인하여 메시지가 제대로 확인되고 있는지 확인합니다.

> - 주제 대상에 비활성 영구 가입이 있습니다.

> 영구 가입이 비활성 상태인 경우 해당 사용자가 활성화되어 메시지를 사용할 수 있을 때까지 대상에 메시지가 저장됩니다.

> 문제의 원인을 확인하려면 다음 작업을 수행합니다.

> 각 주제 대상에서 영구 가입 상태를 확인합니다.

> imqcmd list dur -d destName

> 문제를 해결하려면 다음 작업을 수행합니다.

> 다음 작업 중 하나를 수행할 수 있습니다.

> - 문제가 있는 영구 가입의 모든 메시지를 제거합니다("영구 가입 관리" 참조).
> - 주제에 대해 메시지 제한 및 제한 동작 속성을 지정합니다(표 6-10 참조). 예를 들어, 메모리에 누적되는 메시지를 삭제하는 REMOVE_OLDEST 및 REMOVE_LOW_PRIORITY 제한 동작을 지정할 수 있습니다.
> - 해당 대상에서 모든 메시지를 제거합니다("대상 제거" 참조).
> - 메시지가 메모리에 남아 있을 수 있는 시간을 제한합니다. 생성자 클라이언트를 다시 작성하여 각 메시지의 수명 값을 설정할 수 있습니다. imqOverrideJMSExpiration 및 imqJMSExpiration 연결 팩토리 속성을 설정하여 연결을 공유하는 모든 생성자에 대해 이러한 설정을 대체할 수 있습니다(표 7-3 참조).
> - 대기열의 메시지를 사용할 수 있는 사용자 수가 너무 적습니다.

> 메시지를 전달할 수 있는 활성 사용자의 수가 너무 적은 경우 메시지가 누적될 때 대기열 대상이 백로그될 수 있습니다. 이런 상태는 다음과 같은 이유 중 하나 때문에 발생할 수 있습니다.

> - 대상에 활성 사용자가 수가 너무 적습니다.
> - 사용자 클라이언트가 연결을 설정하지 못했습니다.
> - 대기열의 메시지에 일치하는 선택기를 사용하는 활성 사용자가 없습니다.

> 문제의 원인을 확인하려면 다음 작업을 수행합니다.

> 사용자가 대기열의 메시지를 사용할 수 없는 원인을 확인하려면 대상에서 활성 사용자의 수를 확인합니다.

> imqcmd metrics dst -n destName -t q -m con

> 문제를 해결하려면 다음 작업을 수행합니다.

> 사용자가 대기열의 메시지를 사용할 수 없는 원인에 따라 다음 작업 중 하나를 수행할 수 있습니다.

> - 추가 사용자 클라이언트를 시작하여 대기열에 더 많은 활성 사용자를 만듭니다.
> - imq.consumerFlowLimit 브로커 등록 정보를 조정하여 여러 사용자에 대한 대기열 전달을 최적화합니다("다중 사용자 대기열 성능" 참조).
> - 대기열에 대해 메시지 제한 및 제한 동작 속성을 지정합니다(표 6-10 참조). 예를 들어, 메모리에 누적되는 메시지를 삭제하는 REMOVE_OLDEST 및 REMIOVE_LOW_PRIOROTY 제한 동작을 지정할 수 있습니다.
> - 해당 대상에서 모든 메시지를 제거합니다("대상 제거" 참조).
> - 메시지가 메모리에 남아 있을 수 있는 시간을 제한합니다. 생성자 클라이언트를 다시 작성하여 각 메시지의 수명 값을 설정할 수 있습니다. imqOverrideJMSExpiration 및 imqJMSExpiration 연결 팩토리 속성을 설정하여 연결을 공유하는 모든 생성자에 대해 이러한 설정을 대체할 수 있습니다(표 7-3 참조).
> - 메시지 사용자가 너무 느리게 처리하여 메시지 생성자를 따라가지 못합니다.

> 이 경우 주제 가입자나 대기열 수신자가 메시지를 사용하는 것이 생성자가 메시지를 보내는 것보다 느립니다. 이러한 불균형으로 인해 하나 이상의 대상이 메시지로 백로그됩니다.

> 문제의 원인을 확인하려면 다음 작업을 수행합니다.

> 메지지가 브로커에 유입 및 유출되는 속도를 확인합니다.

> imqcmd metrics bkr -m rts

> 그런 다음 개별 대상 각각에 대한 흐름 속도를 확인합니다.

> imqcmd metrics bkr -t destType -n destName -m rts

> 문제를 해결하려면 다음 작업을 수행합니다.

> - 사용자 클라이언트 코드를 최적화합니다.
> - 대기열 대상의 경우 활성 사용자의 수를 늘립니다("다중 사용자 대기열 성능" 참조).
> - 클라이언트 확인 처리가 메시지 사용을 느리게 합니다.

> 두 가지 요소가 클라이언트 확인의 처리에 영향을 미칩니다.

> - 상당한 브로커 자원이 클라이언트 확인 처리에 사용될 수 있습니다. 따라서 브로커가 클라이언트 확인을 확인할 때까지 사용자 클라이언트가 차단되는 확인 모드에서는 메시지 사용이 느려질 수 있습니다.
> - JMS 페이로드 메시지와 Message Queue 제어 메시지(예: 클라이언트 확인)는 같은 연결을 공유합니다. 따라서 JMS 페이로드 메시지에 의해 제어 메시지가 일시적으로 중단되어 메시지 사용이 느려질 수 있습니다.

> 문제의 원인을 확인하려면 다음 작업을 수행합니다.

> 패킷 흐름을 기준으로 메시지 흐름을 확인합니다. 초당 패킷 수와 메시지 수의 비율이 맞지 않으면 클라이언트 확인에 문제가 있을 수 있습니다.

> 또는 클라이언트가 JMSException [C4000]: Packet acknowledge failed 메시지를 받았는지 확인합니다.

> 문제를 해결하려면 다음 작업을 수행합니다.

> - 클라이언트가 사용하는 확인 모드를 수정합니다. 예를 들어 DUPS_OK_ACKNOWLEDGEMENT나 CLIENT_ACKNOWLEDGEMENT로 전환합니다.
> - CLIENT_ACKNOWLEDGEMENT 또는 트랜잭션된 세션을 사용 중인 경우 많은 수의 메시지를 하나의 확인으로 그룹화합니다.
> - 사용자 및 연결 흐름 제어 매개 변수를 조정합니다("클라이언트 런타임 메시지 흐름 조정" 참조).
> - 브로커가 생성된 메시지를 따라갈 수 없습니다.

> 이 경우 메시지가 브로커로 유입되는 것이 브로커가 메시지를 라우팅하여 사용자에게 전달하는 것보다 빠릅니다. 브로커의 지체는 CPU, 네트워크 소켓 읽기/쓰기 작업, 디스크 읽기/쓰기 작업, 메모리 페이징, 영구 저장소, JVM 메모리 제한 중 하나나 모두에 대한 제한 때문일 수 있습니다.

> 문제의 원인을 확인하려면 다음 작업을 수행합니다.

> 이 문제를 일으키는 다른 원인은 없는지 확인합니다.

> 문제를 해결하려면 다음 작업을 수행합니다.

> - 컴퓨터나 데이터 저장소의 속도를 업그레이드합니다.
> - 브로커 클러스터를 사용하여 로드를 여러 브로커 인스턴스에 분산합니다.

> ### 문제: 메시지 서버 처리량이 일정하지 않음

> #### 증상:

> - 메시지 처리량이 산발적으로 떨어지다가 정상 성능을 회복합니다.

> #### 가능한 원인:

> - 브로커의 메모리 자원이 매우 적습니다.

> 대상 및 브로커 제한이 제대로 설정되어 있지 않기 때문에 브로커가 메모리 오버로드를 막기 위해 점점 더 중대한 조치를 취하게 되어 메시지 백로그를 지울 때까지 브로커가 아주 느려질 수 있습니다.

> 문제의 원인을 확인하려면 다음 작업을 수행합니다.

> 브로커 로그에서 부족한 메모리 상태([B1089]: In low memory condition, broker is attempting to free up resources)와 새 메모리 상태 및 사용 중인 전체 메모리 양에 대해 설명하는 항목이 있는지 확인합니다.

> 또한 JVM 힙에서 사용 가능한 메모리를 확인합니다.

> imqcmd metrics bkr -m cxn

> 전체 JVM 메모리의 값이 최대 JVM 메모리 값에 근접한 경우 사용 가능한 메모리가 적습니다.

> 문제를 해결하려면 다음 작업을 수행합니다.

> - JVM을 조정합니다("Java 가상 머신 조정" 참조).
> - 시스템 스왑 공간을 늘립니다.
> - JVM 메모리 재생 이용(가비지 컬렉션)이 발생합니다.

> 메모리를 확보하기 위해 메모리 재생 이용이 주기적으로 시스템을 정리합니다. 이럴 경우 모든 스레드가 차단됩니다. 확보할 메모리 양이 크고 JVM 힙 크기가 클수록 메모리 재생 이용으로 인한 지체가 길어집니다.

> 문제의 원인을 확인하려면 다음 작업을 수행합니다.

> 컴퓨터의 CPU 사용을 모니터합니다. 메모리 재생 이용이 발생하면 CPU 사용이 크게 떨어집니다.

> 또는 다음 명령줄 옵션을 사용하여 브로커를 시작합니다.

> -vmargs -verbose:gc

> 표준 출력에 메모리 재생 이용이 발생하는 시간이 표시됩니다.

> 문제를 해결하려면 다음 작업을 수행합니다.

> 다중 CPU 컴퓨터인 경우 메모리 재생 이용이 병렬로 발생되도록 설정합니다.

> -XX:+UseParallelGC=true

> - JVM이 성능을 높이기 위해 JIT (Just-In-Time) 컴파일러를 사용하고 있습니다.

> 문제의 원인을 확인하려면 다음 작업을 수행합니다.

> 이 문제를 일으키는 다른 원인은 없는지 확인합니다.

> 문제를 해결하려면 다음 작업을 수행합니다.

> 잠시 동안 시스템이 실행되도록 놓아두면 성능이 향상됩니다.

> ### 문제: 메시지가 사용자에게 도달하지 않음

> #### 증상:

> - 생성자가 보낸 메시지를 사용자가 받지 못합니다.

> #### 가능한 원인:

> - 제한 동작으로 인해 메시지가 브로커에서 삭제됩니다.

> 대상 메모리의 메시지 수나 메시지 바이트 수가 구성된 제한에 도달하면 브로커는 메모리 자원을 절약하려고 합니다. 이러한 제한에 도달하면 브로커가 수행하는 구성 가능한 동작 중 다음 세 가지 동작으로 인해 메시지가 손실됩니다.

> - REMOVE_OLDEST: 가장 오래된 메시지를 삭제
> - REMOVE_LOW_PRIORITY: 메시지의 보존 기간을 기준으로 우선 순위가 가장 낮은 메시지 삭제
> - REJECT_NEWEST: 새 메시지 거부(거부된 지속성 메시지에 대해 예외 발생)

> 브로커 메모리의 메시지 수나 메시지 바이트 수가 구성된 제한에 도달하면 브로커는 최신 메시지를 거부하여 메모리 자원을 절약하려고 합니다.

> 문제의 원인을 확인하려면 다음 작업을 수행합니다.

> 브로커 로그에서 WARNING [B2011]: Storing of JMS message from...failed 항목이 있는지 확인합니다. 이 항목 다음에는 초과된 제한에 대해 설명하는 다른 항목이 표시됩니다. 하지만 메시지 삭제를 나타내는 항목은 없습니다.

> 문제를 해결하려면 다음 작업을 수행합니다.

> 제한을 변경하거나 동작을 변경합니다.

> - 메시지 시간 초과 값이 만료됩니다.

> 브로커는 시간 초과 값이 만료된 메시지를 삭제합니다. 대상이 충분히 메시지로 백로그된 경우 수명 값이 너무 짧은 메시지는 삭제될 수 있습니다.

> 문제의 원인을 확인하려면 다음 작업을 수행합니다.

> 브로커 로그 파일에서 Expiring Messages: Expired n messages라는 항목이 있는지 확인합니다.

> 문제를 해결하려면 다음 작업을 수행합니다.

> 대체합니다.

> - 다른 컴퓨터 간에 클럭 시간이 동기화되지 않습니다.

> 클럭이 동기화되어 있지 않은 경우 브로커의 메시지 수명 계산에 오류가 생길 수 있으므로 메시지가 만료 시간을 초과하여 삭제됩니다.

> 문제의 원인을 확인하려면 다음 작업을 수행합니다.

> 모든 컴퓨터의 클럭을 확인합니다.

> 문제를 해결하려면 다음 작업을 수행합니다.

> 클럭을 동기화합니다("시스템 클럭 설정" 참조).

> - 사용자 클라이언트가 연결에서 메시지 전달을 시작하지 못했습니다.

> 클라이언트 코드가 연결을 설정하고 해당 연결에서 메시지 전달을 시작할 때까지 메시지를 전달할 수 없습니다.

> 문제의 원인을 확인하려면 다음 작업을 수행합니다.

> 클라이언트 코드가 연결을 설정하고 메시지 전달을 시작하는지 확인합니다.

> 문제를 해결하려면 다음 작업을 수행합니다.

> 연결을 설정하고 메시지 전달을 시작하도록 클라이언트 코드를 다시 작성합니다.

> ##

> 성능 향상을 위한 구성 조정

> ### 시스템 조정

> 다음 절에서는 운영 체제, JVM 및 통신 프로토콜에서 조정할 수 있는 내용을 설명합니다.

> #### Solaris 조정: CPU 사용률, 페이징/스왑/디스크 입출력

> 운영 체제 조정에 대해서는 시스템 설명서를 참조하십시오.

> #### Java 가상 머신 조정

> 기본적으로 브로커는 192MB의 JVM 힙 크기를 사용합니다. 이 크기는 상당한 메시지 로드에 비해 너무 작은 경우가 많으므로 늘리는 것이 좋습니다.

> 브로커가 Java 객체에서 사용되는 JVM 힙 공간을 소진하는 데 이르면 브로커는 흐름 제어, 메시지 스왑 등 여러 기술을 사용하여 메모리를 확보합니다. 아주 드물게 메모리를 확보하고 메시지 유입을 줄이기 위해 클라이언트 연결을 닫는 경우도 있습니다. 따라서, 이러한 경우가 발생하지 않도록 최대 JVM 힙 공간을 충분하게 설정하는 것이 좋습니다.

> 하지만, 최대 Java 힙 공간을 너무 높게 설정하면 브로커가 전체 시스템 메모리가 부족해 질 때까지 Java 힙 공간을 계속해서 증가시킬 수 있습니다. 그렇게 되면 성능이 감소하거나, 예상치 않은 브로커 충돌이 발생하거나, 시스템에서 실행 중인 다른 응용 프로그램 및 서비스의 동작에 영향을 미칠 수 있습니다. 일반적으로 운영 체제 및 시스템에서 실행할 다른 응용 프로그램이 충분한 물리적 메모리를 사용할 수 있도록 해야 합니다.

> 일반적으로 정상 시스템 메모리와 최대 시스템 메모리를 평가하여 시스템 메모리 문제를 일으키지 않고 우수한 성능을 제공할 수 있도록 Java 힙 크기를 구성하는 것이 좋습니다.

> 브로커의 최소 및 최대 힙 크기를 변경하려면 브로커를 시작할 때 -vmargs 명령줄 옵션을 사용합니다. 예를 들면 다음과 같습니다.

> /usr/bin/imqbrokerd -vmargs "-Xms256m -Xmx1024m"

> 이 명령은 시작 Java 힙 크기를 256MB로 설정하고 최대 Java 힙 크기를 1GB로 설정합니다.

> - Solaris에서 /etc/rc (즉, /etc/init.d/imq)를 통해 브로커를 시작하는 경우 /etc/imq/imqbrokerd.conf 파일에 브로커 명령줄 인수를 지정합니다. 자세한 내용은 해당 파일의 주석을 참조하십시오.
> - Windows에서 브로커를 Windows 서비스로 시작하는 경우 imqsvcadmin install 명령에 -vmargs 옵션을 사용하여 JVM 인수를 지정합니다. "서비스 관리자 유틸리티(imqsvcadmin)"를 참조하십시오.

> 어떤 경우든 브로커 로그 파일을 확인하거나
> imqcmd metrics bkr -m cxn 명령을 사용하여 설정을 확인합니다.

> #### 전송 프로토콜 조정

> 응용 프로그램 요구에 맞는 프로토콜을 선택했으면 선택한 프로토콜을 기반으로 추가 조정하여 성능을 향상시킬 수 있습니다.

> 다음 세 가지 브로커 등록 정보를 사용하여 프로토콜의 성능을 수정할 수 있습니다.

> - imq.protocol protocol_type nodelay
> - imq.protocol protocol_type inbufsz
> - imq.protocol protocol_type outbufsz

> TCP 및 SSL 프로토콜의 경우 이러한 등록 정보는 클라이언트와 브로커 사이의 메시지 전달 속도에 영향을 미칩니다. HTTP 및 HTTPS 프로토콜의 경우 이 등록 정보는 Web Server에서 실행 중인 Message Queue 터널 서블릿과 브로커 사이의 메시지 전달 속도에 영향을 미칩니다. HTTP/HTTPS 프로토콜의 경우 성능에 영향을 미칠 수 있는 추가 등록 정보가 있습니다("HTTP/HTTPS 조정" 참조).

> 프로토콜 조정 등록 정보에 대해서는 다음 절에서 설명합니다.

> ##### nodelay

> nodelay 등록 정보는 지정된 프로토콜의 Nagle 알고리즘(TCP/IP에서 TCP_NODELAY 소켓 수준 옵션 값)에 영향을 미칩니다. Nagle 알고리즘은 WAN (Wide-Area Network) 같은 느린 연결을 사용하는 시스템에서 TCP 성능을 향상시키는 데 사용됩니다.

> 이 알고리즘이 사용되면 TCP는 여러 개의 작은 데이터 청크가 원격 시스템으로 보내지지 않도록 데이터를 큰 패킷으로 묶으려고 합니다. 소켓에 기록된 데이터가 필요한 버퍼 크기를 채우지 못하는 경우 프로토콜은 버퍼가 채워지거나 특정 지연 시간이 경과될 때까지 패킷 전송을 지연합니다. 버퍼가 채워지거나 시간 초과가 발생하면 패킷을 보냅니다.

> 대부분의 메시징 응용 프로그램에서 패킷을 지연 없이 보내는 경우(Nagle 알고리즘을 사용하지 않는 경우) 최고의 성능을 냅니다. 이는 클라이언트와 브로커 사이의 상호 작용이 대부분 클라이언트가 데이터 패킷을 브로커에게 보내고 응답을 기다리는 요청/응답 상호 작용이기 때문입니다. 예를 들어, 일반적인 상호 작용에는 다음이 포함됩니다.

> - 연결 만들기
> - 생성자 또는 사용자 만들기
> - 지속성 메시지 보내기(브로커가 메시지 수신 확인)
> - AUTO_ACKNOWLEDGE 또는 CLIENT_ACKNOWLEDGE 세션에서 클라이언트 확인 보내기(브로커가 확인 처리 확인)

> 이러한 상호 작용에서 대부분의 패킷은 버퍼 크기보다 작습니다. 이는 Nagle 알고리즘이 사용되는 경우 브로커가 사용자에게 응답을 보내기 전에 몇 밀리초를 지연함을 의미합니다.

> 하지만 Nagle 알고리즘은 연결이 느리고 브로커 응답이 필요하지 않은 경우 성능을 향상시킬 수 있습니다. 이런 것으로는 클라이언트가 비지속성 메시지를 보내는 경우나 클라이언트 확인을 브로커에서 확인하지 않는 경우(DUPS_OK_ACKNOWLEDGE 세션)를 들 수 있습니다.

> ##### inbufsz/outbufsz

> inbufsz 등록 정보는 소켓에서 들어오는 데이터를 읽는 입력 스트립의 버퍼 크기를 설정합니다. 마찬가지로 outbufsz는 데이터를 소켓에 기록하기 위해 브로커가 사용하는 출력 스트림의 버퍼 크기를 설정합니다.

> 일반적으로 두 매개 변수 모두 보내거나 받는 평균 패킷보다 약간 큰 값으로 설정해야 합니다. 경험에 따르면 이 등록 정보 값을 평균 패킷에 1k를 더한 크기(가장 가까운 k 값으로 반올림)로 설정하는 것이 좋습니다.

> 예를 들어, 브로커가 본문 크기가 1k인 패킷을 받는 경우 패킷의 전체 크기(메시지 본문 + 헤더 + 등록 정보)는 약 1200바이트입니다. inbufsz가 2k (2048바이트)인 경우 적당한 성능을 제공합니다.

> inbufsz나 outbufsz를 이 크기보다 더 키우면 성능은 약간 늘어날 수 있지만 각 연결에 필요한 메모리가 늘어나게 됩니다.

> 그림 9-7은 1k 패킷에 대해 inbufsz를 변경할 때의 결과를 보여 줍니다.

> 그림 9-7 1k (1024바이트) 패킷에 대한 inbufsz 변경의 결과

> 그림 9-8은 1k 패킷에 대해 outbufsz를 변경할 때의 결과를 보여 줍니다.

> 그림 9-8 1k (1024바이트) 패킷에 대한 outbufsz 변경의 결과

> ##### HTTP/HTTPS 조정

> 앞의 두 절에서 설명한 일반 등록 정보 이외에도 HTTP/HTTPS 성능은 클라이언트가 Message Queue 터널 서블릿을 호스트하는 Web Server에 대해 HTTP 요청을 얼마나 빨리 보낼 수 있는지에 따라 제한됩니다.

> 단일 소켓에서 다중 요청을 처리하도록 Web Server를 최적화해야 할 수 있습니다. JDK 버전 1.4 이상에서는 Web Server에 대한 HTTP 연결이 유지되어(Web Server 소켓이 열린 상태로 유지) 다중 HTTP 요청을 처리할 때 Web Server에서 사용되는 자원을 최소화합니다. JDK 버전 1.4를 사용하는 클라이언트 응용 프로그램의 성능이 이전 JDK 릴리스로 실행 중인 같은 응용 프로그램보다 느린 경우 성능을 향상시키기 위해 Web Server의 연결 유지 구성 매개 변수를 조정해야 할 수 있습니다.

> 이러한 Web Server 조정과 더불어 클라이언트가 Web Server를 폴하는 간격도 조정할 수 있습니다. HTTP는 요청 기반 프로토콜입니다. 따라서 HTTP 기반 프로토콜을 사용하는 클라이언트는 Web Server에서 메시지가 대기 중인지 주기적으로 확인해야 합니다. imq.httpjms.http.pullPeriod 브로커 등록 정보(및 해당 imq.httpsjms.https.pullPeriod 등록 정보)는 Message Queue 클라이언트 런타임이 Web Server를 폴하는 간격을 지정합니다.

> pullPeriod 값이 -1 (기본값)인 경우 클라이언트 런타임은 이전 요청이 반환되자마자 서버를 폴하여 개별 클라이언트의 성능을 최대화합니다. 따라서 각 클라이언트 연결이 Web Server의 요청 스레드를 독점하여 Web Server 자원이 고갈될 수 있습니다.

> pullPeriod 값이 양수인 경우 클라이언트 런타임은 주기적으로 Web Server에 요청을 보내 보류 중인 데이터가 있는지 확인합니다. 이 경우 클라이언트가 Web Server의 요청 스레드를 독점하지 않습니다. 따라서 많은 수의 클라이언트가 Web Server를 사용 중인 경우 pullPeriod를 양수로 설정하면 Web Server 자원을 절약할 수 있습니다.

> #### 파일 기반 영구 저장소 조정

> 파일 기반 영구 저장소 조정에 대한 자세한 내용은 "기본 제공 지속성"을 참조하십시오.

> ### 브로커 조정

> 다음 절에서는 브로커 등록 정보를 조정하여 성능을 향상시키는 방법에 대해 설명합니다.

> #### 메모리 관리: 로드 하에서 브로커 안정성 증가

> 대상별 또는 시스템 전체 수준(모든 대상을 묶어서)에서 메모리 관리를 구성할 수 있습니다.

> ##### 대상 제한 사용

> 대상 제한에 대한 자세한 내용은 "대상 관리"를 참조하십시오.

> ##### 시스템 전체 제한 사용

> 메시지 생성자가 메시지 사용자보다 넘치는 경향이 있는 경우 메시지가 브로커에 누적될 수 있습니다. 브로커에는 메모리가 부족한 경우 생성자를 억제하고 활성 메모리로부터 메시지를 스왑하는 메커니즘이 포함되어 있지만("메모리 자원 및 메시지 흐름 관리" 참조) 브로커가 보관할 수 있는 전체 메시지(및 메시지 바이트) 수에 대해 엄격한 제한을 설정하는 것이 좋습니다.

> imq.system.max_count 및 imq.system.max_size 브로커 등록 정보를 설정하여 이러한 제한을 제어합니다. 브로커 등록 정보 설정에 대한 자세한 내용은 "인스턴스 구성 파일 편집" 또는 "imqbrokerd 옵션 요약"을 참조하십시오.

> 예를 들면 다음과 같습니다.

> imq.system.max_count=5000

> 위에서 정의한 값은 브로커가 전달되지 않은/확인되지 않은 메시지를 5000개까지만 보관함을 의미합니다. 추가로 보내는 메시지는 브로커에서 거부됩니다. 메시지가 지속성인 경우 생성자가 메시지를 보내려고 하면 예외가 발생합니다. 메시지가 비지속성인 경우 브로커는 메시지를 자동으로 삭제합니다.

> 비지속성 메시지가 지속성 메시지처럼 예외를 반환하게 하려면 클라이언트가 사용하는 연결 팩토리 객체에 대해 다음 등록 정보를 설정합니다.

> imqAckOnProduce = true

> 위의 설정은 비지속성 메시지를 브로커로 보낼 때의 성능을 저하시킬 수 있지만(클라이언트가 다음 메시지를 보내기 전에 응답을 기다림) 브로커로의 메시지 유입은 일반적으로 시스템 병목 현상이 아니므로 종종 이 설정이 허용되기도 합니다.

> 메시지를 보낼 때 예외가 반환되면 클라이언트는 잠시 동안 일시 중지하고 다시 보내 보아야 합니다.

> #### 다중 사용자 대기열 성능

> 다중 대기열 사용자가 대기열 대상에서 메시지를 처리하는 효율성은 구성 가능한 대기열 대상 속성, 즉 활성 사용자의 수(maxNumActiveConsumers)와 단일 일괄 처리로 사용자에게 전달할 수 있는 최대 메시지 수(consumerFlowLimit)에 따라 달라집니다 이 속성들에 대해서는 표 6-10에서 설명합니다.

> 최적의 메시지 처리량을 달성하려면 대기열의 메시지 생성 속도에 부합하는 충분한 활성 사용자의 수가 있어야 하며 대기열의 메시지를 그 사용 속도를 최대화할 수 있는 방식으로 라우팅한 다음 활성 사용자에게 전달해야 합니다. 여러 사용자 간에 메시지 전달의 균형을 조정하기 위한 일반 메커니즘에 대해서는 "다중 사용자로의 대기열 전달"에서 설명합니다.

> 메시지가 대기열에 누적되고 있는 경우 활성 사용자 수가 메시지 로드를 처리하기에 충분하지 않을 수 있습니다. 또는 사용자에서 메시지 정체를 일으키는 일괄 처리 크기로 메시지가 사용자에게 전달되고 있을 수 있습니다. 예를 들어 일괄 처리 크기(consumerFlowLimit)가 너무 큰 경우 한 사용자가 대기열의 모든 메시지를 받는 동안 다른 활성 사용자는 메시지를 전혀 받지 못할 수 있습니다. 사용자가 아주 빠른 경우 이것은 문제가 되지 않을 수 있습니다.

> 하지만 사용자가 비교적 느린 경우 메시지를 사용자에게 균등하게 분산시켜야 하므로 일괄 처리 크기가 작은 게 좋습니다. 일괄 처리 크기가 작을수록 메시지를 사용자에게 전달하는 데 더 많은 오버헤드가 필요합니다. 그럼에도 불구하고 느린 사용자의 경우 작은 일괄 처리 크기를 사용하는 것이 결과적으로 성능 향상이 있습니다.

> ### 클라이언트 런타임 메시지 흐름 조정

> 이 절에서는 성능에 영향을 미치는 흐림 제어 동작을 설명합니다("클라이언트 런타임 구성" 참조). 이러한 동작은 연결 팩토리 관리 대상 객체의 속성으로 구성됩니다. 연결 팩토리 속성 설정에 대한 자세한 내용은 7장, "관리 대상 객체 관리"를 참조하십시오.

> #### 메시지 흐름 측정

> 클라이언트가 보내고 받는 메시지(JMS 메시지)와 Message Queue 제어 메시지는 같은 클라이언트-브로커 연결을 통해 전달됩니다. 제어 메시지가 JMS 메시지 전달로 인해 일시 중단되면 브로커 확인처럼 제어 메시지 전달이 지연될 수 있습니다. 이러한 유형의 혼잡을 막기 위해 Message Queue는 연결에서 JMS 메시지의 흐름을 측정합니다.

> JMS 메시지는 imqConnectionFlowCount 등록 정보에서 지정한 대로 설정된 수만 전달되도록 일괄 처리됩니다. 일괄 처리가 전달되면 JMS 메시지 전달이 일시 중지되고 보류 중인 제어 메시지가 전달됩니다. JMS 메시지의 다른 일괄 처리가 전달된 다음 대기열에 있던 제어 메시지가 전달되는 식으로 이러한 주기가 반복됩니다.

> 클라이언트가 브로커에 많은 응답을 요구하는 작업을 수행 중인 경우(예: 클라이언트가 CLIENT_ACKNOWLEDGE 또는 AUTO_ACKNOWLEDGE 모드, 지속성 메시지, 트랜잭션, 대기열 브라우저를 사용하고 있거나 클라이언트가 사용자를 추가 또는 제거하고 있는 경우) imqConnectionFlowCount 값을 낮게 유지해야 합니다. 반면 클라이언트에 연결에서 DUPS_OK_ACKNOWLEDGE 모드를 사용하는 단순 사용자만 있는 경우 성능을 저하시키지 않고 imqConnectionFlowCount를 늘릴 수 있습니다.

> #### 메시지 흐름 제한

> 메모리와 같은 로컬 자원 제한이 발생하기 전에 Message Queue 클라이언트 런타임이 처리할 수 있는 JMS 메시지 수에 대한 제한이 있습니다. 이 제한에 가까워지면 성능에 악영향을 줍니다. 따라서 Message Queue에서는 연결을 통해 전달되고 클라이언트 런타임에 버퍼링되어 사용 대기 중일 수 있는 사용자당 메시지(또는 연결당 메시지) 수를 제한할 수 있습니다.

> ##### 사용자 기반 제한

> 클라이언트 런타임에 전달된 JMS 메시지 수가 사용자의 imqConsumerFlowLimit 값을 초과하면 해당 사용자에 대해 메시지 전달이 중지됩니다. 해당 사용자의 사용되지 않은 메시지 수가 imqConsumerFlowThreshold에 설정된 값 이하로 떨어져야만 메시지 전달이 재개됩니다.

> 다음은 이러한 제한의 사용을 보여 주는 예입니다. 주제 사용자의 기본 설정을 고려해 보십시오.

> imqConsumerFlowLimit=1000

> imqConsumerFlowThreshold=50

> 사용자가 만들어지면 브로커는 초기 일괄 처리인 1000개의 메시지(있는 경우)를 일시 중지 없이 이 사용자에게 전달합니다. 1000개의 메시지를 보낸 다음 브로커는 클라이언트 런타임이 추가 메시지를 요청할 때까지 전달을 중지합니다. 클라이언트 런타임은 응용 프로그램이 메시지를 처리할 때까지 이 메시지들을 보관합니다. 그런 다음 클라이언트 런타임은 브로커에게 다음 일괄 처리를 보내도록 요청하기 전에 응용 프로그램이 적어도 메시지 버퍼 용량(imqConsumerFlowThreshold)의 50% (즉, 500개의 메시지)를 사용할 수 있도록 합니다.

> 같은 상황에서 임계값이 10%인 경우 클라이언트 런타임은 다음 일괄 처리를 요청하기 전에 응용 프로그램이 최소 900개의 메시지를 사용할 때까지 기다립니다.

> 다음 일괄 처리 크기는 다음과 같이 계산됩니다.

> imqConsumerFlowLimit - (버퍼에서 현재 보류 중인 메시지 수)

> 따라서 imqConsumerFlowThreshold가 50%인 경우 다음 일괄 처리 크기는 응용 프로그램의 메시지 처리 속도에 따라 500과 1000 사이에서 변동될 수 있습니다.

> imqConsumerFlowThreshold가 너무 높게 설정된 경우(100% 가까이) 브로커는 더 작은 일괄 처리를 보내는 경향이 있으므로 메시지 처리량이 떨어질 수 있습니다. 이 값이 너무 낮게 설정된 경우(0% 가까이) 브로커가 다음 집합을 전달하기 전에 클라이언트가 버퍼링된 나머지 메시지를 모두 처리할 수 있으므로 메시지 처리량이 저하됩니다. 일반적으로 특정 성능이나 안정성 문제가 있는 경우가 아니라면 imqConsumerFlowThreshold 속성의 기본값을 변경할 필요가 없습니다.

> 사용자 기반 흐름 제어(특히 imqConsumerFlowLimit)는 클라이언트 런타임의 메모리 관리에 가장 좋은 방법입니다. 일반적으로 클라이언트 응용 프로그램에 따라 연결에서 지원해야 할 사용자 수, 메시지 크기 및 클라이언트 런타임에서 사용할 수 있는 전체 메모리 양에 대해 알고 있습니다.

> ##### 연결 기반 제한

> 하지만 일부 클라이언트 응용 프로그램의 경우 최종 사용자의 선택에 따라 사용자 수가 불확실할 수 있습니다. 이러한 경우에도 연결 수준 흐름 제한을 사용하여 메모리를 관리할 수 있습니다.

> 연결 수준 흐름 제어는 연결의 모든 사용자에 대해 버퍼링되는 전체 메시지 수를 제한합니다. 이 수가 imqConnectionFlowLimit를 초과하면 전체 수가 연결 제한 아래로 떨어질 때까지 해당 연결을 통한 메시지 전달이 중지됩니다(imqConnectionFlowLimitEnabled 등록 정보를 true로 설정하는 경우에만 imqConnectionFlowLimit를 사용할 수 있음).

> 세션의 대기열에 있는 메시지 수는 각 사용자의 메시지 로드와 세션을 사용하는 메시지 사용자 수의 함수입니다. 클라이언트가 메시지를 생성하거나 사용할 때 지연을 나타내는 경우 일반적으로 응용 프로그램을 재설계하여 메시지 생성자와 사용자를 여러 세션에 분산시키거나 세션을 여러 연결에 분산시킴으로써 성능을 향상시킬 수 있습니다.

> 이전 목차 색인 다음

> Copyright 2004 Sun Microsystems, Inc. 모든 권리는 저작권자의 소유입니다.