자바가 사용하는 메모리의 종류와 특징

|

http://drkein.tistory.com/95

 

상황인지 미들웨어를 개발하다 보니.. 
성능면에서 등록 가능한 룰의 갯수를 측정해 본적이 있다.
그런데, 약 8만개 정도의 룰을 등록하니 OutOfMemory 에러가 발생.. 
일단 jvm 에서 -Xmx1024로 메모리를 늘려 잡아서 10만개 까지 룰 등록을 하긴 했는데.. 
원인을 알아야 해결을 할 수 있을것 같다.. 

자... 
자바가 사용하는 메모리의 종류엔 뭐가 있을까... 
얼핏 떠오르는게 힙 메모리 밖에 없다..  (근데, Heap 메모리는 뭐지? )

일단 여기저기에서 찾아낸 자바 메모리 관련 정보를 정리해 보자.
일단 자바가 사용하는 메모리의 종류를 알아보고
메모리 관리 방법(Garbage collection 방법)을 파악한 뒤
내 application 에 맞는 최적화 방법을 찾아내는 방법으로 메모리 문제에 접근하는게 순서 인것 같다.

(자바의 garbage collection 관련 링크 : http://java.sun.com/docs/hotspot/gc5.0/gc_tuning_5.html )

1. 자바 VM은 힙을 세개의 영역으로 나누어 사용한다.
  1) New/Young 영역 : 새로 생성된 객체를 저장
  2) Old 영역 : 만들어진지 오래된 객체를 저장
  3) Permanent 영역 : JVM클래스와 메서드 객체를 저장

자바가 사용하는 메모리 구조


여기서 New 영역은 다시  
 a) Eden : 모든 새로 만들어진 객체를 저장
 b) Survivor Space 1, Survivor Space 2 : Old 영역으로 넘어가기 전 객체들이 저장되는 공간
으로 구분된다.

2. Garbage Collector
자바 언어의 중요한 특징중 하나.
전통적인 언어의 경우 메모리를 사용한 뒤에는 일일이 메모리를 수거해 주어야 했다. 
그러나, 자바 언어 에서는 GC기술을 사용하여 개발자로 하여금 메모리 관리에서 자유롭게 했다.

자바의 GC는 New/Young 영역과 Old 영역에 대해서만 GC를 수행한다.  
(Permanent 영역은 code가 올라가는 부분이기 때문에 GC가 필요없다.)

1) Minor GC
New 영역의 GC를 Minor GC라고 부른다. New 영역은 Eden과 Survivor라는 두 영역으로 구분된다.
Eden 영역은 자바 객체가 생성 되자 마자 저장이 되는 곳이다. 
이곳의 객체가 Minor GC가 발생할 때 Survivor 영역으로 이동된다.

Survivor 영역은 Survivor1 과 Survivor2로 나뉘어 지는데, Minor GC가 발생하면 Eden과 Survivor1에 살아있는 객체가 Survivor2로 이동되고, Eden 영역과 Survivor1 영역에 남아있는(죽어있는) 객체는 clear된다.
결과적으로, 현재 살아있는 객체들만 Survivor2에 남아있게 된다.
다음번 Minor GC가 발생되면 같은 원리로, Eden과 Survivor2의 살아있는 객체가 Survivor1으로 이동되고, 두 영역은 Clear 된다.
이와 같은 방법으로 반복되면서 메모리를 수거한다. 이런 방식의 GC알고리즘을 Copy & Scavenge라고 한다. 속도가 빠르며 작은 크기의 메모리를 collecting 하는데 효과적이다.
Minor GC 과정중 오래된 객체는 Old 영역으로 복사된다.  
(Kein:얼마나 지나야 '오래된' 객체인 것인지는 명확히 모르겠네요)


2) Full GC
Old 영역의 GC를 Full GC라 한다. Mark & Compact 알고리즘을 이용하는데, 전체 객체들의 reference를 따라가면서 연결이 끊긴 객체를 marking 한다. 이 작업이 끝나면 사용되지 않는 객체가 모두 mark 되고, 이 객체들을 삭제한다. 
실제로는 삭제가 아니라, mark 된 객체로 생기는 부분을 unmark된, 즉 사용중인 객체로 메꾸는 방법이다.

