59
JMS Technical Training DaeJung Kim Senior Consultant BEA Systems Korea. October, 2004

JMS Technical Training - cfile23.uf.tistory.com

  • Upload
    others

  • View
    2

  • Download
    0

Embed Size (px)

Citation preview

Page 1: JMS Technical Training - cfile23.uf.tistory.com

JMS Technical Training

DaeJung KimSenior Consultant

BEA Systems Korea.October, 2004

Page 2: JMS Technical Training - cfile23.uf.tistory.com

2

목차

1. 메시징미들웨어

2. 기본 JMS API 개념

3. JMS 1.0 API 개요

Page 3: JMS Technical Training - cfile23.uf.tistory.com

3

분산 미들웨어 종류

• 리모트프로시저호출 (RPC)– 동기– 타겟시스템상의 EJBBeans, Corba Service등의메쏘드/프로시저를직접호출

– 클라이언트와서버가밀접하게 coupled 되어있음.

• 메시지기반미들웨어 (MOM) – 비동기 (and synchronous)– 프로시저를호출하기위해메시지를타겟시스템에전달

– 클라이언트와서버가분리된형태

Needs Work

Does Work

Needs Work

Does Work

Queue

Producer

Consumer

Page 4: JMS Technical Training - cfile23.uf.tistory.com

4

메시징이란?

• 메시징은프로그램또는소프트웨어컴포넌트가서로통신하기위한메커니즘이다.– 애플리케이션간 비동기통신– 인터페이스와구현의분리– 클라이언트, 메시징서버, 메시지로구성.

Page 5: JMS Technical Training - cfile23.uf.tistory.com

5

Message BrokerMessaging은 loosely-couple 방법으로분산커뮤니케이션을가능하게한다.

Service orchestration

Custom applications

Distributed query engine

Adapters

.NETapps

Java apps

Web Svcs MQ gateway

Mainframe & legacy

apps

JMS

Routing & Transformation

Message Bus(Transport,Protocols,, Routing, Transformation )

SOAP/HTTP,JMS

BPEL4WS, PD4JXQuery

J2EE,Struts

XQuery,JDBC

JCA

SOAP,WSDL, UDDI

Page 6: JMS Technical Training - cfile23.uf.tistory.com

6

메시징 사용의 장점

• 클라이언트응답시간향상– 응답을기다리지않으므로애플리케이션은처리를계속할수있다.

• 확장성향상– 소비자(Consumer)는시스템여유가있을때/ 메시지처리가가능할때응답할수있다.

• 가용성향상– 처리시간이오래걸리는작업은여러개의트랜잭션으로나우어처리할수있다.

• 유지관리향상– 서버구현이변경되었을때거의변경없이적용가능하다.

• 신뢰성향상– 선택적으로메시지를영구저장소(persistent store)에저장함으로서언제라도메시지전달을보장할수있다.

– 클라이언트가연결되어있지않을경우일단메시지를저장하고클라이언트가접속되면메시지를전달할수있다.

Page 7: JMS Technical Training - cfile23.uf.tistory.com

7

MOM 유저 케이스

• 워크플로우 / 프로세스• 네트웍관리• 통신서비스• 고객관리• 공급체인관리• 기업의산재한통합

Page 8: JMS Technical Training - cfile23.uf.tistory.com

8

목차

1. 메시징미들웨어

2. 기본 JMS API 개념

3. JMS 1.0 API 개요

Page 9: JMS Technical Training - cfile23.uf.tistory.com

9

What is Java Messaging Service?

• JMS는자바/J2EE 애플리케이션을위한자바표준엔터프라이즈메시징서비스이다. – 표준 API , 벤더중립 API ( javax.jms )– 분산환경에서애플리케이션컴포넌트들간에메시지를라우팅하는지능적인교환기역할담당

MOMSystem

ApplicationA

ApplicationB

Message Message

Page 10: JMS Technical Training - cfile23.uf.tistory.com

10

언제 JMS API를 사용할수 있는가?

• 컴포넌트가다른컴포넌트의인터페이스에대한의존성을배제하고자할때, 그래서컴포넌트가쉽게대치(replace) 될수있도록할때..

• 모든컴포넌트가 up이거나동시에수행되지않아도애플리케이션을수행하고자할때.. 애플리케이션이 .. 모든컴포넌트가 up 이고 running 동시에 running 이아니어도될때..

• 애플리케이션비즈니스모델이 다른 애플리케이션에정보를보내고즉시응답을받지않고다른작업을수행한후메시지를받아처리하고자할때..

Page 11: JMS Technical Training - cfile23.uf.tistory.com

11

JMS는 J2EE와 적합한가?

