AMQP协议

 

AMQP协议

AMQP协议是一个异步消息传递所使用的应用层协议规范。又可以称为消息中间件协议。它是定义一个标准的接收及发送机制。它包括消息的路由(exchange)和缓存(queue)两个主要部分。

1.体系结构:

Producer-client---> exchange-->queue ---->Consumer-client

中间的exchange、queue就是AMQP定义的server也叫broker。

         Exchange接收消息生产者(Message Producer)发送的消息并根据不同的路由算法将消息发送往不同的Message queue。Message queue会在消息不能被正常消费时缓存这些消息,当message queue与消息消费者(Message consumer)之间的连接通畅时,Message queue将把消息转发给consumer。

         Message是当前模型中所操纵的基本单位,它由Producer产生,经过Broker被Consumer所消费。它的基本结构有两部分: Header和Body。Header是由Producer添加上的各种属性的集合,这些属性有控制Message是否可被缓存,接收的queue是哪个,优先级是多少等。Body是真正需要传送的数据,它是对Broker不可见的二进制数据流,在传输过程中不应该受到影响。

         一个broker中会存在多个Message queue,Exchange怎样知道它要把消息发送到哪个Message queue中去呢? 这就是由路由算法决定的,并由bind实现。Message queue的创建是由client Application控制的,在创建Message queue后需要确定它来接收并保存哪个Exchange路由的结果。Binding是用来关联Exchange与Message queue的域模型。即把这个queue接受哪种消息的条件绑定到Exchange,这个条件也叫Binding key 或是 Criteria。

         当一个Exchange与多个Message queue关联后,Exchange中就会存在一个路由表,这个表中存储着每个Message queue所需要消息的限制条件。Exchange就会检查它接受到的每个Message的Header及Body信息,来决定将Message路由到哪个queue中去。Message的Header中应该有个属性叫Routing Key,它由Message发送者产生,提供给Exchange来路由这Message。Exchange根据不同的Exchange Type,来选择路由算法。比如有Direct类型,需要Binding key 等于Routing key;topic则是Binding key与Routing key符合一个模式关系。一些基础的路由算法由AMQP所提供,client application也可以自定义各种自己的扩展路由算法。

Binding key是由consumer在binding Exchange与Queue时决定的,而Routing key是由producer指定。而它们的匹配方式是由exchange TYPE决定的。

 

2.通信方式:

client与virtual host建立connection;

然后可以在该conn上建立多个channel进行并发运行;

channel是用于传输client与broker的命令及消息的实体;

在通信的时候会为每个command分配一个惟一标识符(可以是一个UUID),是为了在传输过程中可以对command做校验和重传。

客户端默认使用guest/guest访问权限和访问虚拟主机的根目录,这些默认项也是RabbitMQ的默认安装选项。

通过rabbitmqctl查看具体的信息

 

3.Exchange  TYPE:

direct[default exchange]

routing-key == binding-key。 every queue that is created is automatically bound to it[direct exchange] with a routing key which is the same as the queue name.

For example, when you declare a queue with the name of "search-indexing-online", the AMQP broker will bind it to the default exchange using "search-indexing-online" as the routing key. Therefore, a message published to the default exchange with the routing key "search-indexing-online" will be routed to the queue "search-indexing-online". In other words, the default exchange makes it seem like it is possible to deliver messages directly to queues, even though that is not technically what is happening.

注:我试了一下,好像不行还是得自己再去调用bind指令

图1

从这个图可以看到一个消息可以被发送到多个queue,只要它们与exchange binding时使用的bindkey相同就可以。

 

fanout

A fanout exchange routes messages to all of the queues that are bound to it and the routing key is ignored(可以不用写). If N queues are bound to a fanout exchange, when a new message is published to that exchange a copy of the message is delivered to all N queues. Fanout exchanges are ideal for the broadcast routing of messages. [广播]

 

topic

用于模式匹配分析消息的routing-key属性。它将routing-key和binding-key的字符串切分成单词。这些单词之间用点隔开。它同样也会识别两个通配符:#匹配0个或者多个单词,*匹配一个单词。例如,binding key *.stock.#匹配routing key usd.stcok和eur.stock.db,但是不匹配stock.nasdaq。[多播]

