RabbitMQ如何通过单个TCP连接以通道的形式支持大量虚拟连接?在其他技术中看到了相同的优化吗?如何从单个TCP连接支持多个通道的伪代码如何?
答案 0 :(得分:1)
AMQP协议在4.3 Channel Multiplexing部分声明:
AMQP允许对等方创建多个独立的控制线程。 每个通道充当共享单个套接字的虚拟连接: 帧帧帧
+-----------+-----------+-----------+-----------+ | channel | channel | channel | channel | +-----------+-----------+-----------+-----------+ | socket | +-----------------------------------------------+
实施者指南:
AMQP对等体可以支持多个通道。最大通道数在连接协商时定义,并且对等端可以 将此协商为1。
每个对等方应该以合理的方式平衡所有开放渠道的流量。这种平衡可以基于每帧进行,也可以基于 每个频道的流量基础。同行不应该允许 一个非常繁忙的频道,让一个不太繁忙的频道的进展挨饿。
用于通道复用的最简单的伪代码可能看起来像
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
这是非常基本的元代码,它不能同时处理来自多个频道的数据消费,但我希望这个想法很清楚。
类似的优化(对我而言,它看起来不像优化,因为在一个通道中存在类似连接级别异常的警告)通常出现在高级库中,例如websocket-multiplex,并且肯定会出现在各种RabbitMQ客户端中库。
同样RTMP protocol (streaming video and audio in flash)使用通道复用,其中通过单个连接发送各种流:
然后可以交错来自不同流的片段 通过单一连接进行多路复用。