• JMS API는 J2EE 1.3 플랫폼에서다음과같은사항을가능하게한다.– 애플리케이션클라이언트 , EJB 컴포넌트, 웹서비스컴포넌트는

JMS 메시지를동기적(Synchronously)으로보내고받을수있다.– 추가적으로 , 애플리케이션클라이언트는비동기(Asynchronously)적으로 JMS 메시지를받을수있다.

– ( Applet은 JMS API지원를지원하지않는다.)– MDB는메시지의비동기적처리를가능하게한다.

• JMS Provider는추가적으로구현될수있다. – 송. 수신메시지는트랜잭션에참여할수있습니다.

• J2EE 1.3 , 1.2는 JMS 1.0 , J2EE 1.4는 JMS 1.1 스펙구현

Page 12: JMS Technical Training - cfile23.uf.tistory.com

12

JMS API 아키텍처

JMSProvider

JMSClients

AdministrationTool

CF D

JMSClients

JMSClients

JMSClients

Connection

Message

Lookup

Bind

*CF : ConnectionFactory* D : Destination

Page 13: JMS Technical Training - cfile23.uf.tistory.com

13

메시징 도메인 타입

• JMS 도메인– point-to-point– publish/subscribe

Sender Receiver

Publisher

Subscriber 1

Subscriber 1

Subscriber 1

Page 14: JMS Technical Training - cfile23.uf.tistory.com

Point-to-Point (PTP) 메시징 도메인

• 각메시지를단하나의메시지소비자(consumer)에게전송한다.• 메시지수신자(receiver)는 Queue에메시지가존재할경우언제든지 메시지를가져올수있다. – 메시지수신시시간의종속성이없음.

QueueSender AReceiver BSends

Consumes

AcknowledgesSender B

Receiver A

14

Page 15: JMS Technical Training - cfile23.uf.tistory.com

15

Publish/Subscribe (Pub/Sub) 메시징 도메인

• 각메시지는하나이상의메시지소비자(consumer)에의해처리된다.

• 영구적구독(durable subscription)이설정되어있지않을경우 , 메시지수신은 시간에종속적이다.

PublisherA

Subscriber B

Publishes

SubscribesDelivers

TopicSubscribes

Delivers

Subscriber A

PublisherB

Page 16: JMS Technical Training - cfile23.uf.tistory.com

16

영구적 구독자(Durable Subscribers)

• 경우에따라서클라이언트가재접속되었을때 , 토픽메시지를재전송받아야만하는경우가있다. 이때durable topic subscriptions을사용한다.

• JMS 토픽에만해당된다.• Publisher는반드시식별자를제공해야한다.

– 클라이언트가 JMS Provider에재접속했을때 ,JMS가처리안된메시지들을식별할수있도록하기위해서이다.

• JMS provider는 durable subscriber에대하여메시지미수신시메시지를저장한다.

Page 17: JMS Technical Training - cfile23.uf.tistory.com

17

목차

1. 메시징미들웨어

2. 기본 JMS API 개념

3. JMS 1.0 API 개요

Page 18: JMS Technical Training - cfile23.uf.tistory.com

18

JMS Component Overview

Base Interface Point-to-Point Publish-Subscribe NotesDestination javax.jms.Destination javax.jms.Queue javax.jms.Topic Looked up in JNDI

Producer javax.jms.MessageProducer javax.jms.QueueSender javax.jms.TopicPublisherCan specify message expiration, delivery mode, and priority

Consumer javax.jms.MessageConsumer javax.jms.QueueReceiver javax.jms.TopicSubscriber

Asynchronous consumers implement javax.jms.MessageListener interface. Synchronous consumers w ill block until a message arrives. Consumers can f ilter messages using SQL SELECT and WHERE statements.

Message javax.jms.Message

javax.jms.BytesMessage, javax.jms.MapMessage,

javax.jms.ObjectMessage, javax.jms.StreamMessage,

javax.jms.TextMessage

javax.jms.BytesMessage, javax.jms.MapMessage,

javax.jms.ObjectMessage, javax.jms.StreamMessage,

javax.jms.TextMessage

P-to-P: A message is delivered to only 1 queue. Remains in queue (PERSISTENT or NON-PERSISTENT) until receiver is available. Pub-Sub: A message is delivered to many consumers.

ConnectionFactory javax.jms.ConnectionFactory javax.jms.QueueConnectionFactory javax.jms.TopicConnectionFactory Looked up in JNDI, creates Connections

Connection javax.jms.Connection javax.jms.QueueConnection javax.jms.TopicConnectionCreates Sessions. Pub-Sub: Needs ClientID (ie. Username) to uniquely identify subscriber.

Session javax.jms.Session javax.jms.QueueSession javax.jms.TopicSession Creates Producers, Consumers, and Messages

Page 19: JMS Technical Training - cfile23.uf.tistory.com

