생성 날짜로 보니 어제쯤에 4.1 SNAPSHOT이 release 된 거 같다. 라이브러리 저장소가기
요즘 메시지 큐를 프로젝트에 적용하고 있는데 며칠동안 삽질한 결과, 만족할만한 결과가 나오길래 포스팅해도 될꺼 같다는 판단하에 남겨놓는다.

● 개발환경
  - H/W : Dell insprion 6400
  - OS : Windows XP
  - Platform : JDK 1.5
  - IDE : Ecilpse 3.1 + WDT

● 사용라이브러리
- 꽤나 많다. 대부분 activeMQ 라이브러리 안에 포함되어있다. 포함되지 않은 것들만 소개한다.
- activeMQ 4.1 SNAPSHOT
- jakarta commons
  - net 1.4.1
  - collection 3.1
  - dbcp 1.2.1, pool .12 (DB 사용시에 필요^^)
- xercesImpl (XML 파서)
- geronimo : Geronimo 시작하기(activeMQ 내부적으로 사용되는 라이브러리기 때문에 굳이 읽을 필요는 없다)

● 참고문서
- 라이브러리 안에 간단한 예제를 보면 이해하기 쉽다.
  -  examples이라는 폴더 안에 있다.

● 선수지식
- AciveMQ 홈페이지 가서 최소한 JMS의 내용이라도 이해하고 있어야 쉽다.

● 구조
- example과 다른 것은 없지만, 약간 변경했다.

역시 이클립스다.


● 설명
- 어설프지만 개념은 요렇다! 자세한 건 AciveMQ 홈페이지에서...
- kr.pe.dada.main.ActiveMQSample.java : 다운로드
main 클래스. 먼저 Broker(Queue)를 생성한 다음, Consumer를 생성하고, Producer를 이용해서 5개의 메시지를 Broker에게 넘긴다. Thread.sleep이 사용된 이유는 각각 라이브러리를 로딩하는 데 시간이 걸리기 때문이다.

- kr.pe.dada.broker.ActiveMQBroker.java : 다운로드
지정된 xml 설정파일을 xbean 이용해서 읽는다. 굳이 xml 설정파일을 읽지않고 쓰려면 example의 예제처럼 BrokerService를 생성하고 하나하나 setter 메소드로 설정해주면 된다 :)

- kr.pe.dada.broker.ActiveMQProducer.java : 다운로드
Message를 보낼 목적지(Destination)을 설정하고, 현재 시간을 Message에 실어 Broker로 보낸다. (send 메소드) session 생성시에 유의할 점이 있는데, 나중에 간단히 설명하도록 하겠다.

- kr.pe.dada.broker.ActiveMQConsumer.java : 다운로드
Producer가 Broker에게 던지면, Broker가 다시 Consumer에게 Event(MessageListner를 통해서..)를 알린다. 역시 Producer와 동일하게 Destination을 정하고(같은 Destination을 사용해야한다.), Listner 2개를 등록한다.

- activemq.xml : 다운로드
Broker에 대한 전반적인 설정 xml. 내용이 많으니 Xml Configuration을 참고하자. 내가 만든 예제는 JDBC를 이용하여 Queue를 DB로 이용한 예제다. DB말고 메모리, 파일로도 사용가능하니 꼭 읽어봐야한다^^

● 포럼
- nabble

● 삽질기
  1. Ack 문제
- 버그인 듯한데...  Producer와 Consumer에서 session 생성시 다음과 같이 되어있다.
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
여러가지 장애처리를 염두해두느라, Producer와 Broker를 돌리고 있는 도중 Consumer를 죽여봤다. 즉, Message가 계속 Queue에 쌓이는 상태에서 Consumer를 따로 실행하면, 일단 Message를 잘 받는다. 하지만, 다시 죽이고 실행하면 이전의 Message를 또 받는 것이다. (dequeue가 제대로 되질 않는다. nabble 포럼에서는 AUTO_ACKNOWLEDGE의 버그일 꺼라 추측하고 있다. 자동으로 ACK을 날려주는 옵션인 듯한데, 자동으로 ACK을 날려주지 않는다!)

포럼에서는 여러가지 해결책을 제시하고 있는데, 나의 경우는 다음과 같이 처리했다. Consumer와 Producer 동일하게 처리한다.
session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);

그리고 Message를 주고 받을 때, 다음을 호출한다. Consumer에서는 OnMessage 메소드에서 Producer에서는 Send 메소드 호출후, acknowledge를 하면, 양쪽으로 ACK을 날림으로써 Message주고 받은 것을 알려준다.
message.acknowledge();

  2. mysql InnoDB engine 문제
- DB에 Table 생성시 에러가 발생
Table 'messagequeue.ACTIVEMQ_ACKS' doesn't exist

innoDB를 사용함으로써, PK의 데이터 사이즈(bytes)가 초과되어 발생하는 문제다. 아래 페이지를 참고해서 다음과 같이 처리한다. Unable to create ACTIVEMQ_ACK table
<persistenceadapter>
<journaledjdbc usejournal="false" journallogfiles="5" datadirectory="../activemq-data" datasource="#ds">
<statements>
<statements stringiddatatype="VARCHAR(128)" msgiddatatype="VARCHAR(128)" containernamedatatype="VARCHAR(128)">
</statements>
</statements></journaledjdbc>
Posted by xHuro
,