rabbitmq 学习-6-rabbitmq基础

rabbitmq 学习-6-rabbitmq基础  

2010-04-27 23:31:05|  分类: rabbitmq|字号 订阅

rabbitmq的中文资料真少,和同事lucas经过两周的学习,讨论,测试,终于搞清了部分rabbitmq的知识,先总结一下

1,Connection

连接,与rabbitmq server建立的一个连接,由ConnectionFactory创建,虽然创建时指定 了多个server address,但每个connection只与一个物理的server进行连接,此连接是基于Socket进行连接的,这个可以相似的理解为像一个DB Connection

ConnectionParameters params = new ConnectionParameters();

params.setUsername(userName);

params.setPassword(password);

params.setVirtualHost(virtualHost);

params.setRequestedHeartbeat(0);

ConnectionFactory factory = new ConnectionFactory(params);

Connection conn = factory.newConnection(hostName,

AMQP.PROTOCOL.PORT);


2,Channel

建立在connection基础上的一个通道,相对于connection来说,它是轻量级的。可以这样理解,它就像是hibernate里面的session一样,相对于DB Connection来说,session就是一个轻量级的东西。

Channel channel = conn.createChannel();

注:尽量避免在多线程中使用一个channelChannel javadoc有如下说明:

While a Channel can be used by multiple threads, it's important to ensure

that only one thread executes a command at once. Concurrent execution of

commands will likely cause an UnexpectedFrameError to be thrown.

另官方Java Client API Guide里面也同样提到

     Channel thread-safety

In general, Channel instances should not be used by more than one thread simultaneously: application code should maintain a clear notion of thread ownership for Channel instances. If more than one thread needs to access a particular Channel instance, the application should enforce mutual exclusion itself, for example by synchronising on the Channel.

Symptoms of incorrect serialisation of Channel operations include, but are not limited to,de>IllegalStateExceptionde>s with the message "cannot execute more than one synchronous AMQP command at a time", and de>UnexpectedFrameErrorde>s.


3,Exchange,Queue,RoutingKey

先看下面一张图

rabbitmq 学习-6-rabbitmq基础_第1张图片

蓝色-- Client(相对于Rabbitmq Server来说)

绿色--Exchange

红色—Queue

     - 交换器(Exchange),它是发送消息的实体。

     - 队列(Queue),这是接收消息的实体。

     - 绑定器(Bind),将交换器和队列连接起来,并且封装消息的路由信息。

Exchange指向Queue的黑色线—RoutingKey,可以将它简单的理解为一条连接ExchangeQueue的路线

ExchangeQueue都需要通过channel来进行定义,而RoutingKey则只需要在binding时取个名字就行了。

这一块的理解是不正确的,具体参见 rabbitmq 学习-8- Exchange Queue RoutingKey关系说明

左边的Client向右边的Client发送消息,流程:

1,  获取Conection

2,  获取Channel

3,  定义ExchangeQueue

4,  使用一个RoutingKeyQueue Binding到一个Exchange

5,  通过指定一个Exchange和一个RoutingKey来将消息发送到对应的Queue上,

6,  接收方在接收时也是获取connection,接着获取channel,然后指定一个Queue直接到它关心的Queue上取消息,它对ExchangeRoutingKey及如何binding都不关心,到对应的Queue上去取消息就OK

一个Client发送消息,哪些Client可以收到消息,其核心就在于ExchangeRoutingKeyQueue的关系上。

 

Exchange

RoutingKey

Queue

1

E1

R1

Q1

2

 

R2

Q2

3

E2

R3

Q1

4

 

R4

Q2

5

E1

R5

Q1

6

E2

R6

Q1

我们可以这样理解,RoutingKey就像是个中间表,将两个表的数据进行多对多关联,只不过对于相同的ExchangeQueue,可以使用不同的RoutingKey重复关联多次。

 注:本人现在使用的是rabbitmq server 1.7.2,它使用的AMQP 0.8协议,最新的1.0里面有些东西有变化,比如Exchange type,1.0里面还有个system

Exchange在定义的时候是有类型的,以决定到底是哪些Queue符合条件,可以接收消息

Exchange Type 说明

fanout

所有bind到此exchangequeue都可以接收消息

direct

通过routingKeyexchange决定的那个唯一的queue可以接收消息

topic

所有符合routingKey(此时可以是一个表达式)routingKeybindqueue可以接收消息

表达式符号说明:#代表一个或多个字符,*代表任何字符

例:#.a会匹配a.aaa.aaaa.a

*.a会匹配a.ab.ac.a

注:使用RoutingKey为#,Exchange Type为topic的时候相当于使用fanout

headers


你可能感兴趣的:(rabbitmq 学习-6-rabbitmq基础)