【消息中间件JMS java message service】ActiveMQ

名词解释

Broker

消息服务器,作为server提供消息核心服务

应用场景

异步通行

把同步任务转为异步任务

异构

消费者生产者可以用不同语言实现

过载保护

可以熔断保护

缓冲

把大量的生产者产生的数据,放在mq中,消费者可以慢慢处理

解耦

生产者做生产者的事情,消费者做消费者的事情。可以各自扩容和修改

冗余

MQ把queue数据一直持久化,一直到消费才会删除

扩展性

消费者和生产者可以各自扩容

可恢复性

系统的一部分挂掉,另外的系统不影响,因为信息在MQ中

顺序保证

queue是有顺序的,FIFO

数据流处理

ActiveMQ的安全机制

WEB网页权限

访问的时候需要有账号密码,在jetty.xml中配置

访问activeMQ密码

在acivteMQ.xml中增加插件,配置密码

持久化

持久化默认是放到file中,但是可以通过配置,放到数据库中,内存中等等,如果放到数据库中,则可以做到持久化,重启也不会丢失数据。

事务

// 开启事务
Session session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
// 可以批量提交
session.commit();
// try catch 可以回滚
session.rollback():

高级API

监听器

采用监听器去处理数据,可以避免线程阻塞。

 consumer.setMessageListener(new MessageListener() {
            @Override
            public void onMessage(Message message) {
                try {
                    System.out.println(((TextMessage) message).getText());
                } catch (JMSException e) {
                    e.printStackTrace();
                }
            }
        });

send object msg

需要在接受端增加信任列表

// 设置trust列表
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(ActiveMQConnectionFactory.DEFAULT_USER, ActiveMQConnectionFactory.DEFAULT_PASSWORD,
                "tcp://0.0.0.0:61616");
factory.setTrustedPackages(Lists.newArrayList(Object.class.getPackage().getName()));
 // 其他正常操作即可

死信队列

当provider发送信息到mq之中,但是没有客户端消费,这些信息会保存在内存中。当信息超时后,会进入死信队列。provider可以拿到死信队列中的数据,进行再次投递,成为***重投***

默认只有持久化msg才会进入死信队列

 // 设置超时,超时后进入死信队列
        producer.setTimeToLive(1000);

消息延迟投递

在配置文件中配置schedulerSupport=true,接着在代码中

  textMessage.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, 10 * 1000);

重复投递

textMessage.setIntProperty(ScheduledMessage.AMQ_SCHEDULED_REPEAT, 10);

等待投递

textMessage.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_PERIOD, 10);

消息选择器

可以有类似sql的写法,session.createConsumer(queue, “type=1 AND groupSize >1”);
like '李%四‘

客户端只会消费当前选择器选择的msg
生产者,设置额外属性

textMessage.setLongProperty("week", 1);

消费者,指定选择器

MessageConsumer consumer = session.createConsumer(queue, "week=1");

独占消费

选择器的一种
设置之后,只要客户端拿到一个队列后,其他客户端都拿不到了

Queue queue = session.createQueue("HelloWorld?consumer.exclusive=true");

消息的优先级

可以打乱消费数据。
需要在配置文件中,开启优先级策略

消息发送时的同步异步

在这里插入图片描述

Queue

ACK的几种模式

  • Session.AUTO_ACKNOWLEDGE:当客户成功的从recive方法返回的时候,或者从MessageListener.onMessage方法成功返回的时候,会话会自动确认客户收到的消息
  • Session.CLIENT_ACKNOWLEDGE:客户通过消息的acknowagledge方法确认。这种确认会一次性确认该次会话消费的所有的消息。(当客户端收到消息之后没有立刻ack或者宕机了,别的客户端就可以收到该条消息)
  • Session.DUPS_OK_ACKNOWLEDGE:

开始事物模式,在一个客户端消费的数据,没有comit的时候,发送端也会hold住,不给其他人消费。但当持有的客户端关闭,其他客户端就可以拿到