Full GC는 속도가 매우 느리며, Full GC가 일어나는 도중에 순간적으로 java application이 멈춰버리기 때문에 Full GC가 일어나는 정도와 Full GC에 소요되는 시간은 application의 성능과 안정성에 매우 큰 영향을 미치게 된다.

Full GC 동작 순서


3. Garbage Collection이 중요한 이유
Minor GC는 보통 0.5초 이내에 끝나기 때문에 큰 문제가 되지 않는다. 하지만, Full GC의 경우 보통 수 초가 소요되고, GC동안 Application이 멈추기 때문에 문제가 될 수 있다. 5초 동안 서버가 멈춘다면, 멈춰있는 동안 사용자의 request는 쇄도하게 되고, queue에 저장되었다가 요청이 한꺼번에 들어오게되면 여러 장애를 발생할 수 있게 된다.
원할한 서비스를 위해서 GC를 어떻게 일어나게 하느냐가 시스템의 안정성과 성능에 변수로 작용하게 된다.


4. Garbage Collection 알고리즘들
1) Default Collector
위에 설명한 전통적인 GC방법으로 Minor GC에 Scavenge를, Full GC에 Mark & Compact를 사용하는 방법이다.

2) Parallel GC
JDK 1.3까지는 하나의 thread 에서만 GC가 수행되었다. JDK 1.4 부터 지원되는 parallel gc 는 minor gc를 동시에 여러개의 thread 를 이용해서 수행하는 방법으로 하나의 thread 에서 gc를 수행하는 것보다 빠른 gc를 수행한다.


하지만, parallel gc가 언제나 유익한 것은 아니다. 1 CPU에서는 오히려 parallel gc 가 느리다. multi thread에 대한 지원이나 계산등을 위해서 4CPU의 256M 정도의 메모리를 보유한 시스템에서 유용하게 사용된다.
parallel gc 는 두가지 옵션을 제공하는데, Low-Pause 방식과 Throughput 방식이다. 
solaris 기준으로 Low-pause 방식은 ?XX:+UseParNewGC 옵션을 사용한다. Old GC를 수행할 때 Application 이 멈추는 현상을 최소화 하는데 역점을 두었다. 
Throughput 방식은 ?XX:+UseParallelGC 옵션을 사용하며, Old 영역을 GC할때는 기본 옵션을 사용하며 Minor GC가 발생했을 때 최대한 빨리 수행되도록 throughput에 역점을 둔 방식이다.

3) Concurrent GC
Full GC를 하는 동안 시간이 길고, Application이 순간적으로 멈추는 현상이 발생하는 단점을 보완하기 위해서, Full GC에 의해 Application이 멈추는 현상을 최소화 하기 위한 방법이다.
Full GC에 소요되는 작업을 Application을 멈추고 하는것이 아니라, 일부는 Application을 수행하고, Application이 멈추었을때 최소한의 작업만을 GC에 할당하는 방법으로 Application이 멈추는 시간을 최소화 한다.
Application이 수행중 일 때 (붉은라인) Full GC를 위한 작업을 수행한다. Application이 멈춘 시간동안에는 일부분의 작업을 수행하기 때문에 기존 Default 방법보다 멈추는 시간이 현저하게 줄어든다.
solaris JVM 에서는 -XX:+UseConcMarkSweepGC 옵션을 사용한다.

