Active Queue/Topic 开发

ActiveMQ结合Spring开发 Queue

queue默认持久化到文件

1.引入相关依赖

pom:
	<dependency>
		<groupId>org.apache.activemq</groupId>
		<artifactId>activemq-spring</artifactId>
		<version>5.15.12</version>
	</dependency>
	<!--注册消息连接池相关类-->
	<dependency>
		<groupId>org.apache.activemq</groupId>
		<artifactId>activemq-pool</artifactId>
		<version>5.15.12</version>
	</dependency>
	<!--注册jms核心类-->
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-jms</artifactId>
		<version>5.2.5.RELEASE</version>
	</dependency>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-context</artifactId>
		<version>5.2.5.RELEASE</version>
	</dependency>

2.Spring配置

##配置Spring扫描
<context:component-scan base-package="testSpringActiveMQQueue"/>
##配置JMS工厂类,并指定Broker
    <bean id="jmsFactory" class="org.apache.activemq.pool.PooledConnectionFactory" destroy-method="stop">
        <property name="connectionFactory">
            <bean class="org.apache.activemq.ActiveMQConnectionFactory">
                <property name="brokerURL">
                    <value>tcp://192.168.28.130:61616</value>
                </property>
            </bean>
        </property>
    </bean>
##指定目的Queue,value值为Queue Name
    <bean id="destination-queue" class="org.apache.activemq.command.ActiveMQQueue">
        <constructor-arg index="0" value="activeMQ-spring-queue"/>
    </bean>
##JMS实现,并制定消息转换器
    <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
        <property name="connectionFactory" ref="jmsFactory"/>
        <property name="defaultDestination" ref="destination-queue"/>
        <property name="messageConverter">
            <bean class="org.springframework.jms.support.converter.SimpleMessageConverter"/>
        </property>
    </bean>

3.MessageProducer

@Service("messageProducer")
public class MessageProducer {

    @Autowired
    private JmsTemplate jmsTemplate;

    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        MessageProducer producer = (MessageProducer) ctx.getBean("messageProducer");
        for(int i=0;i<3;i++){
            producer.jmsTemplate.send(new MessageCreator() {
                public Message createMessage(Session session) throws JMSException {
                    MapMessage mapMessage= session.createMapMessage();
                    mapMessage.setString("msg:", "testMsg");
                    return  mapMessage;
                }
            });
        }
    }
}

4.MessageConsumer

@Service("messageCustomer")
public class MessageCustomer {
    @Autowired
    private JmsTemplate jmsTemplate;

    public static void main(String[] args) throws JMSException {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        MessageCustomer customer = (MessageCustomer) ctx.getBean("messageCustomer");
        for(int i=0;i<3;i++){
        MapMessage msg = (MapMessage) customer.jmsTemplate.receive();
        System.out.println(msg.getString("msg:"));
        }
        
    }
}

不足点:

上面的例子是使用了JMS的 receive()方法,但是一般不推荐使用此方法来接收消息。因为jms所有的调用都是同步的(Synchronized),这意味着调用需要线程被阻塞,直到方法返回结果,才能继续接收下一条消息,这对系统性能影响很大。

5.解决方案:

使用DefaultMessageListenerContainer,它允许异步(Asynchronized)接受消息,并且缓存session和消息consumer,而且还可以根据消息数量动态增加或缩减监听器的数量。

##在上面的内容添加如下配置
<bean id="messageListener" class="testSpringActiveMQQueue.MyMessageListener"/>

<bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
	<property name="connectionFactory" ref="jmsFactory"/>
	<property name="destination" ref="destination-queue"/>
	<property name="messageListener" ref="messageListener"/>
</bean>

6.MessageListener

public class MyMessageListener implements MessageListener {
    @Override
    public void onMessage(Message message) {
        MapMessage msg = (MapMessage) message;
        try {
            System.out.println(msg.getString("msg:"));
        } catch (JMSException e) {
            e.printStackTrace();
        }
    }
}

ActiveMQ结合Spring开发Topic

首先需要了解如下连个概念

1.非持久的Topic消息(NonPersistentTopic)

必须要求消费者在线,唯有消费者在线,生产者发送的消息,消费者才能接收到该消息。

2.持久的Topic消息(PersistentTopic)

必须先运行订阅者端,等于先向消息中间件注册该Topic的订阅者,然后运行发布者端,此时无论订阅者是否在线都可以接收到该消息,如果订阅者不在线,当订阅者下次连接时候,会自动接收到不在线期间的消息。(保证了消息的可靠性,消息不易丢失)

3.NonPersistentTopic原始方式

public class NonPersistentMessageConsumer {
    public static void main(String[] args) throws JMSException {
        ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://192.168.28.130:61616");
        Connection connection = connectionFactory.createConnection();
        connection.start();

        final Session session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);
        Topic myFirstNonPersistentTopic = session.createTopic("myFirstNonPersistentTopic");

        MessageConsumer consumer = session.createConsumer(myFirstNonPersistentTopic);
        int i = 0;
        while (i < 3) {
            i++;
            TextMessage message = (TextMessage) consumer.receive();
            session.commit();
            System.out.println("Message content:" + message.getText());
        }

        //close the resource
        session.close();
        connection.close();
    }
}


