In previous parts of the tutorial we knew nothing about exchanges, but still were able to send messages to queues. That was possible because we were using a default exchange, which we identify by the empty string ("").
在教程的之前部分我们对交换机还一无所知,但这并不妨碍我们能够发送消息到队列中,这之所以成为可能,是因为我们使用了基于空字符串来标识的默认交换机。
Recall how we published a message before:
回忆一下以前我们是如何发布消息的:
var message = GetMessage(args); var body = Encoding.UTF8.GetBytes(message); channel.BasicPublish(exchange: "", routingKey: "hello", basicProperties: null, body: body);The first parameter is the the name of the exchange. The empty string denotes the default or nameless exchange: messages are routed to the queue with the name specified by routingKey, if it exists.
第一个参数就是交换机的名字。空字符串表示默认的或者匿名的交换机:根据明确的路由键(routingKey)将消息路由到已存在的队列。
Now, we can publish to our named exchange instead:
现在,我们用具名(自定义命名)的交换机来进行发布:
var message = GetMessage(args); var body = Encoding.UTF8.GetBytes(message); channel.BasicPublish(exchange: "logs", routingKey: "", basicProperties: null, body: body); Temporary queues 临时队列As you may remember previously we were using queues which had a specified name (remember hello and task_queue?). Being able to name a queue was crucial for us -- we needed to point the workers to the same queue. Giving a queue a name is important when you want to share the queue between producers and consumers.
你可能还记得之前我们使用过指定名称的队列(记得好像是 hello 和 task_queue?)。能够为队列命名对我们来说是至关重要的 -- 我们需要将工作单元指向相同的队列。同样,当你想在生产者和消费者之间共享队列时,为队列赋予一个名字也是非常重要的。
But that's not the case for our logger. We want to hear about all log messages, not just a subset of them. We're also interested only in currently flowing messages not in the old ones. To solve that we need two things.
但是,以上并不是我们日志系统的案例。我们想要监听所有的日志消息,而不仅仅是它们的一部分。我们只对当前正在流动的消息感兴趣,而不是旧的消息,为解决这个问题我需要做好两件事。
Firstly, whenever we connect to Rabbit we need a fresh, empty queue. To do this we could create a queue with a random name, or, even better - let the server choose a random queue name for us.
首先,无论我们何时连接到 Rabbit,都需要一个崭新的、空的队列,为做到这一点我们可以使用随机名称来创建一个队列,当然更好的做法是,让服务端为我们选择一个随机名称。
Secondly, once we disconnect the consumer the queue should be automatically deleted.
其次,一旦我们与消费者断开连接,相关的队列也应当能自动删除。
In the .NET client, when we supply no parameters to queueDeclare() we create a non-durable, exclusive, autodelete queue with a generated name:
在 .NET 客户端中,当我们调用 queueDeclare 方法而并未提供任何参数时,实际上就是创建了一个非持久化、独享,且自动删除的具名队列。
var queueName = channel.QueueDeclare().QueueName;At that point queueName contains a random queue name. For example it may look like amq.gen-JzTY20BRgKO-HjmUJj0wLg.
在此处 queueName 包含的是一个随机队列名称,比如它看起来可能像 amq.gen-JzTY20BRgKO-HjmUJj0wLg。
Bindings 绑定We've already created a fanout exchange and a queue. Now we need to tell the exchange to send messages to our queue. That relationship between exchange and a queue is called a binding.
我们已经创建了一个 fanout 型交换机和队列,现在我们需要告诉交换机把消息发送到队列,那么,交换机和队列之间的关系就被称作绑定。
channel.QueueBind(queue: queueName, exchange: "logs", routingKey: "");From now on the logs exchange will append messages to our queue.
从现在开始,日志交换机将会把消息追加到队列中。
Listing bindings 列举绑定You can list existing bindings using, you guessed it:
你可以列举出现有的绑定,(所使用的命令)你该可以猜到:
rabbitmqctl list_bindings Putting it all together 融合一起