19

JMS API Programming Model

Page 20: JMS Technical Training - cfile23.uf.tistory.com

20

What is a Message?

• A message is composed of:– 10 header fields– optional header fields called

properties– a body

Message Headers

Message Properties

Message Body

Page 21: JMS Technical Training - cfile23.uf.tistory.com

21

Message Headers

Page 22: JMS Technical Training - cfile23.uf.tistory.com

22

JMS 헤드 필드들

이름 지정 설명

JMSDestination Send() 메시지가보내어질목적지이름. Send() 메쏘드에서자동지정

JMSDeliveryMode Send() 메시지가지속성(persistent)인지비지속성인지를설정함.

JMSExpiration Send() 메시지가만료되어시스템에서지워지는시점을정의함.이필드는메시지가보내질때설정되는경과시간(time-to-live)에좌우된다. TTL이 0 일경우만료되지않음을의미

JMSPriority Send() 메시지우선순위(0-9) 설정. 높을수록우선순위. 기본값은 4

JMSMessageID Send() 메시지의식별값을문자열로가지고있음. 식별값은 ID: 로시작하고일반적으로 JMS Provider에의해자동부여됨.

JMSTimestamp Send() 전송될메시지가 JMS Provider로들어온시간을 long 값으로가지고있음.

JMSCorrelationID Client 메시지를보내기전에 client에서절정되는임의의문자열이다. 이것은

JMSReplyTo Client Consumer가응답을보낼때사용할수있는 JMS 목적지이다.

JMSType Client 메시지타입설정. 클라이언트에서지정한임의의타입을가진메시지를구분하는데사용.

JMSRedelivered JMS Provider

수신자가메시지를확인하지못했거나세션이복구되어 JMS 메시지를재전송할때.

Page 23: JMS Technical Training - cfile23.uf.tistory.com

23

Queue에 저장된 메시지 보기

public void displayQueue(Message m) throws JMSException {System.out.println("Message ID " + m.getJMSMessageID() +

" delivered " + new Date(m.getJMSTimestamp()) +" to " + m.getJMSDestination());

System.out.print("\tExpires ");

if (m.getJMSExpiration() > 0) {System.out.println( new Date( m.getJMSExpiration()));

} else {System.out.println("never");

}

System.out.println("\tPriority " + m.getJMSPriority());System.out.println("\tMode " + (

m.getJMSDeliveryMode() == DeliveryMode.PERSISTENT ?"PERSISTENT" : "NON_PERSISTENT"));

System.out.println("\tCorrelation ID " + m.getJMSCorrelationID());System.out.println("\tReply to " + m.getJMSReplyTo());System.out.println("\tMessage type " + m.getJMSType());

if (m instanceof TextMessage) {System.out.println("\tTextMessage \"" + ((TextMessage)m).getText() + "\"");

}

}// 속성값설정시..setStringProperty (“Reply“ ,”toxxx” );

Page 24: JMS Technical Training - cfile23.uf.tistory.com

24

메시지 타입

• Stream– Stream of Java primitive values– 객체는반드시쓰여진순서대로읽혀져야한다.

• Map– 이름과값의쌍

– 각각의이름이맵에서고유한값을가짐.– 엔트리의순서는없음.

• Text– String 인스턴스– XML 문서지원

• WebLogic JMS 에서이타입을확장하여 XMLMessage 타입을만듬. • Object

– 직렬화가가능한객체

• Bytes– Raw 바이트스트림– Raw 메시지형식을사용하는클라이언트에서이메시지타입사용..

Page 25: JMS Technical Training - cfile23.uf.tistory.com

25

What is a Destination?

• A destination is an administered object– Producers produce messages to destinations, consumers

consume messages from destinations– Support concurrent use– To write portal code, it should be looked up via JNDI.

• Topics– Publish/Subscribe message model– Can exist as a hierarchy

• Queues– Point-to-Point message model

Page 26: JMS Technical Training - cfile23.uf.tistory.com

26

What is a Producer?

• Producer is the sender of messages– PTP: QueueSender, created by QueueSession

QueueSender queueSender = queueSession.createSender(queue)

– Pub/Sub: TopicPublisher, created by TopicSessionTopicPublisher topicPublisher = topicSession.createPublisher(topic)

• Can specify the following default for a message:– Delivery mode

• PERSISTENT (Delivered once and only once)• NON_PERSISTENT (Delivered at most once)

– 우선순위• 0-9 levels

– Time-to-live (expiration) • 0 means never expires

Page 27: JMS Technical Training - cfile23.uf.tistory.com

27

What is a Consumer?• A consumer is the receiver of messages

– PTP: QueueReceiver, created by QueueSessionQueueReceiver queuereceiver = queueSession.createReceiver(queue)

