Preface
Today, we share with you springboot's integration of activeMq's topic (Theme) - Publish / subscribe mode, similar to the WeChat public number. We can receive messages when we are concerned about the public. Topic needs consumers to subscribe before they can receive messages. If there is no consumer subscription, the message generated by the producers is the waste message (publish / subscribe mode, the producer produces a message, which can be consumed by multiple consumers. Consumption). This instance supports websocket, message resend and persistence
Version information: SpringBoot2.1.5 ActiveMQ 5.15.10
Consumer Engineering
Consumer engineering catalog
pom file
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-activemq</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency>
yml file configuration
server port: 8085 spring: activemq: broker-url: tcp://localhost:61616 user: admin password: admin jms: pub-sub-domain: true #Own theme name myTopic: boot_actviemq_topic
Configuration class
package com.example.topic_customer.config; import org.apache.activemq.ActiveMQConnectionFactory; import org.apache.activemq.RedeliveryPolicy; import org.apache.activemq.command.ActiveMQTopic; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.jms.config.DefaultJmsListenerContainerFactory; import org.springframework.stereotype.Component; import org.springframework.web.socket.server.standard.ServerEndpointExporter; import javax.jms.ConnectionFactory; import javax.jms.Topic; /** * @Date 2019/11/13 10:22 * @Desc Consumer configuration class */ @Configuration public class BeanConfig { @Value("${myTopic}") private String myTopic; /** * websocket To configure * * @return */ @Bean public ServerEndpointExporter serverEndpointExporter() { return new ServerEndpointExporter(); } @Bean public Topic topic() { return new ActiveMQTopic(myTopic); } public RedeliveryPolicy redeliveryPolicy() { RedeliveryPolicy redeliveryPolicy = new RedeliveryPolicy(); //Whether to increase the waiting time after each attempt to resend fails redeliveryPolicy.setUseExponentialBackOff(true); //The number of retransmissions, which is 6 by default, is set to 10 here, and - 1 means unlimited times redeliveryPolicy.setMaximumRedeliveries(-1); //Retransmission interval, default 1 ms, set to 10000 MS redeliveryPolicy.setInitialRedeliveryDelay(10000); //Indicates that there is no delay and only when useexponential backoff (true) is true //Wait 10000 ms after the first failure before resending and 10000 * 2 ms after the second failure //Double 10000 * 2 * 2 for the third time, and so on redeliveryPolicy.setBackOffMultiplier(2); //Avoid message collision redeliveryPolicy.setUseCollisionAvoidance(true); //Setting the maximum delay time of resend 360000 MS means there is no delay, only when useexponential backoff (true) is true redeliveryPolicy.setMaximumRedeliveryDelay(360000); return redeliveryPolicy; } public ConnectionFactory connectionFactory() { ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(); //Set resend properties connectionFactory.setRedeliveryPolicy(redeliveryPolicy()); return connectionFactory; } /** * JMS Listener container factory for queues */ @Bean(name = "jmsTopicListener") public DefaultJmsListenerContainerFactory jmsTopicListenerContainerFactory() { DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory(); factory.setConnectionFactory(connectionFactory()); factory.setPubSubDomain(true); factory.setSessionTransacted(true); factory.setAutoStartup(true); //Open persistent subscription factory.setSubscriptionDurable(true); //Reconnection interval factory.setRecoveryInterval(1000L); factory.setClientId("topic_provider:zb1"); return factory; } }
There are two main ways to set up consumer persistence:
- //Open persistent subscription factory.setSubscriptionDurable(true);
2.factory.setClientId("topic [provider: zb1"); / / this can be set at will
. topicalcustomer class
package com.example.topic_customer.customer; import lombok.Data; import org.springframework.jms.annotation.JmsListener; import org.springframework.stereotype.Component; import javax.jms.JMSException; import javax.jms.TextMessage; import javax.websocket.OnClose; import javax.websocket.OnError; import javax.websocket.OnMessage; import javax.websocket.OnOpen; import javax.websocket.server.ServerEndpoint; import java.util.concurrent.CopyOnWriteArraySet; /** * @Date 2019/11/13 13:31 * @Desc */ @Component @ServerEndpoint("/websocket") @Data public class TopicCustomer { /** * Each client will have a corresponding session, and the server can send relevant messages */ private javax.websocket.Session session; /** * J.U.C The thread safe class under the package is mainly used to store the corresponding webSocket connection of each client */ private static CopyOnWriteArraySet<TopicCustomer> copyOnWriteArraySet = new CopyOnWriteArraySet<>(); @OnOpen public void onOpen(javax.websocket.Session session) { this.session = session; copyOnWriteArraySet.add(this); } @OnClose public void onClose() { copyOnWriteArraySet.remove(this); } @OnMessage public void onMessage(String message) { } @OnError public void onError(javax.websocket.Session session, Throwable error) { error.printStackTrace(); } @JmsListener(destination = "${myTopic}", containerFactory = "jmsTopicListener") public void receive(TextMessage textMessage, javax.jms.Session session) throws JMSException { //Traverse client for (TopicCustomer webSocket : copyOnWriteArraySet) { try { //Server active push webSocket.session.getBasicRemote().sendText(textMessage.getText()); System.out.println("-- Receive topic Persistent message -- " + textMessage.getText()); } catch (Exception e) { System.out.println("-----Test retransmission-----"); session.rollback();// You cannot omit to use the retransmission information } } } }
Startup class
package com.example.topic_customer; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class TopicCustomerApplication { public static void main(String[] args) { SpringApplication.run(TopicCustomerApplication.class, args); } }
Screenshot of mq after the consumer starts successfully:
Producer Engineering
Manufacturer's engineering catalog
yml profile
server: port: 8084 spring: activemq: broker-url: tcp://localhost:61616 user: admin password: admin jms: pub-sub-domain: true myTopic: boot_actviemq_topic
Configuration class
package com.example.topicprovider.config; import org.apache.activemq.ActiveMQConnectionFactory; import org.apache.activemq.RedeliveryPolicy; import org.apache.activemq.command.ActiveMQTopic; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.jms.config.DefaultJmsListenerContainerFactory; import org.springframework.stereotype.Component; import javax.jms.ConnectionFactory; import javax.jms.Topic; /** * @Date 2019/11/13 10:22 * @Desc Producer profile */ @Component public class BeanConfig { @Value("${myTopic}") private String myTopic; public RedeliveryPolicy redeliveryPolicy(){ RedeliveryPolicy redeliveryPolicy= new RedeliveryPolicy(); //Whether to increase the waiting time after each attempt to resend fails redeliveryPolicy.setUseExponentialBackOff(true); //The number of retransmissions, which is 6 by default, is set to 10 here, and - 1 means unlimited times redeliveryPolicy.setMaximumRedeliveries(-1); //Retransmission interval, default 1 ms, set to 10000 MS redeliveryPolicy.setInitialRedeliveryDelay(10000); //Indicates that there is no delay and only when useexponential backoff (true) is true //Wait 10000 ms after the first failure before resending and 10000 * 2 ms after the second failure //Double 10000 * 2 * 2 for the third time, and so on redeliveryPolicy.setBackOffMultiplier(2); //Avoid message collision redeliveryPolicy.setUseCollisionAvoidance(true); //Setting the maximum delay time of resend 360000 MS means there is no delay, only when useexponential backoff (true) is true redeliveryPolicy.setMaximumRedeliveryDelay(360000); return redeliveryPolicy; } @Bean public Topic topic() { return new ActiveMQTopic(myTopic); } public ConnectionFactory connectionFactory(){ ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(); //Set resend properties connectionFactory.setRedeliveryPolicy(redeliveryPolicy()); return connectionFactory; } /** * JMS Listener container factory for queues */ @Bean(name = "jmsTopicListener") public DefaultJmsListenerContainerFactory jmsTopicListenerContainerFactory() { DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory(); factory.setConnectionFactory(connectionFactory()); factory.setPubSubDomain(true); factory.setSessionTransacted(true); factory.setAutoStartup(true); //Open persistent subscription factory.setSubscriptionDurable(true); //Reconnection interval factory.setRecoveryInterval(1000L); return factory; } }
TopicProvider class
package com.example.topicprovider.topic_provider; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jms.core.JmsMessagingTemplate; import org.springframework.jms.core.JmsTemplate; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import javax.jms.Topic; import java.util.UUID; /** * @Date 2019/11/13 10:25 * @Desc */ @Component public class TopicProvider { @Autowired private Topic topic; @Autowired private JmsTemplate jmsTemplate; @Scheduled(fixedDelay = 10000) private void produceMsg() { jmsTemplate.convertAndSend(topic, "Subject producers" + UUID.randomUUID().toString().substring(1, 7)); System.out.println( jmsTemplate.getDeliveryMode()); System.out.println("Theme producer 1"); } }
Startup class
package com.example.topicprovider; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.scheduling.annotation.EnableScheduling; @SpringBootApplication @EnableScheduling public class TopicProviderApplication { public static void main(String[] args) { SpringApplication.run(TopicProviderApplication.class, args); } }
Results after successful startup:
Last
Like, you can pay attention to my public address: java little melon brother sharing platform. Thank you for your support!