spring-boot学习:十九、spring-boot集成activemq

故事扮演 提交于 2020-08-16 14:00:53

一、安装activemq(windows)

  1. 下载后解压到指定目录

    http://activemq.apache.org/components/classic/download/
    
  2. 配置文件D:\software\apache-activemq-5.15.9\conf
    1)jetty.xml
    配置控制台地址和端口:

    <bean id="jettyPort" class="org.apache.activemq.web.WebConsolePort" init-method="start">
    		 <!-- the default port number for the web console -->
    	<property name="host" value="0.0.0.0"/>
    	<property name="port" value="8161"/>
    </bean>
    

    角色:

    <bean id="securityConstraint" class="org.eclipse.jetty.util.security.Constraint">
    	<property name="name" value="BASIC" />
    	<property name="roles" value="user,admin" />
    	<!-- set authenticate=false to disable login -->
    	<property name="authenticate" value="true" />
    </bean>
    

    2)jetty-realm.properties
    配置账号和角色

    # username: password [,rolename ...]
    admin: admin, admin
    user: user, user
    

    3)activemq.xml
    配置连接地址/端口:默认61616

    <transportConnectors>
    	<!-- DOS protection, limit concurrent connections to 1000 and frame size to 100MB -->
    	<transportConnector name="openwire" uri="tcp://0.0.0.0:61616?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
    	<transportConnector name="amqp" uri="amqp://0.0.0.0:5672?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
    	<transportConnector name="stomp" uri="stomp://0.0.0.0:61613?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
    	<transportConnector name="mqtt" uri="mqtt://0.0.0.0:1883?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
    	<transportConnector name="ws" uri="ws://0.0.0.0:61614?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
    </transportConnectors>
    

    <shutdownHooks>后面加入连接账号:

    <plugins>   
    	<simpleAuthenticationPlugin>   
    		<users>   
    			<authenticationUser username="${activemq.username}" password="${activemq.password}" groups="users,admins"/>   
    		</users>   
    	</simpleAuthenticationPlugin>   
    </plugins>
    

    4)credentials.properties
    配置连接账号:

    activemq.username=system
    activemq.password=manager
    guest.password=password
    
  3. 启动D:\software\apache-activemq-5.15.9\bin\win64\activemq.bat在这里插入图片描述

  4. 登录控制台查看http://127.0.0.1:8161/admin/
    使用账号admin/admin(参考jetty-realm.properties)
    在这里插入图片描述

  5. activemq支持两种消息
    在这里插入图片描述
    二、springboot集成activemq

    1.pom.xml

    <dependency>
    	<groupId>org.springframework.boot</groupId>
    	<artifactId>spring-boot-starter-activemq</artifactId>
    </dependency>
    
    <!-- 启用pool需要引入以下jar包 -->
    <dependency>  
    	 <groupId>org.apache.activemq</groupId>  
    	 <artifactId>activemq-pool</artifactId>  
     </dependency>
     
     <dependency>
    	 <groupId>org.messaginghub</groupId>
    	 <artifactId>pooled-jms</artifactId>
     </dependency>
    

    2.application.properties

    # activemq (https://docs.spring.io/spring-boot/docs/2.1.5.RELEASE/reference/htmlsingle/#boot-features-activemq)
    spring.activemq.broker-url=tcp://127.0.0.1:61616
    spring.activemq.user=system
    spring.activemq.password=manager
    spring.activemq.pool.enabled=true
    spring.activemq.pool.max-connections=500
    

    3.Application.java

    @EnableJms
    public class Application extends SpringBootServletInitializer {
    
    	// 当需要activemq支持topic消息,需要注册JmsListenerContainerFactory,且设置PubSubDomain为true,否则无法消费topic消息
    	// 也可以在配置文件中加入spring.jms.pub-sub-domain=true,则只支持topic消息,不支持queue消息
    	@Bean
    	public DefaultJmsListenerContainerFactory jmsTopicListenerContainerFactory(
    			ConnectionFactory connectionFactory) {
    		DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
    		factory.setConnectionFactory(connectionFactory);
    		factory.setPubSubDomain(true);
    		return factory;
    	}
    }
    

    4.消息生产者,直接使用JmsTemplate发送消息

    import javax.jms.Destination;
    import javax.jms.Queue;
    import javax.jms.Topic;
    
    import org.apache.activemq.command.ActiveMQQueue;
    import org.apache.activemq.command.ActiveMQTopic;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.jms.core.JmsTemplate;
    import org.springframework.stereotype.Component;
    
    @Component
    public class ActivemqProducer {
    	
    	@Autowired
    	private JmsTemplate jmsTemplate;
    	
    	public void sendMsg(Destination destination, String message) {
    		jmsTemplate.convertAndSend(destination, message);
    	}
    	
    	public void sendQueueMsg(Queue queue, String message) {
    		sendMsg(queue, message);
    	}
    	
    	public void sendQueueMsg(String queueName, String message) {
    		sendMsg(new ActiveMQQueue(queueName), message);
    	}
    	
    	public void sendTopicMsg(Topic queue, String message) {
    		sendMsg(queue, message);
    	}
    	
    	public void sendTopicMsg(String topicName, String message) {
    		sendMsg(new ActiveMQTopic(topicName), message);
    	}
    }
    

    5.消息消费者,分别创建了两个queue消费者和两个topic消费者,默认的containerFactory是queue消息,所以消费queue消息时可不配置containerFactory

    import org.springframework.jms.annotation.JmsListener;
    import org.springframework.stereotype.Component;
    
    @Component
    public class ActivemqConsumer {
    
    	@JmsListener(destination = "spring-boot.queue")
        public void consumerQueueMessage(String message){
            System.out.println("收到spring-boot.queue报文:"+message);
        }
    	
    	@JmsListener(destination = "spring-boot.queue")
        public void consumerQueueMessage2(String message){
            System.out.println("收到spring-boot.queue报文2:"+message);
        }
    	
    	@JmsListener(destination = "spring-boot.topic", containerFactory = "jmsTopicListenerContainerFactory")
        public void consumerTopicMessage(String message){
            System.out.println("收到spring-boot.topic报文:"+message);
        }
    	
    	@JmsListener(destination = "spring-boot.topic", containerFactory = "jmsTopicListenerContainerFactory")
        public void consumerTopicMessage2(String message){
            System.out.println("收到spring-boot.topic报文2:"+message);
        }
    	
    }
    

    6.测试(@OpenAPI和@OpenAPIMethod是自定义的接口注解,可直接使用

    @RestController和@RequestMapping替换)
    @Component
    @OpenAPI
    public class ApiTest {
    	
    	private static final Logger logger = LoggerFactory.getLogger(ApiTest.class);
    	
    	@Autowired
    	private ActivemqProducer mqProducer;
    	
    	@OpenAPIMethod(methodName = "testActivemqSender")
        public Object testActivemqSender(final String msg) throws Exception {
    
    		mqProducer.sendQueueMsg("spring-boot.queue", msg);
    		
    		mqProducer.sendTopicMsg("spring-boot.topic", msg);
    		
    		return null;
        }
    }
    

    访问:http://10.0.0.57:9001/api/testActivemqSender?msg=KevinTest

    日志打印:
    收到spring-boot.queue报文2:KevinTest
    收到spring-boot.topic报文2:KevinTest
    收到spring-boot.topic报文:KevinTest


    7.查看控制台
    queues:spring-boot.queue未消费的消息数为0,存在2个消费者,生产消息数为1,消费消息数为1
    在这里插入图片描述

    topics: spring-boot.topic存在两个消费者,生产消息数1,消费消息数2
    在这里插入图片描述

    8.关闭所有消费者后再发送一次消息http://10.0.0.57:9001/api/testActivemqSender?msg=KevinTestNoConsumer

    queues: spring-boot.queue未消费的消息数为1,存在0个消费者,生产消息数为2,消费消息数为1
    在这里插入图片描述

    查看未消费的消息详情:
    在这里插入图片描述

    topics:spring-boot.topic存在0个消费者,生产消息数2,消费消息数2
    在这里插入图片描述

    9.以上测试说明
    1)queue消息只能被一个consumer消费,当没有消费者时,消息会被保存,消费者上线后会被消费
    2)topic消息可以被所有consumer消费,当没有消费者时,消息不会被保存

    JMS(java message service)是一个Java平台中关于面向消息中间件(MOM)的API,存在跨语言跨平台的缺陷,所以出现了AMQP

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!