4) Incremental GC (Train GC)
Incremental GC 또는 Train GC 라고 불리우는 방법은 JDK 1.3 부터 지원된 방법이다. 의도 자체는 Full GC 동안 Application이 멈추는 시간을 최소화 하는데 목적이 있다.
Minor GC가 일어날 때 마다 Old 영역을 조금씩 GC를 해서, Full GC가 발생하는 횟수나 시간을 줄이는 방법이다.
그림에서 보듯, 왼쪽의 Default GC Full GC가 일어난 후에나 Old 영역이 Clear된다그러나오른쪽의 Incremental GC를 보면 Minor GC가 일어난후에, Old 영역이 일부Collect된것을 알 수 있다.
Incremental GC
를 사용하는 방법은 JVM 옵션에 ?Xinc 옵션을 사용하면 된다
.
Incremental GC
는 많은 자원을 소모하고, Minor GC를 자주일으키며Incremental GC를 사용한다고 Full GC가 없어지거나 그 횟수가 획기적으로 줄어드는 것은 아니다오히려 느려지는 경우가 많다.

5. GC 로그 수집 및 분석 방법
이제 적군에 대해 알았으니 나 자신을 파악할 차례다. 
내 Application의 gc 동태를 파악하기 위해 java 실행 옵션에 -verbose:gc 옵션을 주면 gc 로그를 출력할 수 있다. 

garbage collection 로그

로그중 GC 는 Minor GC 이고, Full GC는 Full GC를 나타낸다. 
그 뒤의 숫자는 GC수행 전 heap 메모리 사용량 이다. (New + Old + Perm 영역)
그뒤 -> 이후의 숫자는 GC 수행 후 heap 메모리 사용량을 나타낸다. 
Minor GC 가 수행된 뒤에는 Eden 과 Survivor 영역의 GC가 수행된 것이며, GC이후 heap 사용량은 Old영역의 용량과 유사하다. 괄호 안의 Total Heap Size 는 현재 jvm 이 사용하는 Heap memory의 양이다. 이 크기는 java 실행 옵션의 -Xms -Xmx 옵션으로 설정이 가능한데, 예를 들어 -Xms512 -Xmx1024로 해 놓으면 jvm는 메모리 사용량에 따라서 512~1024m 사이에서 적절하게 메모리 사용량을 늘였다 줄였다 하며 동작한다.
그 다음값은 gc에 소요된 시간이다. 

위의 로그를 보면, Minor GC가 일어날 때 마다 약 20,000Kbytes 정도의 collection이 일어난다. Minor GC는 Eden과 survivor 영역 하나를 gc 하는 것이기 때문에  New 영역을 20,000Kbyte 정도로 생각할 수 있다. 
Full GC 때를 보면 약 44,000Kbytes 에서 1,749Kbytes 로 줄어든 것을 볼 수 있다. Old 영역에 큰 데이터가 많지 않은 경우이다. 
Data를 많이 사용하는 Application의 경우 전체 Heap 이 512M 라 할 때, Full GC 후에도 480M 정도로 유지되는 경우가 있다. 이런 경우에는 실제로 Application이 메모리를 많이 사용하는 경우라고 판단할 수 있기 때문에, 전체 Heap 메모리를 늘려주면 효과적이다. 

gc 로그를 분석하여 OutOfMemory가 발생하는 시점을 추적할 수 있다.
위의 설명처럼 Full GC 이후 Heap 메모리가 부족한 경우 전체 heap 을 조정하면 되고
Minor gc 도중 New 또는 survivor의 영역에 부족하여 에러가 발생하는 경우
new 또는 survivor의 영역을 확장하여 문제를 해결할 수 있다.


그럼 이제
내 어플리케이션의 gc 로그를 통해서 어떤 방법이 좋은 것인지 분석해 봐야 겠다

'개발/활용정보 > Java' 카테고리의 다른 글

Creating a Custom Event  (0) 2011.04.19
eclipse 단축키  (0) 2011.04.13
Java 메모리 설정 MaxPermSize  (0) 2011.04.13
Jboss Clustering  (0) 2011.04.13
Java theory and practice: 메모리 누수와 약한 참조  (0) 2011.04.13
And

Java 메모리 설정 MaxPermSize

|

Permanent generation 영역은 객체나, 함수가 차지하는 영역이고

Xmx로 설정하는 heap 메모리 영역에 포함되지 않는다는것...

 

테스트 해서 나옵 옵션들..