– Pub/sub: TopicSubscriber, created by TopicSessionTopicSubscriber topicSubscriber =

topicSession.createSubscriber(topic)

TopicSubscriber durableTopicSubscriber = topicSession.createDurableSubscriber(topic)

• Can filter messages using a subset of SQL92• Synchronous consume

– Consumer will block using method: receive( Message message )

• Asynchronous consume– Register as a MessageListener– Consumer notified with callback method:

MessageListener.onMessage(Message message)when a message arrives

Page 28: JMS Technical Training - cfile23.uf.tistory.com

28

What is a Connection?

• A connection represents a physical connection to the JMS provider.

• Created by ConnectionFactory• Creates Session objects• Must be started to consume messages

– Note: Does not need to be started to producemessages!

• Support concurrent use

Page 29: JMS Technical Training - cfile23.uf.tistory.com

29

What is a Session?

• Session은 producer 와 consumer간대화상태(conversional state)를유지하며실제메시지의교환을관리한다.

• Producer, Consumer 및메시지를생성한다. • Session은싱글쓰레드모델이므로 동시사용을지원하지않는다.

• Connection에다음과같은기능을추가할수있다.– 생성되는(produced) 메시지와소비되는(consumed) 메시지의순서정의

– 비동기 consumer의리스너메쏘드 호출

– 메시지전달보장(Guaranteed Delivery)

Page 30: JMS Technical Training - cfile23.uf.tistory.com

30

Guaranteed Messaging - Two Types of Sessions

• 메시지확인(acknowledgement) 세션QueueSession ackQueueSession =

queueConnection.createQueueSession(false, acknowledgement)

• 트랜잭션세션QueueSession transactedQueueSession =

queueConnection.createQueueSession(true, 0)

트랜잭션세션에서는acknowledgement 모드가무시됨. “0”으로설정하는것을권장함.

Page 31: JMS Technical Training - cfile23.uf.tistory.com

31

비 트랜잭션 모드에 대한 메시지 확인

• 세션에대한 3가지종류의확인(acknowledgement)옵션들– AUTO_ACKNOWLEDGE

• 동기식에서는 consumer의 receive() 메쏘드호출이예외상황없이끝날때메시지가자동으로확인된다. 비동기식에서메시지는 onMessage 콜백함수가반환될때확인된다.

• 메시지를처리하면 JMS Provider가자동으로메시지를확인함.• Provider 오류후최대한개의재전송메시지를보장함.

– DUPS_OK_ACKNOWLEDGE• 늦은(Lazy) 메시지확인. AUTO_* 보다효율적인데그이유는모든메시지가확인되는것은아니기때문이다. 그러나시스템이나네트웍장애시메시지가중복전송될수도있다.

– CLIENT_ACKNOWLEDGE• 클라이언트에서 javax.jms.Message.acknowledge() 메쏘드를사용하여메시지를확인할때사용됨. 클라이언트는모든메시지를일일이확인할필요가없고대신acknowledge()를호출하면현재까지발생한메시지를일괄적으로확인한다.

– NO_ACKNOWLEDGE• 웹로직에서추가한확인모드로메시지전송과정이없다. JMS는메시지를소비자에게전송한후바로버퍼에서제거한다.

– MULTICAST_NO_ACKNOWLEDG• 웹로직에서추가한확인모드. JMS 메시지를 IP 멀티캐스트(multicast)를통해 topic

subscriber에게전달함.

Page 32: JMS Technical Training - cfile23.uf.tistory.com

32

적당한 확인 모드는 무엇인가?

QueueSession qsessionSend = qcon.createQueueSession(false, /* 비트랜잭션세션 */ Session.AUTO_ACKNOWLEDGE);

QueueSession qsessionReceive = qcon.createQueueSession(false,Session.AUTO_ACKNOWLEDGE);

Page 33: JMS Technical Training - cfile23.uf.tistory.com

33

What is a ConnectionFactory?

• A connection factory in an administered JMS object.

• Used to create JMS connections.• It is looked up in JNDI. For example:

InitialContext ctx = new InitialContext(connectionProperties);

QueueConnectionFactory queueConnectionFactory = (QueueConnectionFactory) ctx.lookup(“MyConnectionFactory”);

Page 34: JMS Technical Training - cfile23.uf.tistory.com

34

JMS Exception Handling

• Root class: JMSException

Page 35: JMS Technical Training - cfile23.uf.tistory.com

35

Point-to-Point JMS 예제 코드

1. JNDI에서 ConnectionFactory lookup2. ConnectionFactory를이용하여 Connection객체생성

3. Connection을이용하여 Session 객체생성4. JNDI에서 Queue 또는 Topic lookup5. Session 과 Queue 또는 Topic 을이용하여

