如果企业有很多部门,部门都有自己的系统,那么不同的系统之间的集成通信,Message Queue是很好的选择。
中间件比较
(1) kafka
编程语言:scala。
大数据领域的主流MQ。
(2) rabbitmq
编程语言:erlang
基于erlang语言,不好修改底层,不要查找问题的原因,不建议选用。
(3) rocketmq
编程语言:java
适用于大型项目。适用于集群。
(4) activemq
编程语言:java
适用于中小型项目。
====================================================系统之间直接调用存在的问题?
(1) *系统之间接口耦合比较严重*
(2) *面对大流量并发时,容易被冲垮*
(3) *等待同步存在性能问题*
*MQ的主要作用*
(1) 异步。调用者无需等待。
(2) 解耦。解决了系统之间耦合调用的问题。
(3) 消峰。抵御洪峰流量,保护了主业务。
防火墙
centos7:
systemctl status firewalld.service
systemctl stop firewalld.service
61616端口提供JMS服务
8161端口提供管理控制台服务
ip:8161
admin/admin
./activemq start/stop 普通启动
lsof -i:61616
netstat -anp|grep 61616
JMS的组成结构:
- JMS Provider
- JMS Producer
- JMS Consumer
- JMS Message
(消息头、消息属性、消息体)
JMS的消息头有哪些属性:
JMSDestination:消息目的地
JMSDeliveryMode:消息持久化模式
JMSExpiration:消息过期时间
JMSPriority:消息的优先级
JMSMessageID:消息的唯一标识符。后面我们会介绍如何解决幂等性。
说明: 消息的生产者可以set这些属性,消息的消费者可以get这些属性。
这些属性在send方法里面也可以设置。
5种消息体
- TextMessage
- MapMessage
- BytesMessage
- StreamMessage
- ObjectMessage
消息属性
识别/去重/重点标注等操作非常有用的方法
topic消息持久化
topic默认就是非持久化的,因为生产者生产消息时,消费者也要在线,这样消费者才能消费到消息。
topic消息持久化,只要消费者向MQ服务器注册过,所有生产者发布成功的消息,该消费者都能收到,不管是MQ服务器宕机还是消费者不在线。
注意:
\1. 一定要先运行一次消费者,等于向MQ注册,类似我订阅了这个主题。
\2. 然后再运行生产者发送消息。
\3. 之后无论消费者是否在线,都会收到消息。如果不在线的话,下次连接的时候,会把没有收过的消息都接收过来。
事务性
设置了事务之后,send之后,要commit之后才能收到数据。
保证出错可以回滚,一错全不能提交等等。
*消息的签收机制*
***签收的几种方式*
① 自动签收(Session.AUTO_ACKNOWLEDGE):该方式是默认的。该种方式,无需我们程序做任何操作,框架会帮我们自动签收收到的消息。
② 手动签收(Session.CLIENT_ACKNOWLEDGE):手动签收。该种方式,需要我们手动调用Message.acknowledge(),来签收消息。如果不签收消息,该消息会被我们反复消费,只到被签收。
③ 允许重复消息(Session.DUPS_OK_ACKNOWLEDGE):多线程或多个消费者同时消费到一个消息,因为线程不安全,可能会重复消费。该种方式很少使用到。
④ 事务下的签收(Session.SESSION_TRANSACTED):开始事务的情况下,可以使用该方式。该种方式很少使用到。
事务优先级比签收高,开启事务提交消息则自动签收
ActiveMQ支持的client-broker通讯协议有:TVP、NIO、UDP、SSL、Http(s)、VM。其中配置Transport Connector的文件在ActiveMQ安装目录的conf/activemq.xml中的标签之内。
个人说明:除了tcp和nio协议,其他的了解就行。各种协议有各自擅长该协议的中间件,工作中一般不会使用activemq去实现这些协议。如: mqtt是物联网专用协议,采用的中间件一般是mosquito。ws是websocket的协议,是和前端对接常用的,一般在java代码中内嵌一个基站(中间件)。stomp好像是邮箱使用的协议的,各大邮箱公司都有基站(中间件)。
注意:协议不同,我们的代码都会不同。
JDBC方式,mysql开启了允许了非本地访问还是start失败,不知道为什么
消息存储使用一个事务日志和仅仅用一个索引文件来存储它所有的地址。
① 异步发送可以让生产者发的更快。
② 如果异步投递不需要保证消息是否发送成功,发送者的效率会有所提高。如果异步投递还需要保证消息是否成功发送,并采用了回调的方式,发送者的效率提高不多,这种就有些鸡肋。
***具体哪些情况会引发消息重发*
① Client用了transactions且再session中调用了rollback
② Client用了transactions且再调用commit之前关闭或者没有commit
③ Client再CLIENT_ACKNOWLEDGE的传递模式下,session中调用了recover