-XX:MinHeapFreeRatio=    힙메모리 최소 비율 인데.. 이비율 이하로 free heap size가 떨어지면 gc 가 일어나는 듯 하다...

 

 

------------------------------------------------------------

 

java.lang.OutOfMemoryError: PermGen space

요즘 들어 부쩍 java.lang.OutOfMemoryErorr로 인해 이클립스가 뻗어버리는 일이 많이 발생했었다. 하지만 Heap Monitor를 보면 200M 조차 사용하지 않는다. 이런 경우, 대부분은 PermGen 영역이 모자란 것이 원인일 수 있다.

{workspace}/.metadata/.log를 확인해보면 PermGen space라고 기록되어 있을 것이다.

Eclipse를 사용할 때는 JVM에 -Xmx 옵션은 대부분은 넣어서 사용하리라 생각한다. 하지만 Java는 메모리 영역을 사실상 두 부분으로 구분하여 사용한다. 일반 Java Heap space와 클래스와 같이 Permenant Generation 대상 데이터를 두기 위한 PermGen space이다.

대부분의 자바 애플리케이션에서는 기본 PermGen Size로 충분하겠지만 이클립스의 경우 클래스가 꽤 많아지면서 모자란 경우가 있는듯 하다. javanese의 경우 Callisto를 깔아놓고 JDT, CDT를 왔다갔다 하면서 사용하다보니 Heap은 별로 쓰지도 않는데 PermGen space가 종종 모자라는 경우가 있다. 아마 Web관련 Tool을 많이 사용하는 분도 같은 현상이 나타날 수 있을 것이다.

PermGen space는 -XX:MaxPermSize 옵션으로 설정할 수 있다.

eclipse -vm /usr/lib/jvm/java-1.5.0-sun/bin/java -vmargs -XX:MaxPermSize=128m -Xms128m -Xmx512m

OutOfMemory 에러가 발생한다면 -Xmx만 늘려주지말고 PermSize도 확인해보라.

{ 3 }

Comments

  1. 우오옷 이런 문제였군요. 요즘 툭 하면 뻗어버려서 아주 짜증이 솟구쳤는데 감사합니다.

  2. 클래스 갯수가 주요원인이기보다는 최근에 framework들이 reflection을 많이 사용해서 더 큰 perm size가 꽤 필요합니다. 이클립스뿐만 아니라, WAS에도 사이즈를 늘려줘야 합니다.

  3. 저 같은 경우는, perm size와 -Xms -Xmx의 크기를 줄여주니 작동하더라구요. 실제 메모리에 따라 적당히 늘리고 줄여야 될거 같습니다.

-----------------------------------------------------------------

MaxPermSize and how it relates to the overall heap

Many people have asked if the MaxPermSize value is a part of the overall -Xmx heap setting or additional to it. There is a GC document on the Sun website which is causing some confusion due to a somewhat vague explanation and an errant diagram. The more I look at this document, the more I think the original author has made a subtle mistake in describing -Xmx as it relates to the PermSize and MaxPermSize.

First, a quick definition of the "permanent generation".

"The permanent generation is used to hold reflective data of the VM itself such as class objects and method objects. These reflective objects are allocated directly into the permanent generation, and it is sized independently from the other generations." [ref]



Yes, PermSize is additional to the -Xmx value set by the user on the JVM options. But MaxPermSize allows for the JVM to be able to grow the PermSize to the amount specified. Initially when the VM is loaded, the MaxPermSize will still be the default value (32mb for -client and 64mb for -server) but will not actually take up that amount until it is needed. On the other hand, if you were to set BOTH PermSize and MaxPermSize to 256mb, you would notice that the overall heap has increased by 256mb additional to the -Xmx setting.

So for example, if you set your -Xmx to 256m and your -MaxPermSize to 256m, you could check with the Solaris 'pmap' command how much memory the resulting process is taking up.

i.e.,

$ uname -a
SunOS devnull 5.8 Generic_108528-27 sun4u sparc
SUNW,UltraSPARC-IIi-cEngine

$ java -version
java version "1.3.1_02"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.1_02-b02)
Java HotSpot(TM) Client VM (build 1.3.1_02-b02, mixed mode)