public class NonPersistentMessageProducer {
    public static void main(String[] args) throws JMSException, InterruptedException {
        ConnectionFactory connectionFactory=new ActiveMQConnectionFactory("tcp://192.168.28.130:61616");
        Connection connection = connectionFactory.createConnection();
        connection.start();

        Session session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);
        Topic myFirstNonPersistentTopic = session.createTopic("myFirstNonPersistentTopic");

        MessageProducer producer = session.createProducer(myFirstNonPersistentTopic);
        for(int i=1;i<3;i++){
            TextMessage textMessage = session.createTextMessage("Non Persistent Topic Message--"+i);
            Thread.sleep(1000);
            //use the producer to send the message
            producer.send(textMessage);
        }
        //commit the session
        session.commit();
        //close the resource
        session.close();
        connection.close();
    }
}


##消费者不在线时候,生产者产出的消息,消费者永远也接收不到

4.NonPersistentTopic结合Spring方式

Spring配置

<context:component-scan base-package="testSpringActiveMQTopic.NonPersistentTopic"/>
    <bean id="jmsFactory" class="org.apache.activemq.pool.PooledConnectionFactory" destroy-method="stop">
        <property name="connectionFactory">
            <bean class="org.apache.activemq.ActiveMQConnectionFactory">
                <property name="brokerURL">
                    <value>tcp://192.168.28.130:61616</value>
                </property>
            </bean>
        </property>
    </bean>

    <bean id="destination-topic" class="org.apache.activemq.command.ActiveMQTopic">
        <constructor-arg index="0" value="activeMQ-spring-NonPersistentTopic"/>
    </bean>

    <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
        <property name="connectionFactory" ref="jmsFactory"/>
        <property name="defaultDestination" ref="destination-topic"/>
        <property name="messageConverter">
            <bean class="org.springframework.jms.support.converter.SimpleMessageConverter"/>
        </property>
    </bean>
@Service("messageProducer")
public class MessageProducer {

    @Autowired
    private JmsTemplate jmsTemplate;

    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        MessageProducer producer = (MessageProducer) ctx.getBean("messageProducer");
        producer.jmsTemplate.send(new MessageCreator() {
            public Message createMessage(Session session) throws JMSException {
                MapMessage mapMessage= session.createMapMessage();
                mapMessage.setString("msg:","testMsg");
                return  mapMessage;
            }
        });
    }
}



@Service("messageCustomer")
public class MessageCustomer {
    @Autowired
    private JmsTemplate jmsTemplate;

    public static void main(String[] args) throws JMSException {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        MessageCustomer customer = (MessageCustomer) ctx.getBean("messageCustomer");
        MapMessage msg = (MapMessage) customer.jmsTemplate.receive();
        System.out.println(msg.getString("msg:"));
    }
}

同理使用messageListener替换jms的receive来接收消费者

##Spring配置上添加如下内容    
<bean id="messageListener" class="testSpringActiveMQTopic.NonPersistentTopic.MyMessageListener"/>

<bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
    <property name="connectionFactory" ref="jmsFactory"/>
    <property name="destination" ref="destination-NonPersistent-topic"/>
    <property name="messageListener" ref="messageListener"/>
</bean>
public class MyMessageListener implements MessageListener {
    @Override
    public void onMessage(Message message) {
        MapMessage msg = (MapMessage) message;
        try {
            System.out.println(msg.getString("msg:"));
        } catch (JMSException e) {
            e.printStackTrace();
        }
    }
}

5.PersistentTopic原始方式

##必须先运行订阅者端,向消息中间件中注册该Topic的订阅者

public class PersistentMessageSubscriber {
    public static void main(String[] args) throws JMSException {
        ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://192.168.28.130:61616");
        Connection connection = connectionFactory.createConnection();
        //******每个Subscriber都有一个固定的ClientId********//
        connection.setClientID("c1");

        final Session session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);
        Topic myFirstPersistentTopic = session.createTopic("myFirstPersistentTopic");
        //*******获得持久的Subscriber*********//
        TopicSubscriber subscriber1 = 
session.createDurableSubscriber(myFirstPersistentTopic, "t1");
        connection.start();

        int i = 0;
        while (i < 3) {
            i++;
            TextMessage message = (TextMessage) subscriber1.receive();
            session.commit();
            System.out.println("Message content:" + message.getText());
        }

        //close the resource
        session.close();
        connection.close();
    }
}


public class PersistentMessagePublisher {
    public static void main(String[] args) throws JMSException, InterruptedException {
        ConnectionFactory connectionFactory=new ActiveMQConnectionFactory("tcp://192.168.28.130:61616");
        Connection connection = connectionFactory.createConnection();

        Session session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);
        Topic myFirstPersistentTopic = session.createTopic("myFirstPersistentTopic");
        MessageProducer producer = session.createProducer(myFirstPersistentTopic);
        //******指定发布模式为持久模式******//
        producer.setDeliveryMode(DeliveryMode.PERSISTENT);
        connection.start();

        for(int i=1;i<3;i++){
            TextMessage textMessage = session.createTextMessage("Persistent Topic Message--"+i);
            Thread.sleep(1000);
            //use the producer to send the message
            producer.send(textMessage);
        }
        //commit the session
        session.commit();
        //close the resource
        session.close();
        connection.close();
    }
}

6.PersistentTopic结合Spring方式

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值