不管是官方还是能搜到的文章,使用MQ的基本思路都是这样:

        static void Main(string[] args)
{
//通过工厂建立连接
using (IConnection connection = factory.CreateConnection())
{
//通过连接创建会话,这里还有可能是Channel
using (ISession session = connection.CreateSession())
{
while (true)或者一个for 循环发送100万个消息
{
//创建一个msg
string message = "Hello World";
//发送
xxx.Send(message);
}
}
}
}

那么问题来了:

这个"Hello World"怎么传进去?如何对外提供服务?

然后会发现有些客户端SDK是这么处理的:

       public static void SendMsg()
{
MQAPI("Hello World");
} private static void MQAPI(string message)
{
IConnectionFactory factory;
//通过工厂建立连接
using (IConnection connection = factory.CreateConnection())
{
//通过连接创建Session会话
using (ISession session = connection.CreateSession())
{
//创建一个msg
string message = message; //发送
xxx.Send(message);
}
}
}

去公开一个接口调用SendMsg吧。

看起来似乎解决了这个问题,但是实际测试下会吓一跳:后者的QPS仅为前者的40%左右,这是不能容忍的。

那么接下来大家肯定会从SQLConnection的经验得出一个解决方案:

将connection抽出来,那么session或者Channel呢?

我们通过研究RabbitMQ的链接客户端和服务端链接过程(这个过程较为复杂,写了几遍都删了)得出如下结论:

  1. 先建立Connection链接,这个链接就是一个TCP链接,Producer和Consumer都是通过TCP连接到RabbitMQ Server 的。经过connection.start -> connection.start_ok -> connection.secure -> connection.secure_ok -> connection.tune -> connection.tune_ok(这时rabbit会建立一个心跳进程)-> connection.open -> connection.open_ok后,客户端与rabbit之间就认为已经建立 了连接。
  2. 再建立Channels: 虚拟连接。它建立在上述的TCP连接中。数据流动都是在Channel中进行的。也就是说,一般情况是程序起始建立TCP连接,第二步就是建立这个Channel。可以多路复用,1~65535为可用的channel编号,channel的索引不为0时(0是全局链接),rabbit认为这些数据从属于某个 channel。如果该channel进程不 存在,则会创建一个channel进程,并由此进程负责该channel上 的所有数据。根据AMQP协议,经过channel.open -> channel.open_ok后,客户端就可以开始在该channel上发送数据了。

那么,建立和关闭TCP连接是有代价的,频繁的建立关闭TCP连接对于系统的性能有很大的影响,而且TCP的连接数也有限制,这也限制了系统处理 高并发的能力。但是,在TCP连接中建立 Channel是没有上述代价的。对于Producer或者Consumer来说,可以并发的使用多个 Channel进行 Publish或者Receive。

然而我研究了RabbitMQ.Client代码之后发现其并未维护一个连接池:

                if (AutomaticRecoveryEnabled)
{
var autorecoveringConnection = new AutorecoveringConnection(this, clientProvidedName);
autorecoveringConnection.Init(endpointResolver);
conn = autorecoveringConnection;
}
else
{
IProtocol protocol = Protocols.DefaultProtocol;
conn = protocol.CreateConnection(this, false, endpointResolver.SelectOne(this.CreateFrameHandler), clientProvidedName);
}

只是有一个自动恢复功能,需要设置为true建立长TCP链接,然后根据在请求的时候再创建Channel。