MessageProducer 또는 MessageConsumer 생성

6. Connection 시작

Page 36: JMS Technical Training - cfile23.uf.tistory.com

36

Point-to-Point JMS Example Code

Preparing to send/receive a message to/from a Queue:

public final static String JNDI_FACTORY= "weblogic.jndi.WLInitialContextFactory";public final static String JMS_FACTORY= "javax.jms.TopicConnectionFactory"; public final static String QUEUE= "javax.jms.exampleQueue"; public void init(Context ctx, String queueName) throws NamingException, JMSException{

//1. Look up a JMS ConnectionFactory in JNDIQueueConnectionFactory qconFactory =

(QueueConnectionFactory)ctx.lookup(JMS_FACTORY); //2. Use the ConnectionFactory to create a ConnectionQueueConnection qcon = qconFactory.createQueueConnection();

//3. Use the Connection to create a SessionQueueSession qsessionSend = qcon.createQueueSession(false,

Session.AUTO_ACKNOWLEDGE);QueueSession qsessionReceive = qcon.createQueueSession(false,

Session.AUTO_ACKNOWLEDGE);

//4. Look up Queues or Topics in JNDIQueue queue = (Queue) ctx.lookup(“ExampleQueue”);

//5. Use the Session and the Queues or Topics to create message producers and consumersQueueSender qsender = qsessionSend.createSender(queue); QueueReceiver qreceiver = qsessionReceive.createReceiver(queue); qreceiver.setMessageListener(this);//6. Start the connectionqcon.start();

}

Page 37: JMS Technical Training - cfile23.uf.tistory.com

Point-to-Point JMS 예제 코드

Sending a message to a Queue:

publicvoid sendMsg(){

TextMessage msg = qsessionSend.createTextMessage(); msg.setText("Welcome to WebLogic JMS!"); qsender.send(msg);

}

publicvoid sendMsg(String mode){

TextMessage msg = qsessionSend.createTextMessage(); msg.setText("Welcome to WebLogic JMS!"); qsender.send(msg,DeliveryMode.PERSISTENT,Message.DEFAULT_PRIORITY

,Message.DEFAULT_TIME_TO_LIVE);

}

37

Page 38: JMS Technical Training - cfile23.uf.tistory.com

38

Point-to-Point JMS 예제 코드Queue로부터비동기메시지수신

//비동기수신자는QueueReceiver의 setMessageListner를 호출하여 JMS에자신을등록한다.

QueueSender qsender = qsessionSend.createSender(queue); QueueReceiver qreceiver = qsessionReceive.createReceiver(queue);

public void onMessage(Message msg) {

//Consumer asynchronous callback receive method//Implementation of javax.jms.MessageListener interfacetry {

String msgText; if (msg instanceof TextMessage) {

msgText = ((TextMessage)msg).getText(); } else { // If it is not a TextMessage...

msgText = msg.toString(); }

System.out.println("Message Received: "+ msgText ); } catch (JMSException jmse) {

jmse.printStackTrace(); }

}

Page 39: JMS Technical Training - cfile23.uf.tistory.com

39

Point-to-Point JMS 예제 코드Queue로부터동기(synchronous) 메시지수신• 동기식메시지수신을위하여 receive(), receive(long time-out),

receiveNoWait()를사용한다.– 동기식수신은메시지를수신하는동안하나의쓰레드를점유하고서버자원을 Blocking 하므로가급적사용을하지말것을권장한다.

– 부득이할경우 time-out값을적용한 receive(time-out) 이나receiveNoWait() 를사용할것을권장한다.

// Create a receiver to receive a message from the queue.

QueueReceiver qreceiver = qsession.createReceiver(queue);

qcon.start();

TextMessage msg = (TextMessage) qreceiver.receive(1000L);

System.out.println("Message is: " + msg.getText());

Page 40: JMS Technical Training - cfile23.uf.tistory.com

40

Point-to-Point JMS 예제 코드Queue로부터동기(synchronous) 메시지수신전체코드try {

Hashtable env = new Hashtable();// Lookup a connection factory and create a connection.QueueConnectionFactory qconFactory = (QueueConnectionFactory)ctx.lookup("example.QueueConnectionFactory");QueueConnection qcon = qconFactory.createQueueConnection();

// Create a session that is not transacted.QueueSession qsession =

qcon.createQueueSession(false,Session.AUTO_ACKNOWLEDGE);// Lookup a destination objectQueue queue = (Queue) ctx.lookup("example.ExampleQueue");

// Create a receiver to receive a message from the queue.QueueReceiver qreceiver = qsession.createReceiver(queue);qcon.start();//TextMessage msg = (TextMessage) qreceiver.receive();TextMessage msg = (TextMessage) qreceiver.receive(1000L);System.out.println("Message is: " + msg.getText());

} catch (Exception e) {System.out.println("Exception caught: " + e);e.printStackTrace();

}

