略
对比AMQP和JMS可以发现,AMQP有很多的优势:
- AMQP为消息定义了线路层(wire-level protocll)的协议,而JMS使用了API规范;
- JMS规定了它的发送的消息被相同的JMS所使用,而AMQP可以给不同的AMQP来实现;
- AMQP甚至可以跨语言和平台,只要遵循了它的规范,都可以使用;
AMQP简介
JMS使用有三个角色:生产者,消费者,传递消息的通道.生产者和消费者解耦了,但是他们俩和通道依然存在耦合,这样一来通道就具有双重责任,既要传递消息,又要确保消息传递的目的地和方式.
AMQP与其不同,它的生产者不会直接把消息放到队列中.他在生产者和通道中加入了一个间接的机制:Exchange.
生产者会发消息给Exchange.Exchange会绑定到一个或多个队列上,它负责把消息路由到队列上,然后消费者从队列中取出数据并处理.
Exchange不仅仅是一个简单的中介,它也会有不同的处理路由的方法,AMQP定义了4个不同类型的Exchange,每个有不同的路由算法.根据算法不同,消息会被筛选的方式选择队列然后进入队列.四个标准的Exchange分别为:
- Direct: 如果消息的 routing key 与 binding 的 routing key 直接匹配,就会路由到这个队列上;
- Topic: 如果消息的 routing key 与 binding 的 routing key 符合通配符匹配的话,就会路由到这个队列上;
- Headers: 如果消息参数表中的头信息和值都与binding参数列表中匹配,就会路由到这个队列上;
- Fanout: 不管routing和头信息是啥,都会路由到所有的队列上;
根据Exchange的不同,可以设计出各种方式的路由模式,而不限于P2P(point-to-point)和发布/订阅模式,并且这些路由算法对于生产者和消费者的编写没有任何影响,唯一的注意的是:生产者发送消息给Exchange时会带一个runting key.
配置Spring支持AMQP
RabbitMQ实现了AMQP,SpringAMQP为RabbitMQ提供了支持,包括连接工厂,模板,命名空间
发送
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:rabbit="http://www.springframework.org/schema/rabbit" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/rabbit http://www.springframework.org/schema/rabbit/spring-rabbit.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<rabbit:connection-factory id="connectionFactory" host="127.0.0.1" port="5672" username="guest" password="guest"/>
<rabbit:admin connection-factory="connectionFactory"/>
<rabbit:queue id="myQueue1" name="myQueue1"/> <rabbit:queue id="myQueue2" name="myQueue2"/>
<rabbit:fanout-exchange name="myFanoutExchange"> <rabbit:bindings> <rabbit:binding queue="myQueue1"/> <rabbit:binding queue="myQueue2"/> </rabbit:bindings> </rabbit:fanout-exchange>
<rabbit:direct-exchange name="myDirectExchange"> <rabbit:bindings> <rabbit:binding queue="myQueue2" key="ab#"/> <rabbit:binding queue="myQueue1" key="#ab" exchange="myFanoutExchange"/> </rabbit:bindings> </rabbit:direct-exchange>
<rabbit:template id="template" connection-factory="connectionFactory"/>
</beans>
|
接收
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:rabbit="http://www.springframework.org/schema/rabbit" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/rabbit http://www.springframework.org/schema/rabbit/spring-rabbit.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:property-placeholder location="classpath*:rabbitmq.properties"/>
<rabbit:connection-factory id="connectionFactory" host="127.0.0.1" port="5672" username="guest" password="guest"/>
<rabbit:queue id="myQueue1" name="myQueue1"/>
<bean class="MyListener" id="listener"/>
<rabbit:listener-container connection-factory="connectionFactory"> <rabbit:listener ref="listener" method="myMethod" queues="myQueue1"/> </rabbit:listener-container>
</beans>
|
区别
RabbitMQ几乎与ActiveMQ的配置相同,下面列举一下区别:
- 发送端:RabbitMQ有Exchange需要配置,通过Exchange来连接每个队列,使用不同的Exchange效果不同,Exchange之间也可以互相连接在一起,可以通过Exchange来实现复杂的消息发布的方式.
- RabbitMQTemplate的send方法,需要传递三个参数,一是Exchange,二是routing key,三是发送的消息(注意要和消费者myMethod方法的参数一致).
- RabbitMQ的监听器中没有目的地属性,有一个queues属性可以配置监听的队列
其他方面RabbitMQ与ActiveMQ在Spring中的配置都一样.RabbitMQ就比ActiveMQ多了一个Exchange.