消息中间件MQ的使用

MQ的简介

    消息队列MQ本质上一种应用程序对应用程序的通信方法。是一种消息中间件。Active MQ 是JMS的一个具体实现,所以首先要对JMS有所了解。

JMS即Java消息服务(Java Message Service)应用程序接口,是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。Java消息服务是一个与具体平台无关的API,绝大多数MOM提供商都对JMS提供支持。

JMS的优势就是异步和可靠!

MQ的使用

去官网下载:http://activemq.apache.org/download.html

选择一个版本,根据自己电脑上的jdk版本,apache-activemq-5.15.0以后是1.8以上的版本

下载后解压到本地,在bin目录下win32和win64进入对应目录,用activemq.bat文件启动就可以了。(注意Activemq是依赖于JVM的,所以首先要搭好java环境)

在Maven项目中配置pom.xml

 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-activemq</artifactId>
 </dependency>

然后在application.properties中

spring.activemq.broker-url=tcp://172.24.225.122:61610
spring.activemq.username=admin
spring.activemq.password=admin
spring.activemq.in-memory=true
spring.activemq.pool.enabled=false
spring.activemq.packages.trust-all=true

这有两个比较重要的概念,即生产者和消费者。生产者是消息的发送者,消费者是消息接收者。Activemq的消息模式有点对点模式(Queue)和消息订阅模式(Topic)。


点对点:

扫描二维码关注公众号,回复: 1532033 查看本文章

1. 一个消息只能被一个服务接收;

2. 消息一旦被消费,就会消失;

3 . 如果没有被消费,就会一直等待,直到被消费;

4. 多个服务监听同一个消费空间,先到先得;

订阅模式:

1. 一个消息可以被多个服务接收;

2. 订阅一个主题的消费者,只能消费自它订阅之后发布的消息;

3. 消费端如果在生产端发送消息之后启动,是接收不到消息的,除非生产端对消息进行了持久化;

使用MQ的场景

在项目中,将一些无需即时返回且耗时的操作提取出来, 进行了异步处理,而这种异步处理的方式大大的节省了服务器 的请求响应时间,从而提高了系统的吞吐量。比如发邮件发短信,同步数据。

FAQ

1.服务挂掉
在传输数据时突然断电或服务挂掉,这时就涉及到数据持久化的问题。
解决方案:
打开安装目录下的配置文件:
D:\ActiveMQ\apache-activemq\conf\activemq.xml在越80行会发现默认的配置项:  

  <persistenceAdapter>
            <kahaDB directory="${activemq.data}/kahadb"/>
  </persistenceAdapter>
2.丢消息
报错javajava.net.SocketException异常
发送消息后调用close关闭连接,当接收方用read方法读取数据时,发送方由于已经close,报异常,当发生SocketException后,原本缓存区中数据也作废。
解决方案:用持久化消息,或者非持久化消息及时处理不要堆积,或者启动事务,启动事务后,commit()方法会负责任的等待服务器的返回,也就不会关闭连接导致消息丢失了
3.不均匀消费
多个相同的消费者消费一个生产者发送的消息,一个一直消费,其他却没有接收到任何消息。
这样就非常耗时。
原因就是ActiveMQ的prefetch机制。
当消费者去获取消息时,不会一条一条去获取,而是一次性获取一批,默认是1000条。
解决方案:将默认的prefetch设为1,每次处理1条消息,处理完再去取,这样也慢不了多少

4.消息阻塞

消息短时间内过多使目标空间已满会导致服务也挂掉
ActiveMQ默认的生产者发送的是Persistent message,这种消息的发送每次都需要等待broker给一个确认回复才能进行下一条消息的发送,这种可以在activemq.xml上设置流控,broker检测到目标空间已满时将会阻塞生产者。
解决方法:
  1.降低生产者的发送消息速度。
  2.提高消费者消费消息的速度。(可用多线程,多个消费者等)
  2. systemUsage设置sendFailIfNoSpace=true,空间满了会抛异常,
  服务里可以捕获这个异常,然后进行下一步业务操作



猜你喜欢

转载自blog.csdn.net/wuzhixiu007/article/details/80498105