---------------------------------------------
$ java -Xms256m -Xmx256m -XX:MaxPermSize=256m Hello &
$ pmap 6432
6432: /usr/java1.3.1/bin/../bin/sparc/native_threads/java -Xms256m -Xmx256m

total 288416K
---------------------------------------------
Notice above that the overall heap is not 256m+256m yet? Why? We did not specify PermSize yet, only MaxPermSize.


---------------------------------------------
$ java -Xms256m -Xmx256m -XX:PermSize=256m -XX:MaxPermSize=256m Hello &
$ pmap 6472
6472: /usr/java1.3.1/bin/../bin/sparc/native_threads/java -Xms256m -Xmx256m

total 550544K
---------------------------------------------

Now we see the overall heap grow, -Xmx+PermSize. This shows conclusive proof that PermSize and MaxPermSize are additional to the -Xmx setting.


'개발/활용정보 > Java' 카테고리의 다른 글

Creating a Custom Event  (0) 2011.04.19
eclipse 단축키  (0) 2011.04.13
자바가 사용하는 메모리의 종류와 특징  (0) 2011.04.13
Jboss Clustering  (0) 2011.04.13
Java theory and practice: 메모리 누수와 약한 참조  (0) 2011.04.13
And

Jboss Clustering

|

http://community.jboss.org/wiki/TwoClustersontheSameNetwork


------------------------------------------




Created on: Oct 5, 2005 9:36 AM by Stan Silvert - Last Modified:  Oct 16, 2009 12:32 PM by Brian Stansberry

Note: this document is intended as JBoss Application Server documentation and not as general JGroups documentation. Some of the content may be useful in a general sense, but it is written from the point of view of configuring JBoss AS clusters.

I want to have two JBoss AS clusters on the same network and I don't want them to see each other

 

First, what do we mean by a cluster here? Short answer: we're talking about a JGroups Channel.

 

Longer answer: We're talking about a service, an instance of which is deployed on several JBoss AS instances, where the different instances communicate with each other in order to provide a unified view to clients.

 

Within the AS, there are a number such services -- 3 different JBoss Cache services (used for HttpSession replication, EJB3 SFSB replication and EJB3 entity replication) along with a general purpose clustering service called HAPartition that underlies most other JBossHA services.

 

Each instance of these services creates a JGroups Channel and uses it to communicate with its peers.

 

In AS 5 or EAP 4.3 the JBoss Messaging service opens a further two channels.

 

It is critical that these channels only communicate with their intended peers; not with the channels used by other services and not with channels for the same service opened on machines not meant to be part of the group.

 

Isolating JGroups Channels

 

A JGroups Channel is defined by its group name, multicast address, and multicast port.

 

To isolate JGroups channels for different services on the same set of AS instances from each other, you MUSTuse a unique group name for each and either 1) use a different multicast port for each or 2) have the channels share a JGroups shared transport (available beginning with AS 5.0.0) .


For example, say we have a production cluster of 3 machines, each of which has an HAPartition deployed along with a JBoss Cache used for web session clustering.  The HAPartition channels should not communicate with the JBoss Cache channels.  Those channels should use a different group name and should either use a different multicast port or share a JGroups transport. They can use the same multicast address, although they don't need to. The default configs that ship in AS 4.0.4 and later will use different group names and multicast ports for the standard AS clustering services, while in AS 5.0.0 and later they will use a shared transport. So isolating the channels for different services requires no effort.

 

To isolate JGroups channels for the same service from other instances of the service on the network, youMUST change ALL three values on 4.x and earlier. Each channel must have its own group name, multicast address, and multicast port. Due to improvements in JGroups, in AS 5.x and later it is sufficient to change just the group name and multicast address; changing multicast ports should not be necessary in AS 5.

 

For example, say we have a production cluster of 3 machines, each of which has an HAPartition deployed.  On the same network there is also a QA cluster of 3 machines, which also has an HAPartition deployed. The HAPartition group name, multicast address, and multicast port (in AS 4.x and earlier) for the production machines must be different from those used on the QA machines.

 