message info

TOPIC

高级使用

queue brower

只能浏览,不参与消费

JMSCorrelationId

用于消息之间的关联,给人会话的感觉。reply to只有地址,不知道是哪条的回复,所以用这个属性。

Message.setJMSCorrelationId

queueRequestor

完全的同步消息。发送端发送消息给broker,并且创建一个temp queue,且用阻塞方法reviver()去等待消息。接收端收到信息后,从reply to中获得temp queue地址,然后发送消息给temp queue

preFetchSize

consumer端的缓冲区大小,建立connectionFactory或者queue,topic时候,指定prefetchSize的条数。当broker推送的消息并且没有接到ack的消息,大于这个条数的时候,就不推送了。
如果没有设置,则是consumer主动去broker拉取消息

高可用(主备)

同时起两个broker,但是用一个db fild,只会有一个broker抢到db的锁,此时其他broker会启动阻塞。当抢到锁的broker挂掉,其他的broker就会拿到锁,启动成功

高性能集群

静态网络配置

通过actviemq.xml的配置文件,配置 networkConnectors,则2个broker可以互相访问。
此时注意:queue尽量从对应的broker获取数据,不要利用集群的broker从目标queue所在的broker拉取数据,很消耗io。这种方式针对topic的效果最佳

动态网络配置

通过multicast协议,配置networkConnectors,并且在transportConnectors中配置discoverUri。通过udp协议自动发现。

常见问题

  • 如何保证消费顺序:
    • queue就是顺序的
  • 如何防止不丢数据:
    • 做高可用
    • 死信队列
    • 持久化
    • ack
    • 消息重投
    • 记录日志
    • 消费确认,reply to
    • broker负载/限流
    • 检查独占消费者
  • 如何防止重复消费
    • 消息幂等处理,用map或者concurrentHashMap的putIfAbsent方法(如果没有才会往map里面put)。注意别内存溢出,可以替代map用guava的cahe,弄ttl超时
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
好的,我可以为您提供一个简单的示例。 首先,您需要在SpringBoot项目中添加ActiveMQ的依赖。在pom.xml文件中添加以下代码: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-activemq</artifactId> </dependency> ``` 然后,您需要在application.properties文件中配置ActiveMQ的连接信息,如下所示: ```properties spring.activemq.broker-url=tcp://localhost:61616 spring.activemq.user=admin spring.activemq.password=admin ``` 接下来,您需要创建一个消息队列,用于存储要发送的邮件信息。在SpringBoot中,可以使用JmsTemplate来发送消息。您可以在您的Java代码中注入JmsTemplate,然后使用它来发送邮件消息。以下是一个示例代码: ```java import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jms.core.JmsTemplate; import org.springframework.stereotype.Service; @Service public class EmailService { @Autowired private JmsTemplate jmsTemplate; public void sendEmail(String to, String message) { jmsTemplate.convertAndSend("email.queue", new Email(to, message)); } } ``` 在上面的代码中,我们注入了JmsTemplate,并使用它来发送一个Email对象到名为“email.queue”的消息队列中。 最后,您需要编写一个消息监听器,用于监听邮件队列中的消息,并实现邮件发送逻辑。以下是一个示例代码: ```java import org.springframework.jms.annotation.JmsListener; import org.springframework.stereotype.Component; @Component public class EmailListener { @Autowired private JavaMailSender mailSender; @JmsListener(destination = "email.queue") public void sendEmail(Email email) { SimpleMailMessage message = new SimpleMailMessage(); message.setTo(email.getTo()); message.setSubject("Test Email"); message.setText(email.getMessage()); mailSender.send(message); } } ``` 在上面的代码中,我们使用@JmsListener注解来监听名为“email.queue”的消息队列中的消息,并实现了邮件发送逻辑。 最后,您需要确保ActiveMQ服务器已经启动,然后运行您的SpringBoot应用程序即可。 希望这个示例对您有帮助!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值