RabbitMQ随笔的更多相关文章

  1. RabbitMQ系列随笔——介绍及安装

    一.RabbitMQ介绍 RabbitMQ是由erlang开发的AMQP(Advanced Message Queuing Protocol)的开源实现.他是高级消息队列协议,是应用层协议的一个开放标 ...

  2. RabbitMQ 应用学习随笔

    1.安装 Rabbit MQ 是建立在强大的Erlang OTP平台上,因此安装RabbitMQ之前要先安装Erlang. erlang:http://www.erlang.org/download. ...

  3. RabbitMQ消息队列随笔

    本文权当各位看官对RabbitMQ的基本概念以及使用场景有了一定的了解,如果你还对它所知甚少或者只是停留在仅仅是听说过,建议你先看看这篇文章,在对RabbitMQ有了基本认识后,我们正式开启我们的Ra ...

  4. RabbitMQ原理与相关操作(二)

    接着 上篇随笔 增加几个概念: RabbitMQ是一个在AMQP(高级消息队列协议)标准基础上完整的,可服用的企业消息系统. AMQP模型的功能组件图(上图摘自 Sophia_tj 的 第2章 AMQ ...

  5. RabbitMQ的安装

    随笔记下Rabbit的环境搭建 1.下载RabbitMQ:RabbitMQ下载地址 Windows下安装 <1>安装Erlang 下载地址:Erlang下载 安装: Erlang安装完成 ...

  6. Java 小记 — RabbitMQ 的实践与思考

    前言 本篇随笔将汇总一些我对消息队列 RabbitMQ 的认识,顺便谈谈其在高并发和秒杀系统中的具体应用. 1. 预备示例 想了下,还是先抛出一个简单示例,随后再根据其具体应用场景进行扩展,我觉得这样 ...

  7. 使用EasyNetQ组件操作RabbitMQ消息队列服务

    RabbitMQ是一个由erlang开发的AMQP(Advanved Message Queue)的开源实现,是实现消息队列应用的一个中间件,消息队列中间件是分布式系统中重要的组件,主要解决应用耦合, ...

  8. RabbitMQ入门:认识并安装RabbitMQ(以Windows系统为例)

    最近在学习Spring Cloud,其中消息总线Spring Cloud Bus是必不可少的,但是Spring Cloud Bus目前只支持RabbitMQ和kafka,因此学习RabbitMQ势在必 ...

  9. RabbitMQ入门:总结

    随着上一篇博文的发布,RabbitMQ的基础内容我也学习完了,RabbitMQ入门系列的博客跟着收官了,以后有机会的话再写一些在实战中的应用分享,多谢大家一直以来的支持和认可. RabbitMQ入门系 ...

随机推荐

  1. Netty重要概念介绍

    Netty重要概念介绍 Bootstrap Netty应用程序通过设置bootstrap(引导)类开始,该类提供了一个用于网络成配置的容器. 一种是用于客户端的Bootstrap 一种是用于服务端的S ...

  2. Go语言之高级篇beego框架之模型(Models)

    一.模型(Models) 1.beego-orm的相关特性 支持 Go 的所有类型存储 -轻松上手,采用简单的 CRUD 风格 -自动 Join 关联表 跨数据库兼容查询 允许直接使用 SQL 查询/ ...

  3. 微信小程序- 提示不在以下合法域名列表中

    第一次开发微信小程序时在访问后台数据时总是提示 提示上面问题主要有两个原因: 1.为配置安全合法域名列表: 微信小程序在开发时需要在官网配置固定的数据来源网站: 登录小程序平台中->设置: 图中 ...

  4. 修改覆盖springboot默认日志策略logback

    目录 背景 自定义 背景 springboot初始化了日志的默认实现,只要我们在配置文件添加对应的配置即可. 比如 logging: file: logs/application-debug.log ...

  5. iSpy免费的开源视频监控平台

    iSpy包括英文,Deutsch,Español,Française,Italiano和中文的翻译 iSpy是我们免费的开源视频监控平台.iSpy作为安装的Windows应用程序运行,具有完整的本地用 ...

  6. stingray中使用angularjs

    引入angularjs 手动启用angularjs 不使用ng-app, 在所有模块和controller定义后挂载启用angularjs function OnLoad() { scroll(0, ...

  7. 周期同步位置模式(CSP),轮廓位置模式(PPM),位置模式(PM)

    什么是运动控制? 运动控制就是通过机械传动装置对运动部件的位置.速度进行实时的控制管理,使运动部件按照预期的轨迹和规定的运动参数(如速度.加速度参数等)完成相应的动作. 运动控制系统的典型构成 1. ...

  8. pycharm调整代码长度分割线

    1.File ->  Settings  ->  Code Style -> Right margin (columns) 的值为80,大功告成. 2.具体设置的数值可以根据个人电脑 ...

  9. 训练集测试集划分 train_test_split(X, y, stratify=y)

    from sklearn.model_selecting import train_test_spilt() 参数stratify: 依据标签y,按原数据y中各类比例,分配给train和test,使得 ...

  10. 【转载】ssh-keygen 基本用法

    [转载]ssh-keygen 基本用法 原文地址:https://www.liaohuqiu.net/cn/posts/ssh-keygen-abc/ ssh 公钥认证是ssh认证的方式之一.通过公钥 ...