Page 41: JMS Technical Training - cfile23.uf.tistory.com

41

JMS 1.1 바뀐 것들

• PTP,Pub/Sub 도메인에대해동일 API – 간단해진클라이언트프로그래밍모델– PTP 와 Pub/sub 메시징을단일트랜잭션에포함시킬수있는기능

• 이러한기능을이용할경우 , 애플리케이션은트랜잭션Session을생성한후, Queue로부터메시지를받는것과Topic에메시지를보내는것을하나의트랜잭션으로처리할수있다.

• JMS 1.0.2b 와의호환성제공• JMS 1.1 은 J2EE 1.4의일부

Page 42: JMS Technical Training - cfile23.uf.tistory.com

42

JMS 1.1 에서 바뀐 내용 - 1

JMS 1.0.2ConnectionFactory,Connection,Session 객체생성

//Create a JNDI InitialContext object if none exists yet.Context jndiContext = new InitialContext();

// Look up connection factory and topic.TopicConnectionFactory topicConnectionFactory = (TopicConnectionFactory)

jndiContext.lookup("TopicConnectionFactory");

Topic topic = (Topic) jndiContext.lookup("StockQuoteTopic");

//Establish TopicConnection and TopicSessionTopicConnection topicConnection = topicConnectionFactory.createConnection();TopicSession topicSession = topicConnection.createTopicSession(false,Session.AUTO_ACKNOWLEDGE);

JMS 1.1connectionFactory = (ConnectionFactory) jndiContext.lookup("TopicConnectionFactory");topic = (Topic) jndiContext.lookup("StockQuoteTopic");//Establish Connection and Sessionconnection = connectionFactory.createConnection();session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);

Page 43: JMS Technical Training - cfile23.uf.tistory.com

43

JMS 1.1 에서 바뀐 내용 - 2MessageProducer 생성JMS 1.0.2

// Create a TopicPublisher and send a message

TopicPublisher topicPublisher = null;

topicPublisher = topicSession.createPublisher(topic);message = topicSession.createTextMessage("A message body");topicPublisher.publish(message);

JMS 1.1// Create a Message Producer and send a message

MessageProducer messageProducer = null;

messageProducer = session.createProducer((Destination)topic);message = session.createTextMessage("A message body");messageProducer.send(message);

Page 44: JMS Technical Training - cfile23.uf.tistory.com

44

JMS 1.1 에서 바뀐 내용 - 3MessageProducer 생성JMS 1.0.2

// Create a TopicPublisher and send a message

TopicPublisher topicPublisher = null;

topicPublisher = topicSession.createPublisher(topic);message = topicSession.createTextMessage("A message body");topicPublisher.publish(message);

JMS 1.1// Create a Message Producer and send a message

MessageProducer messageProducer = null;

messageProducer = session.createProducer((Destination)topic);message = session.createTextMessage("A message body");messageProducer.send(message);

Page 45: JMS Technical Training - cfile23.uf.tistory.com

45

Q&A

Page 46: JMS Technical Training - cfile23.uf.tistory.com

46

resource-ref 사용하기EJB에서메시지보낼때…• 빈인스턴스레벨상에서 JMS 객체캐싱.

– Connection , Session , MessageProducer객체를 ejbCreate 내에서생성하라.– 각각을빈인스턴스그자체상의 private, non-static 변수에할당하라.– ejbRemove내에서 Connection, Session들을 close 하라.

• 그러나 EJB에서는쓰레드간 session 객체를공유하지않는다.• EJB가생성호출되어질때마다, destination, connectionFactory에대한

lookup 이발생하며, Connection, Session,MessageProducer등을생성하고,메시지를생성하고보내야한다. 그리고다시 close를호출애주어야한다.

• 그래서.. Resource-ref를사용할것을권장한다.– Application Server 가이러한일들을대신해줄수있다.– 벤더에따라캐싱등은다르게구현될수있다.– 애플리케이션의이식성을높여줄수있다. – EJB 와 Servlet 에서만적용가능..

• Servlet은멀티쓰레드이므로 JMS 관련코드를 공통클래스에두고공유하도록하자.

Page 47: JMS Technical Training - cfile23.uf.tistory.com

47

resource-ref 사용하기

public void sendAMessage() {

InitialContext c = new InitialContext();

Queue q = c.lookup(“java.comp/env/jms/MYQUEUE”);

QueueConnectionFactory qcf = c.lookup(“java:comp/env/jms/QCF”);

c.close();

QueueConnection conn = qcf.createQueueConnection();

try {

QueueSession session = conn.createQueueSession(true, 0);

QueueSender sender = session.createQueueSender(q);

TextMessage msg = session.createTextMessage(“Hello, World!”);

sender.send(msg);

} finally {

conn.close();

}

}