Topic exchange is powerful and can behave like other exchanges.When a queue is bound with "#" (hash) binding key - it will receive all the messages, regardless of the routing key - like in fanout exchange.When special characters "*" (star) and "#" (hash) aren't used in bindings, the topic exchange will behave just like a direct one.

 

Header

A headers exchange is designed to for routing on multiple attributes that are more easily expressed as message headers than a routing key. Headers exchanges ignore the routing key attribute. Instead, the attributes used for routing are taken from the headers attribute. A message is considered matching if the value of the header equals the value specified upon binding.

 

4.实体属性

exchange属性

- durable:持久性,broker重启后依然有效不需要重要声明

- auto-delete:自动删除,如果启用,那么交换器将会在其绑定的队列都被删除掉之后自动删除掉自身。

 

queue属性

- durable:持久性,broker重启后依然有效

- auto-delete:自动删除,如果启用那么队列将会在所有的消费者停止使用之后自动删除掉自身。

- exclusive: 排他性,队列只能被声明它的消费者(connection)使用。

Before a queue can be used it has to be declared. Declaring a queue will cause it to be created if it does not already exist. The declaration will have no effect if the queue does already exist and its attributes are the same as those in the declaration. When the existing queue attributes are not the same as those in the declaration a channel-level exception with code 406 (PRECONDITION_FAILED) will be raised.

Queue names starting with "amq." are reserved for internal use by the broker. Attempts to declare a queue with a name that violates this rule will result in a channel-level exception with reply code 403 (ACCESS_REFUSED).

Note that only durable queues can be bound to durable exchanges. This guarantees that it is possible to restore bindings on broker restart.

Durability of a queue does not make messages that are routed to that queue durable. If broker is taken down and then brought back up, durable queue will be re-declared during broker startup, however, only persistent messages will be recovered.

 

Message属性

Content type

Content encoding

Routing key

Delivery mode (persistent or not) :which makes AMQP broker persist them to disk.

Message priority

Message publishing timestamp

Expiration period

Producer application id

Note on message persistence

Marking messages as persistent doesn't fully guarantee that a message won't be lost. Although it tells RabbitMQ to save message to the disk, there is still a short time window when RabbitMQ has accepted a message and hasn't saved it yet. Also, RabbitMQ doesn't do fsync(2) for every message -- it may be just saved to cache and not really written to the disk. The persistence guarantees aren't strong, but it's more than enough for our simple task queue. If you need a stronger guarantee you can wrap the publishing code in a transaction.

If AMQP message cannot be routed to any queue (for example, because there are no bindings for the exchange it was published to) it is either dropped or returned to the publisher, depending on message attributes the publisher has set. 通过设置消息的 mandatory和/或immediate属性为真。

 

通过rabbitmqctl工具可以查看各个实体的相应属性,如:

[xiangzhong.wxd@my031092 rabbitmq-server]$ sudo scripts/rabbitmqctl list_exchanges name type  durable  auto_delete internal

Listing exchanges ...

amq.direct                  direct   true    false   false

amq.topic                  topic    true    false   false

amq.rabbitmq.trace        topic    true    false   false

amq.rabbitmq.log     topic    true    false   false

amq.fanout                 fanout   true    false   false

amq.headers               headers  true    false   false

                                    direct    true    false   false

amq.match                headers  true    false   false

...done.

 

5.消息投递的保障机制

消费者会显式或者隐式地通知消息的使用完毕。当隐式地通知的时候,消息被认为在投递之后便被消耗掉。否则客户端需要显式地发送一个验证信息。只有这个验证信息收到之后,消息才会被认为已经收到并且从队列中删除。如果没有收到,那么broker会在通道关闭之前尝试着重新投递消息。

If consumer dies without sending an ack, RabbitMQ will understand that a message wasn't processed fully and will redeliver it to another consumer. That way you can be sure that no message is lost, even if the workers occasionally die.

【上面的东西大多从官网上找的,也懒得翻译】

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值