Changing the Group Name

 

The group name for a JGroups channel is configured via the service that starts the channel.  Unfortunately, different services use different attribute names for configuring this. For HAPartition and related services configured in the deploy/cluster-service.xml file (deploy/cluster/hapartition-jboss-beans.xml in AS 5), this is configured via a PartitionName attribute.  For JBoss Cache services, the name of the attribute isClusterName.

 

Starting with JBoss AS 4.0.2, you can easily change the cluster-service.xml PartitionName by specifying it as a system property at startup.

 

./run.sh -c all -Djboss.partition.name=MyPartition

 

Starting with JBoss AS 4.0.3, you can use a command line switch instead of setting a system property:

 

./run.sh -c all -g MyPartition

 

or

 

./run.sh -c all --partition MyPartition

 

Behind the scenes, both of these set the jboss.partition.name system property.

 

See Changing a Cluster PartitionName for more on this.

 

Starting with JBoss AS 4.0.4, the value passed at startup via -g or --partition or -Djboss.partition.nameis used as part of the ClusterName used by JBoss Cache for the web session replication cache.  For earlier releases, the tc5-cluster-service.xml file can easily be modified to provide this behavior:

 

<attribute name="ClusterName">Tomcat-${jboss.partition.name:Cluster}</attribute>

 

Changing the Multicast Address

 

Starting with JBoss AS 4.0.3, the jboss.partition.udpGroup system property can be used to control the multicast address used by the JGroups channel opened by all standard AS services. A command line option to set this property was also added:

 

./run.sh -c all -u 233.3.4.5

 

or

 

./run.sh -c all --udp 233.3.4.5

 

Behind the scenes, both of these set the jboss.partition.udpGroup system property.

 

Changing the Multicast Port

 

(Note: improvements in JGroups mean changing multicast ports should not be necessary in AS 5.)

 

Changing the multicast port involves changing the protocol stack configuration for the various JGroups channels. The configuration for any JGroups channel that uses the UDP or MPING protocols should be changed. (MPING is not used in any of the standard protocol stack configurations in AS 4.x or 3.x; it is used in AS 5).  With both UDP and MPING, it is the mcast_port attribute that needs to be changed:

 

.... <config>    <UDP mcast_addr="${jboss.partition.udpGroup:228.1.2.3}"         mcast_port="45566"         ip_ttl="8" ip_mcast="true"         mcast_send_buf_size="800000" mcast_recv_buf_size="150000"         ucast_send_buf_size="800000" ucast_recv_buf_size="150000"         loopback="false"/>     ....

 

MPING is used in a TCP-based stack:

 

.... <config>    <TCP start_port="7600"         ....    />    <MPING timeout="3000"           num_initial_members="3"           mcast_addr="${jboss.partition.udpGroup:230.11.11.11}"           mcast_port="45700"           ip_ttl="${jgroups.udp.ip_ttl:2}"/>   ....

 

Where the JGroups channel configurations are located varies between AS versions:

 

JBoss AS 5

 

Improvements in JGroups mean changing multicast ports should not be necessary in AS 5. However, the following information on how to change multicast ports in AS 5 is provided here as general documentation.

 

In AS 5, all JGroups protocol stack configuration is isolated in a single file: /deploy/cluster/jgroups-channelfactory.sar/META-INF/jgroups-channelfactory-stacks.xml. This file contains a number of protocol stack configurations used by the AS's JGroups ChannelFactory. Not all stacks described in that file are actually used; by default in AS 5.0.0 only the udpjbm-control and jbm-data stacks are used. (Services like the clustered HttpSession cache that use JGroups can be configured to use other stacks in the file besides those three default ones.)  There is no need to change the ports for stacks that you are not using.

 

It shouldn't be necessary to actually modify this file to control the ports used; this is because each port configuration uses system property substitution syntax to allow you to set the property from the command line using -D. For example, the UDP protocol mcast_port for the udp and jbm-control stacks is configured via thejboss.jgroups.udp.mcast_port system property:

