消息队列核心JMS,让面试官对你刮目相看!
上回说到
小二上回把activeMQ以及落地实战代码给大家讲了一讲,上传的文件不知为何会自己涨金币(****不知道搞什么鬼????)需要的可以跟我说一句,我重新传一下就可以了。
还没有入门MQ的可以看看上回文章:mq入门
JMS
上回说到,咱们JavaEE是一套用Java进行企业级应用开发的遵循的13个核心规范工业标准。我们的JMS(Java message service)就是其中一个,指两个应用程序之间进行异步通信的api,为标准消息协议和消息服务提供了一组通用接口,包括创建,发送,读取等等。
很好理解,就是字面意思,相当于JMS可以提供我们在两个应用程序进行通信的一些api。
JMS组成和特点
组成
- JMS Provider :实现JMS接口和规范的消息中间件,就是MQ服务器(常见的ActiveMQ,RabbitMQ等等)
- JMS Producer:消息生产者,创建和发送JMS消息的客户端应用,就是我们程序会产生消息放到服务器。
- JMS Consumer:消息消费者,接收和处理消息的客户端应用,就是从服务器拿消息出来处理的。
解读:我们有服务器,相当于一家工厂;有生产者,相当于做产品的工人;有消费者,相当于把产品拿出去卖的人。那么组成就是类似这些,所以最重要的还是这个“产品”是什么,这才是其特点,也就是JMS的消息。
JMS Message
首先,消息(Message)包含:消息头,消息体,消息属性。
具体了解一下
消息头:
- JMSDestination:消息发送目的地,主要指Queue和Topic,可以为每一条消息指定目的地。意思是我们在生产消息的时候可以设定哪条消息放到Queue,哪条放到Topic。
- JMSDeliveryMode:持久和非持久模式。持久的消息只会被传送一次,也就是说如果提供者出现故障时,消息不会丢失,会在服务器恢复后再次传递消息。非持久的消息最多传送一次,出现故障后会永远丢失。
- JMSExpiration:设置消息过期时间,默认是永不过期。
- JMSPriority:消息优先级,从0-9十个级别,0-4是普通消息,5-9是加急消息,默认4级。这里的级别其实也就只有普通和加急之分,保证加急优先普通到达就行。
- ????JMSMessageID:唯一识别每个消息的标识,它由MQ产生,也可以自定义,在分布式环境使用全局ID设置MessageID,可以根据MessageID去查询消息是否重复消费。
消息体
- TextMessage:普通字符串消息,就是个String
- MapMessage:一个Map类型的消息,key为String类型,value为基本类型
- BytesMessage:二进制数组消息,是一个byte[]
- StreamMessage:Java的流,用标准操作来顺序填充或读取
- ObjectMessage:对象消息,就是个可序列化的Java对象
小二插一句:我们封装具体的消息数据时,发送和接收的消息体类型必须一致对应,不能出错喔!
消息属性
- 当需要设置除消息头字段外的值时,可以使用消息属性。比如以键值对的形式设置,如setStringProperty(String key,String value)
JMS可靠性
上面说了那么多JMS特点和组成的东西,那么我们来讨论一下为什么要使用JMS?它到底有什么好?
对于JMS的可靠性,我们可以从三个方面来讲:持久性,事务,签收
首先是持久性,也是最常见易懂的一个。
- 在使用持久化时,服务器即使宕机,消息依然还是存在的。
- 在非持久化时,服务器宕机后,消息就不存在了,持久化就是比如我们使用常用的kehaDB,将消息持久到这个数据库中,具体怎么操作的以后有时间再教大家。非持久化就是消息在内存中。
- Queue队列默认是持久化传送,Topic主题的持久化是生产者设置持久化传送,消费者使用订阅方式TopicSubscriber。
然后是事务,事务偏生产者,签收偏消费者。
- 如果事务设置为false,那只要执行send发送就进入了队列中了。
- 如果设置为true,那么会先执行send发送,再执行session.commit()方法,消息才会被真正提交到队列中。
最后是签收机制,为了保证咱发出去的消息对方能收到,我们有一个相应的签收机制,然而它与事务又有一定的关联。
- 在非事务情况下,默认是自动签收,也就是Session.AUTO_ACKNOWLEDGE。
- 设置为手动签收Session.CLIENT_ACKNOWLEDGE时,消费者需要调用acknowledge()方法进行签收。
- 当设置了Session.DUPS_OK_ACKNOWLEDGE时,我们就允许重复去签收了。
- 在有事务的情况下,事务的作用域是大于签收的,事务提交后,手动签收不调用acknowledge()方法时,也可以完成签收。
- 事务如果没有提交,即使自动签收也无效,这时会导致重复消费。
他们俩的关系是这样的:
在事务性会话中,当一个事务被成功提交,那么消息会自动签收。如果事务回滚,那么消息会被再次传送。
在非事务性会话中,消息被确认的时刻取决于创建会话时的应答模式(acknowledge mode)
还有一个Broker,它可以被看成消息转发器。在ActiveMQ中,使用的就是用代码去启动,它是一个嵌入式的,代码很少,比起之前的生产者和消费者的那种JMS方式简单许多!
对比来说,Broker嵌入了一个免安装版的mq,让我们不用下载mq也能使用。
看,就这么多代码!但是对于这种Broker来说,开发中一般也不会使用。
JMS就讲到这,虽然代码很少,但是干货满满,让你在面试官面前多一份自信!非常下饭!