RabbitMQ随笔
不管是官方还是能搜到的文章,使用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的链接客户端和服务端链接过程(这个过程较为复杂,写了几遍都删了)得出如下结论:
- 先建立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之间就认为已经建立 了连接。
- 再建立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随笔的更多相关文章
- RabbitMQ系列随笔——介绍及安装
一.RabbitMQ介绍 RabbitMQ是由erlang开发的AMQP(Advanced Message Queuing Protocol)的开源实现.他是高级消息队列协议,是应用层协议的一个开放标 ...
- RabbitMQ 应用学习随笔
1.安装 Rabbit MQ 是建立在强大的Erlang OTP平台上,因此安装RabbitMQ之前要先安装Erlang. erlang:http://www.erlang.org/download. ...
- RabbitMQ消息队列随笔
本文权当各位看官对RabbitMQ的基本概念以及使用场景有了一定的了解,如果你还对它所知甚少或者只是停留在仅仅是听说过,建议你先看看这篇文章,在对RabbitMQ有了基本认识后,我们正式开启我们的Ra ...
- RabbitMQ原理与相关操作(二)
接着 上篇随笔 增加几个概念: RabbitMQ是一个在AMQP(高级消息队列协议)标准基础上完整的,可服用的企业消息系统. AMQP模型的功能组件图(上图摘自 Sophia_tj 的 第2章 AMQ ...
- RabbitMQ的安装
随笔记下Rabbit的环境搭建 1.下载RabbitMQ:RabbitMQ下载地址 Windows下安装 <1>安装Erlang 下载地址:Erlang下载 安装: Erlang安装完成 ...
- Java 小记 — RabbitMQ 的实践与思考
前言 本篇随笔将汇总一些我对消息队列 RabbitMQ 的认识,顺便谈谈其在高并发和秒杀系统中的具体应用. 1. 预备示例 想了下,还是先抛出一个简单示例,随后再根据其具体应用场景进行扩展,我觉得这样 ...
- 使用EasyNetQ组件操作RabbitMQ消息队列服务
RabbitMQ是一个由erlang开发的AMQP(Advanved Message Queue)的开源实现,是实现消息队列应用的一个中间件,消息队列中间件是分布式系统中重要的组件,主要解决应用耦合, ...
- RabbitMQ入门:认识并安装RabbitMQ(以Windows系统为例)
最近在学习Spring Cloud,其中消息总线Spring Cloud Bus是必不可少的,但是Spring Cloud Bus目前只支持RabbitMQ和kafka,因此学习RabbitMQ势在必 ...
- RabbitMQ入门:总结
随着上一篇博文的发布,RabbitMQ的基础内容我也学习完了,RabbitMQ入门系列的博客跟着收官了,以后有机会的话再写一些在实战中的应用分享,多谢大家一直以来的支持和认可. RabbitMQ入门系 ...
随机推荐
- EasyUI学习总结(三)——easyloader源码分析(转载)
声明:这一篇文章是转载过来的,转载地址忘记了,原作者如果看到了,希望能够告知一声,我好加上去! easyloader模块是用来加载jquery easyui的js和css文件的,而且它可以分析模块的依 ...
- C#中使用 SendMessage 向非顶端窗体发送组合键
开门见山,不废话了, 直接举例说明一下: 比如发送ALT + F 以下是 用spy++截取的消息内容 <00001> 000310DC P WM_SYSKEYDOWN nVirtKey:V ...
- EBS MOAC
alter session set nls_language='SIMPLIFIED CHINESE';alter session set nls_language ='AMERICAN'; exec ...
- verilog语法实例学习(12)
verilog中的综合和不可综合总结 Verilog中综合的概念 综合就是EDA工具或者说综合工具把我们编写的verilog代码转化成具体电路的过程.Verilog中有很多语法,结构,过程,语句,有些 ...
- Linux网络编程:socket文件传输范例
基于TCP流协议的socket网络文件传输Demo: 实现:C语言功能:文件传输(可以传任何格式的文件) /********************************************** ...
- C# CRC16 和汉明重量
最近在看redis之类的pdf,发现redis在做集群的时候,不同的key分到不同的主服务器,其中划分key的算法采用CRC16算法,所以特此整理一下其C#code如下: #region CRC16 ...
- 对linux安装中文字体库
问题描述: linux提供的web服务,能在网页展示中文,下载pdf出现中文无法读取!,甚是迷瞪,经分析展示是本地浏览器的解析,下载pdf是服务器端的响应,因此要在服务端安装对应的字体库就可以解决此问 ...
- keras 文本分类 LSTM
首先,对需要导入的库进行导入,读入数据后,用jieba来进行中文分词 # encoding: utf-8 #载入接下来分析用的库 import pandas as pd import numpy as ...
- SNF快速开发平台--规则引擎整体介绍及使用说明书
一.设计目标 a)规则引擎语法能够满足分单,计费,WMS策略的配置要求.语法是一致和统一的 b)能够在不修改规则引擎模块的情况下,加入任意一个新的规则:实现上述需求之外的规则配置需求 c)运算速度快 ...
- GuavaCache学习笔记一:自定义LRU算法的缓存实现
前言 今天在看GuavaCache缓存相关的源码,这里想到先自己手动实现一个LRU算法.于是乎便想到LinkedHashMap和LinkedList+HashMap, 这里仅仅是作为简单的复习一下. ...