zoukankan      html  css  js  c++  java
  • [译]rabbitmq 2.1 Consumers and producers (not an economics lesson)

    我对rabbitmq学习还不深入,这些翻译仅仅做资料保存,希望不要误导大家。

    For now, all you need to know is that producers create messages

    and label them for routing (see figure 2.1).

    现在需要知道的是,producer创建message和用于routing的label。

    Consumers are just as simple. They attach to a broker server and subscribe to a

    queue. Think of a queue as a named mailbox. Whenever a message arrives in a particular

    mailbox, RabbitMQ sends it to one of the subscribed/listening consumers. By the

    time a consumer receives a message, it now only has one part: a payload. The labels

    attached to the message don’t get passed along with the payload when the message is

    routed. RabbitMQ doesn’t even tell you who the producer/sender was. It would be

    like picking up your mail but all of the envelopes are blank. The only way to know a

    message is from your Aunt Millie is if she signed the letter inside. Similarly, if you need

    to know specifically who produced an AMQP message, it’s up to the producer to

    include that information as a part of the message payload.

    consumer较简单,连接到broker然后subscribed一个queue。可以把queue想象为一个mailbox。

    当一个消息到达指定的mailbox,rabbitmq把消息发送到subscribed/listening的consumer。

    这时consumer会收到这个消息,消息只包含一部分:payload。

    rabbtimq route 消息时,消息并不会包含label部分。

    rabbitmq不会告诉你消息的发送者是谁。

    如果你想知道message来自谁,你需要写在消息内容中。

    From the outside it’s simple: producers create messages and consumers receive

    them. Your app can be a producer when it needs to send a message to another app, or

    it can be a consumer when it needs to receive. It can also switch between the two. But

    before it can do either it has to set up a channel. Wait a minute … what’s a channel?

    你的app可以作为producer或者consumer,即收发消息,但是在这之前,你需要建立一个channel。

    Before you consume from or publish to Rabbit, you first have to connect to it. By

    connecting, you’re creating a TCP connection between your app and the Rabbit broker.

    Once the TCP connection is open (and you’re authenticated), your app then creates

    an AMQP channel. This channel is a virtual connection inside the “real” TCP

    connection, and it’s over the channel that you issue AMQP commands. Every channel

    has a unique ID assigned to it (your AMQP library of choice will handle remembering

    the ID for you). Whether you’re publishing a message, subscribing to a queue, or

    receiving a message, it’s all done over a channel. Why do we need channels, you might

    ask? Why not just issue AMQP commands directly over the TCP connection? 

    app成为consumer或者producer之前,必须连接。在连接时,会在app合broker之前建立一个TCP连接。

    当tcp连接被打开,app创建一个AMQP channel。

    channel是真实tcp连接中的虚拟channel,你发布的AMQP命令也是基于channel的。

    每个channel都会被分配一个唯一的ID。

    消息的发送、订阅、接收都是基于channel的。

    为什么需要基于channel,而不是通过tcp连接发送呢?

    The main reason is because setting up and tearing down TCP sessions is expensive for an

    operating system. Let’s say your app consumes messages from a queue and spins

    threads up or down based on service demand. If all you had were TCP connections,

    each thread would need its own connection to Rabbit, which could mean

    hundreds of connections per second during high load periods. Not only

    would this be a massive waste of TCP connections, but an operating system

    can only build so many per second. So you could quickly hit a performance

    wall. Wouldn’t it be cool if you could use one TCP connection for all of your threads for performance, 

    but get the same privacy

    as giving each thread its own connection? This is where a channel comes in. 

    主要原因是tcp的建立和拆除对于操作系统来说代价太高。

    假设你的app从queue中消费消息,线程的启停都基于服务需求,

    如果每个线程都建立一个tcp连接到rabbitmq服务器,

    这意味着高负载时,每秒钟会有几百个连接,

    但是一个操作系统每秒钟只能建立这么多连接。

    所以你很快就会遇到性能瓶颈。

    所以应该使用channel。

    As each thread spins up, it creates a channel on the existing connection and gets its own

    private communication path to Rabbit without any additional load on your operating

    system’s TCP stack, as in figure 2.2. As a result, you can create a channel hundreds or

    thousands of times a second without your operating system seeing so much as a blip.

    There’s no limit to how many AMQP channels you can have on one TCP connection.

    当每个线程启动时在已经存在的tcp连接上创建一个channel,获取他自己私有的

    通信路径并且不会给操作系统tcp栈增加负荷。

    因此,即使你每秒创建成百上千次channel,在操作系统看来也只是一个标志。

    一个TCP连接上,没有限制说只能创建多少个AMQP channel。

    Think of it like a bundle of fiber optic cable.

    Each fiber strand in the cable can transmit (just like a channel). But the cable has

    many fiber strands, allowing all the connected threads to transmit and receive simultaneously

    via multiple strands. A TCP connection is like the cable, and an AMQP channel

    is like an individual fiber strand.

    类似一束光缆。

    每根光缆中的纤维都可以用于传输(正如channel)。

    但是光缆有许多纤维,允许所有已连接的线程同时传输、接收。

    tcp连接就像光缆,AMQP channel就像其中的一根纤维。

    How about an example? Let’s say you’ve written a service for keeping track of valet

    parking, and everyone talks to it through RabbitMQ. Your service has to fulfill two

    tasks:

    1 Store valet ticket IDs and the associated parking space the car is in

    2 Return the parking space for any particular valet ticket ID

    来个例子:

    你在写一个服务来记录代客泊车的情况,每个人通过rabbitmq与你交互。

    你的服务需要实现2个任务:

    1.保存泊车票ID和对应的停车位置

    2.返回指定泊车票对应的停车位

    For the first task, your service is a consumer. It’s subscribed to a Rabbit queue waiting

    for “store ticket” messages with ticket IDs and parking space numbers inside. With the

    second task, your service is both a consumer and a producer. It needs to receive messages

    that tell it a particular valet ticket ID and then it needs to publish a response

    message with the associated parking space number.

    在第一个任务中,你的服务是consumer,订阅了消息,等待包含 泊车票ID 和 停车位置的 "存票"消息。

    在第二个任务中,你的服务是consumer和producer,当然受到一个指定的 泊车票ID后,返回停车位置消息。

    To fulfill the second task, your app is a producer. Once the connection to the

    RabbitMQ broker is open, your app creates multiple channels: chan_recv for the receiving

    thread and a chan_sendX (X being the thread number) channel for each reply

    thread. Using chan_recv, you set up a subscription to the queue that receives messages

    containing “ticket retrieval” requests. When a ticket retrieval message is received by

    your app over chan_recv, it looks up the ticket ID contained in the message. 

    为了实现第二个任务,你的app是一个producer,当与rabbitmq建链之后,你的app创建了多个channel:

    chan_recv - 接收线程channel

    chan_sendX(X代表线程号) -  答复线程channel

    利用chan_recv建立订阅来接收“票检索”请求,收到请求后,根据请求中的票ID进行查找。

    As soon as the associated parking space number has been identified, your app then creates a

    thread to send the response (letting the original thread continue to receive new

    requests). The new reply thread then creates a message containing the parking space

    number. Finally, the new thread labels the response message and publishes it to Rabbit

    using its chan_sendX channel. If your app had only one channel, 

    it wouldn’t be possible to share the TCP connection with the new reply threads.  

    当找到相关的信息,app创建一个线程chan_sendX来发送答复(不使用原来的线程,让原来的线程继续接收消息)。

    如果你的app只有一个channel,这个tcp连接就不能被多个线程共用。

    This would leave youwith two choices.

    Either use one connection and one thread—meaning your app

    couldn't process new ticket retrieval requests until it sent a response to the current

    one—or spawn a TCP connection for each sending thread, wasting TCP resources.

    With multiple channels, many threads can share the same connection simultaneously,

    meaning that responding to requests doesn’t block you from consuming new requests

    and you don’t waste a TCP connection for each thread. Sometimes you may choose to

    use only one channel, but with AMQP you have the flexibility to use as many channels

    as your app needs without the overhead of multiple TCP connections.

    这使得你有2个选择。

    使用一个tcp连接和一个线程,这意味着查询并回复之前,app无法处理一个新的查询请求,

    或者产生大量的tcp连接,浪费tcp的资源。

    使用多个channel,多个线程可以使用同一个tcp连接,

    这意味着答复动作并不会阻塞你的接收动作,并且不会浪费tcp连接。

    The important thing to remember about consumers and producers is that they map

    to the ideas of sending and receiving rather than client and server. Messaging in general,

    and AMQP in particular, can be thought of as an enhanced transport layer. With

    channels, you have the ability to create as many parallel transport layers as your app

    needs without being limited by TCP connection restrictions. When you understand

    these concepts, you can begin thinking of RabbitMQ as a router for your software.

    需要记住的是consumer和producer代表着接收和发送消息。

    通常的消息,特殊的AMQP,可以被看做加强版的消息传输层。

    有了channel,你可以创建很多平行的传输层,而不受tcp连接限制。

    理解了这些概念,你可以认为rabbitmq是软件的路由器。

  • 相关阅读:
    C++读取XML,开进程,开线程
    WinRT 异步模型
    记一个宣告失败的项目Metro VS2012RC的感性认识
    [翻译]深入理解Win32结构化异常处理(四)
    Google Test 测试架构探究
    .NET FrameWork 技术内幕
    [翻译]深入理解Win32结构化异常处理(三)
    谈一谈软件开发
    ExecutionContext & SynchronizationContext
    软件制作:QQPenguin辅助工具
  • 原文地址:https://www.cnblogs.com/solohac/p/4154178.html
Copyright © 2011-2022 走看看