Page 48: JMS Technical Training - cfile23.uf.tistory.com

48

<ejb-jar><enterprise-beans><message-driven><ejb-name>MsgProcessBean</ejb-name><ejb-class>wwtt.jms.mdb.MsgProcessBean</ejb-class><transaction-type>Container</transaction-type><message-driven-destination><destination-type>javax.jms.Queue</destination-type>

</message-driven-destination><env-entry><env-entry-name>jms/props/debug</env-entry-name><env-entry-type>java.lang.Boolean</env-entry-

type><env-entry-value>true</env-entry-value></env-entry><resource-ref><res-ref-name>jms/qcf</res-ref-name><res-type>javax.jms.QueueConnectionFactory</res-type><res-auth>Container</res-auth><res-sharing-scope>Shareable</res-sharing-scope>

</resource-ref><resource-env-ref><resource-env-ref-name>jms/OutQueue</resource-env-ref-name><resource-env-ref-type>javax.jms.queue</resource-env-ref-type>

</resource-env-ref></message-driven>

</enterprise-beans><assembly-descriptor><container-transaction><method><ejb-name>MsgProcessBean</ejb-name><method-name>*</method-name>

</method><trans-attribute>Required</trans-attribute>

</container-transaction></assembly-descriptor>

</ejb-jar>

ejb-jar.xml

Page 49: JMS Technical Training - cfile23.uf.tistory.com

49

resource-ref 사용하기왜 resource-ref를사용하는가?• 배치디스크립터변경만으로 ..

– The JMS provider– The JMS destination– The transaction context

• 소스코드변경이필요없다.• XAConnectionFactory 사용에대해걱정할필요가없다.• EJB 컨테이너가더많은일들을하도록함.• WebLogic Server 8.1 의경우

– JMS Connection , Session , MessageProducer 객체의자동화된풀링기능

– JMS Provider가 down 되었을경우자동재연결– 현재트랜잭션을가진 XA 호환 JMS 프로바이더의자동참여.

Page 50: JMS Technical Training - cfile23.uf.tistory.com

50

트랜잭션 자동 참여.

Session beanX

Session beanYClient

WebLogic EJB Container

1.

2. 3.

4.

5.

Database AQueue A database B

•프로그래머는트랜잭션관련코드작성이필요없다.•단일트랜잭션처리.•트랜잭션이커밋(commit)될때, 3개의자원에대한 update를보장하기위해

WebLogic EJB 컨테이너와메시지, 데이터베이스는 2PC를수행한다.

Page 51: JMS Technical Training - cfile23.uf.tistory.com

51

JMS 메시지 수신MDB를이용하라.• 가능하다면, 되도록 MDB를사용하라.

– 이는컨테이너가인프라적인(middleware) 작업을수행하도록하기위함이다.

• 실패한프로바이더에대한재연결• 트랜잭션• 쓰레드관리

• MDB를사용할수없다면:– EJB와서블릿은 “receive”메쏘드를이용하여동기적으로받을수있다.

– EJB와서블릿들은비동기적으로메시지를수신하기위하여JMS MessageListener 인터페이스를사용을권장하지않는다.

• 컨테이너에의한 EJB 객체의풀링을가진인터페이스이므로..• J2EE 스펙상에서이것을허락하지않는다.• 어떤벤더들은이것을시도할경우 exception을던진다..

Page 52: JMS Technical Training - cfile23.uf.tistory.com

52

JMS 메시지 수신예제코드public class MessageTraderBean implements MessageDrivenBean, MessageListener {

private static final boolean VERBOSE = true;private MessageDrivenContext m_context;private int m_tradeLimit;

public void ejbActivate() {}public void ejbRemove() {}public void ejbPassivate() {}

public void setMessageDrivenContext(MessageDrivenContext ctx) {m_context = ctx;

}

public void ejbCreate () throws CreateException {}

public void onMessage(Message msg) {TextMessage tm = (TextMessage) msg;try {String text = tm.getText();log("Received new quote : " + text);

} catch(JMSException ex) {ex.printStackTrace();

}}}

Page 53: JMS Technical Training - cfile23.uf.tistory.com

53

JMS 메시지 수신ejb-jar.xml<!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN" "http://java.sun.com/dtd/ejb-jar_2_0.dtd"><ejb-jar><enterprise-beans>

<message-driven><ejb-name>exampleMessageDriven1</ejb-name><ejb-class>examples.ejb20.message.MessageTraderBean</ejb-class><transaction-type>Container</transaction-type><message-driven-destination><destination-type>javax.jms.Topic</destination-type>

</message-driven-destination></message-driven>

