Estou desenvolvendo um MDB que chama um processo de EJB e preciso que as mensagens sejam consumidas uma por vez, como que eu faço isso?
Consumo de mensagens MDB
7 Respostas
As mensagens virão uma pro vez das filas JMS.
Não é garantido que as mensagens serão processadas uma por vez pelo MDB. O container pode alocar mais de uma instancia do MDB pra processar as mensagens da fila, de forma que uma determinada mensagem M2 possa comecar a ser processada por uma instancia B do MDB, sem que a mensagem M1 tenha sido completamente processada pela instancia A do MDB. Neste caso cada mensagem estaria sendo processada em uma thread separadamente. É realmente necessário que cada mensagem dependa do completo processamento da mensagem anterior? Este cenário seria um processamento síncrono e não assíncrono que justifique o uso de mdb.
[]'s
É necessário, o processo é demorado. Assim iria para fila e em outra tela poderia ser visto o estado do processo, persistido no banco com a situacao, na fila, terminado, etc. Não tem como?
Certo, mas aí qual o problema se tiver mais de uma mensagem rodando ao mesmo tempo? Há dependencia no resultado de processamento de uma mensagem em relacao à posterior na fila? Pergunto isso pq vc disse: “preciso que as mensagens sejam consumidas uma por vez”
[]'s
isso, em alguns casos pode ter dependencia. tem como fazer com q seja um por vez?
A nao ser que vc configure o seu container para permitir criar no máximo uma instância deste seu MDB, não. De qualquer forma, essa nao seria uma solucao aceitável, pois comprometeria a performance do processamento de suas mensagens. Voce terá q implementar esse controle manualmente. Voce pode fazer com o que o(s) cliente(s) que envia(m) as mensagens pra fila só envie(m) as mensagens dependentes para a fila uma vez que a mensagens pré-requisitos ja tenham sido processada. Ou vc pode definir o seu MDB como CMT, com transaction attribute Required e implementar a verificacao se a mensagem pre requisito ja foi completamente processada no proprio onMessage do MDB. Caso negativo, é só lancar uma SystemException, que o container irá fazer com que a mensagem seja reenviada para uma outra instancia do MDB. Isso tbm pode trazer problemas de performance, mas se o seu container permitir que se configure o tempo de redelivery da mensagem no caso de excecoes, essa alternativa passa a ser valida.
[]`s
Estou lidando com a PAPI do ALBPM. Estou fazendo um sistema de redesignação no BPM da empresa. Na arquitetura atual, o PTIDS faz o sincronismo entre o ALI e o BPM e, a princípio, só podemos executar outra requisição a API do ALI quando esta já estiver totalmente sincronizada com o BPM. Digo "a princípio" pois ainda preciso fazer alguns testes mais profundos de processamento de vários usuários diferentes. Nos testes superficiais, percebi que o PTIDS estava se perdendo quando várias chamadas a API do ALI era executada ao mesmo tempo. Mesmo que seja possível executar várias chamadas, terei que achar uma forma de controlar que a mesma requisição de redesignação não seja feita para o mesmo usuário, pois teríamos um problema sério de concorrencia. Dessa forma, estou usando processamento sequencial das mensagens e não concorrente.
Expliquei este cenário para demonstrar como pode existir uma necessidade de processamento sequencial. Processamento sequencial de mensagens não significa sincronismo, mas sim, continua sendo assincrono, pois o caller não precisa ficar aguardando o processamento da requisição para continuar. Assim, temos de um lado o Publisher, um servlet que recebe a requisição de redesignação via post, monta a mensagem e coloca na fila JMS. E temos o Subscriber, que é um MDB que escuta a fila e delega o processamento da mensagem, que será feita baseada nas RNs, para a camada de negócio, que está em um JAR. Para esta solução, configurei apenas um MDB para escutar a fila. Estou com a pulga atrás da orelha com a questão da perfomance. Ainda vou fazer testes de perfomance para saber até onde (numero de requisições/segundo) a aplicação se comporta de forma aceitável. Ainda não vi nenhuma solução para o problema do PTIDS se perder.
Outro teste que vou fazer será verificar em que circunstância o PTIDS se perde. Para isso, vou colocar novamente alguns MDBs escutando a fila.
Mas, depois de tanta introdução, respondendo a sua pergunta, é possível configurar apenas um MDB para escutar a fila. No meu caso, que estou usando o WLS, basta configurar o weblogic-ejb-jar.xml da seguinte forma.
<?xml version="1.0" encoding="UTF-8"?>
<wls:weblogic-ejb-jar xmlns:wls="http://www.bea.com/ns/weblogic/weblogic-ejb-jar"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd http://www.bea.com/ns/weblogic/weblogic-ejb-jar http://www.bea.com/ns/weblogic/weblogic-ejb-jar/1.0/weblogic-ejb-jar.xsd">
<!--weblogic-version:10.3.0-->
<wls:weblogic-enterprise-bean>
<wls:ejb-name>Consumer</wls:ejb-name>
<wls:message-driven-descriptor>
<wls:pool>
<wls:max-beans-in-free-pool>1</wls:max-beans-in-free-pool>
<wls:initial-beans-in-free-pool>1</wls:initial-beans-in-free-pool>
</wls:pool>
</wls:message-driven-descriptor>
</wls:weblogic-enterprise-bean>
</wls:weblogic-ejb-jar>
Não sei como seria a configuração em outros aplication servers. Mas o caminho é o mesmo.
Abraços.