1. Queue Point
A message can only be consumed by a consumer, and is the persistent message - when consumers are not available, the message is saved until it is consumed location; when the message has been received but the consumer does not respond, the message will be retained or will take you to another customer, this is the case where a plurality of consumers. When a Queue consumers have more available, load balancing can play a role in these consumers.
2. Topic Posted - Subscriber Model
When a message is published, all subscribers will receive, Topic has two modes, (persistent subscription Nondurable subscription (non-persistent subscription) and durable subscription - each subscriber persistence are the equivalent of a lasting words queue of customers end), the default non-persistent subscriptions.
- Persistence: When a message is generated, saved to a file or database, until the message is consumed, Queue persistent messages.
- Non-persistent: messages are not saved when there is no consumer spending, it will be discarded
3. Code
- pom.xml
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-activemq</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
- application.properties
= 9090 the server.port #springboot in activemq configuration, springboot will automatically establish these connections factory spring.activemq.broker-TCP = URL: // localhost: 61616 spring.activemq.non to false-blocking-redelivery = spring.activemq. send-timeout = 0 is set to true # Topic using set Queue # is used to false spring.jms.pub-Sub-Domain = true spring.activemq.user = ADMIN spring.activemq.password = ADMIN #activemq configuration class used configuration items, custom connections project, in order to achieve Topic Virtual activemq.url = tcp: //10.195.229.8: 61616 activemq.username = ADMIN activemq.password = ADMIN activemq.virtual.topic = VirtualTopic.Topic1 activemq.virtual.topic = Consumer.A.VirtualTopic.Topic1 II.A, activemq.virtual.topic.B = Consumer.B.VirtualTopic.Topic1
- activemq configuration class, the plant can be configured to connect the plurality of servers activemq
springboot connection will be generated automatically on the plant configuration according activemq application, but this can not achieve virtual connection factory Topic
Because springboot based spring.jms.pub-sub-domain . When true topic is generated connection factory, it is generated for the false connection queue factory
package com.example.demo.config; import org.apache.activemq.ActiveMQConnectionFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.jms.annotation.EnableJms; import org.springframework.jms.config.DefaultJmsListenerContainerFactory; import org.springframework.scheduling.annotation.EnableAsync; import javax.jms.ConnectionFactory; /** * @author * @version V1.0 * @modify: {原因} */ @Configuration @EnableJms @EnableAsync public class JmsConfig { @Value("${activemq.url}") private String url; @Value("${activemq.username}") private String username; @Value("${activemq.password}") private String password; private Logger logger = LoggerFactory.getLogger(JmsConfig.class); @Bean(name = "firstConnectionFactory") public ActiveMQConnectionFactory firstConnectionFactory(){ ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(); connectionFactory.setBrokerURL(url); connectionFactory.setUserName(username); connectionFactory.setPassword(password); return connectionFactory; } // @Bean(name = "firstJmsTemplate") // public JmsMessagingTemplate getFirstJmsTemplate(@Qualifier("firstConnectionFactory") ConnectionFactory connectionFactory) { // JmsMessagingTemplate template = new JmsMessagingTemplate(connectionFactory); // return template; // } @Bean(name="firstTopicListener") public DefaultJmsListenerContainerFactory firstTopicListenerFactory(@Qualifier("firstConnectionFactory")ConnectionFactory connectionFactory){ DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory(); factory.setConnectionFactory(connectionFactory); factory.setPubSubDomain(true); return factory; } @Bean(name="firstQueueListener") public DefaultJmsListenerContainerFactory firstQueueTopicListenerFactory(@Qualifier("firstConnectionFactory")ConnectionFactory connectionFactory){ DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory(); factory.setConnectionFactory(connectionFactory); return factory; } }
- Producers class
package com.example.demo.VirtualTopic; import org.apache.activemq.command.ActiveMQTopic; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.jms.annotation.JmsListener; import org.springframework.jms.core.JmsMessagingTemplate; import org.springframework.scheduling.annotation.Async; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import javax.jms.Destination; import javax.jms.JMSException; import javax.jms.Topic; @RestController public class ProducerVirtualTopicController { @Autowired private JmsMessagingTemplate jmsMessagingTemplate; @RequestMapping(value = "/sendMessageVirtual",method = RequestMethod.GET) public void sendMessageVirtual(){ for(int i =0;i<5;i++){ //虚拟Topic具有自己的命名规则 ActiveMQTopic topic = new ActiveMQTopic("VirtualTopic.Topic1"); this.jmsMessagingTemplate.convertAndSend(topic,"sss"); } } }
- consumer
package com.example.demo.VirtualTopic; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.jms.annotation.JmsListener; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; import javax.jms.JMSException; @Component public class Consumer { private static final Logger logger = LoggerFactory.getLogger(Consumer.class); @JmsListener(destination="Consumer.B.VirtualTopic.Topic1",containerFactory = "firstQueueListener") @Async public void receiveVTopicB(String message) throws JMSException{ logger.debug("VTopic B ===== "+ message); System.out.println("VTopic B ======="+ message); try{ Thread.sleep(500L); }catch(InterruptedException e){ e.printStackTrace(); } } @JmsListener(destination="Consumer.A.VirtualTopic.Topic1",containerFactory = "firstQueueListener") @Async public void receiveVTopicA1(String message) throws JMSException { logger.debug("VTopic A1 ===== "+ message); System.out.println("VTopic A1 ======="+ message); try{ Thread.sleep(500L); }catch(InterruptedException e){ e.printStackTrace(); } } @JmsListener(destination="Consumer.A.VirtualTopic.Topic1",containerFactory = "firstQueueListener") @Async public void receiveVTopicA2(String message)throws JMSException{ logger.debug("VTopic A2 ===== "+ message); System.out.println("VTopic A2 ======="+ message); try{ Thread.sleep(500L); }catch(InterruptedException e){ e.printStackTrace(); } } }
Start springboot project, call interface http: // localhost: 9090 / sendMessageVirtual can see A1 A2 total consumption to five messages, but also B consumption to 5 messages
4. Summary
- Scenarios
A program to be deployed on multiple servers, there is the same program more, but requires the same procedures only one to receive the message, VirtualTopic is to solve this problem for producers to send a message the topic, the deployment phase for these programs on multiple servers, each of which are in the consumer the same queue, and other deployment programs on the server is still listening topic.
- Virtual Topic naming rules
Topic name: VirtualTopic.xxx
consumer name: Consumer.yyy.VirtualTopic.xxx
Transfer from https://www.jianshu.com/p/a924c30554ca