mcast_port="${jboss.jgroups.udp.mcast_port:45688}"

 

while the MPING protocol mcast_port in the jbm-data stack uses:

mcast_port="${jboss.messaging.datachanneludpport:45710}"

 

The jboss.jgroups.udp.mcast_port property is a bit of a special case; it can be set from the command line using the shorthand -m command line option, e.g.:

 

./run.sh -c all -m 54321 -Djboss.messaging.datachanneludpport=12345
4.2.x and Earlier

 

In AS 4.2.x and earlier, JGroups channel configurations are embedded in the configurations for the services that use the channel.

 

For the HAPartition service, the JGroups channel configuration is found in deploy/cluster-service.xml.

 

Fort HttpSession replication, a JGroups channel configuration is found in deploy/tc5-cluster-service.xml. (In 4.0.4 and 4.0.5, this is instead located in deploy/tc5-cluster.sar/META-INF/jboss-service.xml. In the 4.2 series it is located in deploy/jboss-web-cluster.sar/META-INF/jboss-service.xml).

 

For EJB3 clustering, JGroups channel configurations are found in the deploy/ejb3-clustered-sfsbcache-service.xml and deploy/ejb3-entity-cache-service.xml files.

 

For clustered JBoss Messaging in EAP 4.3, JGroups channel configurations are found in the deploy/jboss-messaging.sar/clustered-hsqldb-persistence-service.xml file.

Configuration via System Property in 4.x

 

In the AS 4.2 and EAP 4.x releases, the mcast_port configurations for the services noted above can all be controlled via a system property by using -D when starting JBoss.The properties and the services they configure are as follows:

 

System Property
Service
jboss.hapartition.mcast_port HAPartition (cluster-service.xml)
jboss.webpartition.mcast_port HttpSession clustering (jboss-web-cluster.sar)
jboss.ejb3entitypartition.mcast_port EJB3 Entity Clustered Second Level Cache (ejb3-entity-cache-service.xml)
jboss.ejb3sfsbpartition.mcast_port EJB3 SFSB clustering (ejb3-clustered-sfsbcache-service.xml)
jboss.messaging.datachanneludpport JBoss Messaging Data Channel (jboss-messaging.sar)
jboss.messaging.controlchanneludpport JBoss Messaging Control Channel (jboss-messaging.sar)

 

For releases prior to 4.2, you can also define the multicast ports via system properties but you need to modify the corresponding xml file to use system property substitution. For this example, we have chosen cluster-service.xml:

 

         ....          <Config>             <UDP mcast_addr="${jboss.partition.udpGroup:228.1.2.3}"                mcast_port="${jboss.hapartition.mcast_port:45566}"                ip_ttl="8" ip_mcast="true"                mcast_send_buf_size="800000" mcast_recv_buf_size="150000"                ucast_send_buf_size="800000" ucast_recv_buf_size="150000"                loopback="false"></UDP>          ....

 

You will have to do a similar thing for any clustered service, such as HTTP session replication, EJB3 entity bean cache...etc. Use a different system property for each. Please, do not use the same port for all services due to the problems explained in the promiscuous traffic wiki.

 

Isolating Channels in JBoss AS 5

 

An excellent piece of news is that isolating clusters in AS 5.0.1 should no longer require changing multicast ports. Actually, simply starting each cluster with a different value passed to -u (as described above) should be sufficient. Even setting different partition names via -g isn't absolutely required (altough it's simple to do and still recommended.) As the above process of changing the multicast ports is by far the most cumbersome aspect of cluster isolation this is good news indeed.

 

In JGroups 2.6.5 and 2.6.6 fixes were made to the UDP and MPING protocols that resolve the issue that lead to the need to change multicast ports.

 

And an added bit of good news is a simple tweak to correct a mistake in the default AS 5.0.0.GA configuration will allow you to skip changing multicast port values in AS 5.0.0.GA as well.  The correction to AS 5.0.0.GA involves a simple edit to the $JBOSS_HOME/server/all/deploy/cluster/jgroups-channelfactory.sar/META-INF/jgroups-channelfactory-stacks.xml file to edit the jbm-data stack configuration:

 

