rabbitMq 为什么不直接使用 TCP 发送消息,而是虚拟 channel?

新手上路,请多包涵

”对于OS来说,建立和关闭TCP连接是有代价的,频繁的建立关闭TCP连接对于系统的性能有很大的影响,而且TCP的连接数也有限制,这也限制了系统处理高并发的能力。但是,在TCP连接中建立Channel是没有上述代价的。“

上面这段话是很多技术文章写到的,也没具体的分析,我很纳闷,TCP连接可以保持长连接,如果不显示关闭,也不会断开呀,我们也可以直接发送消息,只要不断开TCP就行,这样不会出现频繁的建立关闭TCP连接带来的开销啊。而且channel 也是利用TCP,简单来说,不管你多个channel,始终是往一个socket上发送数据。除了channel有私密性以外。本质上为什么这样设置,如果只是系统消耗,好像说不过去。

 如果是http,我还能理解,一种request/response型的协议,为什么要做成request/response这种类型呢,因为server端要服务的client太多了,如果每一个连接都保持而不断开,那么服务器的资源很快就会被消耗完了。但是rabbitMQ有点理解不了。

如果哪位大神知道为什么,麻烦指点一下。### 问题描述

阅读 4.4k
3 个回答

不负责任地瞎猜一下,如果有错误请指正。
在erlang中每建立一个tcp连接必须启动一个进程去处理,不然这个代码就很难写,
而进程之间通信必须是拷贝的方式,rabbitmq中如果建立了多个tcp连接,将这些消息汇聚到一个消息队列的进程中的时候相当于把所有消息拷贝了一次。

如果我没理解错的话,这个只是多路复用而已吧,常规操作。你说的保持长连接不断开这个是另一种复用方式,缺点是后一个逻辑上的连接必须等到前一个连接结束后才能复用这个socket。RabbitMQ的多路复用我猜是跟http2或Socket.IO差不多的那种,多个逻辑上的连接(即channel)共用一个TCP socket,不需要等前一个连接结束,后一个连接即可插入,多个连接同时轮流使用同一个socket。缺点是需要实现帧封装,会有不小的开销,而且一堆连接都被绑在一个socket上,只要这个socket出问题,上面全部连接都得挂。

频繁开关TCP连接开销确实挺大的,高并发的情况下还是能省则省。

TCP的创建和销毁消耗太大,数据量多的时候会有极限值的瓶颈。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题