Controle de filas em jms

4 respostas
S

Boa tarde senhores, tenho o seguinte problema:
Tenho uma fila jms e nessa fila preciso limitar o numero de mensagens que são enviadas a ela.
Uma solução que já usei, é a de usar um monitor que guarda a quantidade de mensagens que já foram enviadas, e quando essa quantidade assume o limite ele aguarda até que uma mensagem da fila seja totalmente consumida, e quando uma mensagem é consumida ele subtrai 1 do monitor.

Isso funciona bem quando tudo roda na mesma jvm, como consigo implementar isso quando existe a possibilidade do consumer e do producer estarem em jvms diferentes?

4 Respostas

R

Tem uma maneira que é a seguinte.

Usar Sessão Transacionada, no caso vc cria uma sessão com varias mensagens.

Ao enviar mensagens em uma sessão transaccionadas, as mensagens não serão entregues ao consumidor de mensagens até que a sessão no produtor de mensagem tenha sido comitado através da Session.commit () .

Para isso, vc precisaria fazer algo do tipo:

public void sendMessages() {
	try {
		//envia as mensagens em uma transação
		System.out.println("Session Transacted: " + session.getTransacted());
		sendMessage("First Message");
		sendMessage("Second Message");
		sendMessage("Third Message");
		//a transação só será encerrada quando for dado o commit
		session.commit();
		connection.close();
	} catch (Exception ex) {
		try {
			System.out.println("Exception caught, rolling back session");
			session.rollback();
		} catch (JMSException jmse) {
			jmse.printStackTrace();
		}
	}
}

private void sendMessage(String text) throws Exception {
	//envia a mensagem de texto dentro do grupo de mensagens
	TextMessage msg = session.createTextMessage(text);
	sender.send(msg);
} 

public JMSSenderTransacted() {
	try {
		//criar a conexão, a sessão, e remetente
		Context ctx = new InitialContext();
		QueueConnectionFactory factory = (QueueConnectionFactory)
		ctx.lookup("QueueCF");
		connection = factory.createQueueConnection();
		connection.start();
		//aqui é onde diz que é transacional, quando marcada a session como true
		session = connection.createQueueSession(true, Session.AUTO_ACKNOWLEDGE);
		Queue queue = (Queue)ctx.lookup("fila");
		sender = session.createSender(queue);
	} catch (Exception jmse) {
		jmse.printStackTrace();
		System.exit(0);
	}
}

Não sei como vc cria suas mensagens, mas poderia armazena-las em uma lista, com a quantidade que deseja, e enviar para o servidor.

R

Uma outra maneira que existe, seria não limitar o envio, mas sim o consumo.

Usando session = connection.createQueueSession(false, Session.DUPS_OK_ACKNOWLEDGE); o consumidor passa a consumir em grupos de 10 mensagens(não tenho certeza se é essa quantidade mesmo).
No caso, vc poderia enviar 50 mensagens, e elas seriam consumidas de 10 em 10.

S

romarcio:
Uma outra maneira que existe, seria não limitar o envio, mas sim o consumo.

Usando session = connection.createQueueSession(false, Session.DUPS_OK_ACKNOWLEDGE); o consumidor passa a consumir em grupos de 10 mensagens(não tenho certeza se é essa quantidade mesmo).
No caso, vc poderia enviar 50 mensagens, e elas seriam consumidas de 10 em 10.

Tem como configurar isso?
Tipo se eu quiser de 15 em 15 ou de 20 em 20?
Eu estou usando o jboss 4.0.5GA

R

Não sei não.

Eu li sobre isso aqui: http://www.nce.ufrj.br/conceito/artigos/2005/012p1-2.htm

E foi o único lugar que encontrei, que cita esse esquema de 10 mensagens. Os demais todos só falam em mensagens repetidas.

Acho que o melhor esquema é o da transação mesmo, leia um pouco sobre isso aqui: http://java.sys-con.com/node/36239

Criado 6 de outubro de 2010
Ultima resposta 6 de out. de 2010
Respostas 4
Participantes 2