</enterprise-beans></ejb-jar>

<weblogic-ejb-jar><weblogic-enterprise-bean><ejb-name>exampleMessageDriven1</ejb-name><message-driven-descriptor><pool><max-beans-in-free-pool>200</max-beans-in-free-pool> <initial-beans-in-free-pool>20</initial-beans-in-free-pool>

</pool><destination-jndi-name>quotes</destination-jndi-name>

</message-driven-descriptor><jndi-name>examplesMessageDriven1</jndi-name>

</weblogic-enterprise-bean></weblogic-ejb-jar>

Vendor-specific DD

Page 54: JMS Technical Training - cfile23.uf.tistory.com

54

Request/Response MessagingUsing a Temporary Queue• JMS 메시지를보낸다음응답을기다릴필요가있을때임시큐(Temporary Queue)를사용한다. 예를들어 , 백엔드시스템에메시지를보내고반드시검증을받아야할경우등..

• 임시목적지는 JMS 애플리케이션이동적으로일시적인목적지를생성하는것이다. 임시목적지는시스템장애시계속존재할수없기때문에메시지손실이발생할수도있다.

• Sender는응답을수집하기위하여 “TemporaryQueue”객체를생성한다. – TemporryQueue tmpQueue = session.createTemporaryQueue();– Queue 클래스를확장하여단지 delete() 메쓰드만을추가한것이다.

• Sender를 “replyTo”필드내에 “Temporary queue”를가지고메시지를보낸다. • Sender는 temporay queue 상의응답을기다린다.• Sender 와 Recipient를모두 resource-ref를사용해야만한다. • JMS 클라이언트는임시목적지작업이끝나면 delete()를호출하여자원을반환한다.

Page 55: JMS Technical Training - cfile23.uf.tistory.com

55

Request/Response MessagingUsing a Temporary Queue

/* 오래걸리는작업이므로 , EJB에서사용할경우 ejbCreate() 메쏘드등에서사용하기를권장 */TemporaryQueue tempQueue= session.createTemporaryQueue();TextMessage msg = session.createTextMessage();msg.setStringProperty(“ “ , );msg.setText(“This is sending message”);

// set the JMSReplyTo for the receipt…msg.setJMSReplyTo(tempQueue);

// send message..sender.send(msg);

QueueReceiver receiver = session.createReceiver(tempQueue);

/* 응답을수신할때까지쓰레드는블럭킹되어진다. */Message receipt = receiver.receive(1000L);

Page 56: JMS Technical Training - cfile23.uf.tistory.com

56

메시지 순서 보장CorrelationID를사용하라.public class MsgProcessBean extends GenericMessageDrivenBean implements MessageDrivenBean, MessageListener{

public void onMessage(Message msg) { printTxID("MsgProcessBean onMessage TxID is: ");String msgText = "";try{

correlationID = msg.getJMSCorrelationID();log("The JMS correlationID is from the message is: " + correlationID);if (msg instanceof TextMessage)

msgText = ((TextMessage)msg).getText(); log("MDB just got message:" + msgText + " from requestID " + correlationID);msgText = "This is the reply to " + msgText + " from requestID " + correlationID;

} catch (JMSException jmse) {jmse.printStackTrace();

}try { reply(msgText); } catch (Exception ex) { ex.printStackTrace(); }

}private void reply(String replyText) throws RemoteException {

javax.jms.QueueConnection connection = qcf.createQueueConnection();try {

QueueSession session = connection.createQueueSession(transacted, Session.AUTO_ACKNOWLEDGE);QueueSender sender = session.createSender(outQueue);replyMsg = session.createTextMessage(replyText);replyMsg.setJMSCorrelationID(correlationID);

sender.send(replyMsg, delivery_mode, 9, 0);}

Page 57: JMS Technical Training - cfile23.uf.tistory.com

57

MessageSelector

• Consumer들은전송된메시지들중에서일부만받기를원하는경우도있다. 이러한 consumer를위해메시지를자동으로필터링하는표준메시지분별기(selector)를사용하자.

• 필터링은메시지가 consumer에게전송되기전에 JMS 에서수행된다.

• JMS 표현식을이용하여작성한다. • 메시지헤더와속성들에대하여적용한다. • 표현식이참이면메시지는 consumer에게전송된다.

Receiver = session.createReceiver(messageQueue, “JMSPriority > 5”);

Page 58: JMS Technical Training - cfile23.uf.tistory.com

58

Best-Practice

• 불필요한메시지속성지정하지말것• MessageSelector를사용하라.• 가능한한비동기메시지를사용하라.• Resource-ref를사용하라.• 잘못된메시지는에러 Destination 으로보내서후처리하라.

Page 59: JMS Technical Training - cfile23.uf.tistory.com

59

Q&A , Demo