<stack name="jbm-data"        description="Stack optimized for the JBoss Messaging Data Channel">   <config>      <TCP singleton_name="jbm-data"           start_port="${jboss.messaging.datachanneltcpport:7900}"            .....            oob_thread_pool.queue_max_size="100"            oob_thread_pool.rejection_policy="run"/>      <MPING timeout=5000             mcast_addr=${jboss.messaging.datachanneludpaddress,jboss.partition.udpGroup:228.6.6.6}             .....

 

Change the MPING.mcast_addr config to:

 

mcast_addr=${jboss.partition.udpGroup:228.6.6.6}

 

Basically, the JGroups XML parser doesn't handle the more complex system property substitution syntax, so reduce it to the simpler syntax. Eliminate the first system property, not the second.

 

There are several other places in the jgroups-channelfactory-stacks.xml file that have the same problem, although this is the only one that causes problems with a default JBoss AS 5.0.0.GA. But, fixing making the same fix to the others is recommended as well.

 

This problem will be eliminated in the first release after AS 5.0.0.GA.

 

Other Notes

Using ip_ttl to isolate clusters

 

Another tip: if your clusters are on different subnets, configure the switches between your VLANs/subnets to drop IP multicast packets. If that is not an option, you can achieve much the same thing by reducing the UDP (and MPING) protocol's ip_ttl to a value where the multicast doesn't leave the subnet, e.g. 2.

 

Beginning with JBoss AS 4.0.5, if you set the jgroups.mcast.ip_ttl system property, that value will be picked up by the standard JGroups channel configurations.

 

This is sometimes a useful technique for developer workstations as well; i.e. set ip_ttl to 0 or 1 to prevent developers' workstations from clustering with each other. This doesn't always work though; it depends on how the specific network hardware deals with the TTL.  Another approach for isolating developer workstations is to start JBoss with -b localhost.

Why isn't it sufficient to change the group name?

 

If channels with different group names share the same multicast address and port, the lower level JGroups protocols in each channel will see, process and eventually discard messages intended for the other group.  This will at a minimum hurt performance and can lead to anomalous behavior.

 

Why isn't it sufficient to change the group name and multicast address? Why do I need to change the multicast port if I change the address?

 

First off, beginning with JGroups 2.6.6 it probably isn't necessary. But for those using earlier JGroups releases, or those interested in details...

 

There is an issue on several operating systems whereby packets addressed to a particular multicast port are delivered to all listeners on that port, regardless of the multicast address they are listening on.  If you know your OS doesn't have this issue, only changing the multicast address is sufficient.  See PromiscuousTrafficfor more on this, including a test you can run to see if your OS exhibits this behavior.

 

In JGroups 2.6.5 and 2.6.6 there are fixes to the JGroups UDP and MPING protocols such that on Linux systems multicast sockets are created in such a way that the promiscuous traffic problem doesn't occur. AnInetAddress indicating the multicast address is passed to the java.net.MulticastSocket constructor; that avoids the problem. However, constructing a MulticastSocket that way on other systems will lead to failures, so before doing this JGroups checks the os.name system property to confirm that Linux is the OS.

 

EJB clients

 

If you have EJB clients, see this forum post for info on restricting EJB clients to a particular partition.

 

The jboss.partition.udpGroup and jboss.partition.udpPort System Properties

 

There are two special system properties,  and , that JGroups will programatically check as part of the process of setting up a channel.  If the former is found, the value of the property will be used to set the channel's multicast address, overriding any value set in the configuration file.  If the latter is found the value of the property will be used to set the channel's multicast port, again overriding any value set in the configuration file.

 

Do not set both of these properties!!! If you do, all the channels on the server will use the same address/port combination and will thus see each others' traffic.  We recommend setting , which is automatically done if you start JBoss AS using the  switch.  If you do that, don't set .

And
prev | 1 | ··· | 80 | 81 | 82 | 83 | 84 | next