How does RabbitMQ supports large number of virtual

2019-06-09 19:42发布

How does RabbitMQ supports large number of virtual connections in form of channels from a single TCP connection? Does the same optimization seen in other technologies? How does the pseudo-code to support multiple channels from a single TCP connection look like?

1条回答
何必那么认真
2楼-- · 2019-06-09 20:26

AMQP protocol declares in section 4.3 Channel Multiplexing:

AMQP permits peers to create multiple independent threads of control. Each channel acts as a virtual connection that share a single socket: frames frames frames frames

+-----------+-----------+-----------+-----------+
|  channel  |  channel  |  channel  |  channel  |
+-----------+-----------+-----------+-----------+
|                     socket                    |
+-----------------------------------------------+

Guidelines for implementers:

  • An AMQP peer MAY support multiple channels. The maximum number of channels is defined at connection negotiation, and a peer MAY negotiate this down to 1.

  • Each peer SHOULD balance the traffic on all open channels in a fair fashion. This balancing can be done on a per-frame basis, or on the basis of amount of traffic per channel. A peer SHOULD NOT allow one very busy channel to starve the progress of a less busy channel.

The simplest pseudo-code for channel multiplexing may looks like

struct DataFrame:
    int   channel_id 
    mixed payload    
    bool  is_last    

function receive(connection):

   DataFrame data

   while (connection->hasData()):
       if data is not set:
           data = connection->data_frame
       else if data->channel_id == connection->data_frame->channel_id:
           data->payload->append(connection->data_frame->payload)
       else:
           # handle data from other channels or ignore it

       if connection->data_frame->is_last:
           break

        return data->payload

function send(connection, DataFrame data):
    while data->payload:
        frame = cutSomeData(data, MAX_FRAME_SIZE)
        connection->send(frame)

        // note, in async way data may be sent when it become available or ready

It is very basic meta-code which doesn't handle data consuming from multiple channel at the same time, but I hope the idea is clear.

The similar optimization (for me it doesn't looks like optimization because there are caveats like connection level exception inside one channel) usually appears in high-level libraries, like websocket-multiplex and definitely in various RabbitMQ client libraries.

Also RTMP protocol (streaming video and audio in flash) uses channel multiplexing where various streams are sent via single connection:

Fragments from different streams may then be interleaved, and multiplexed over a single connection.

查看更多
登录 后发表回答