RabbitMQ 应用一
(百度百科)MQ全称为Message Queue,消息队列(MQ)是一种应用程序对应用程序的通信方法。应用程序通过读写出入队列的消息(针对应用程序的数据)来通信,而无需专用连接来链接它们。消息传递指的是程序之间通过在消息中发送数据进行通信,而不是通过直接调用彼此来通信,直接调用通常是用于诸如远程过程调用的技术。排队指的是应用程序通过 队列来通信。队列的使用除去了接收和发送应用程序同时执行的要求。其中较为成熟的MQ产品有IBM WEBSPHERE MQ等等。
一个项目架构,小的时候,一般都是传统的单一网站系统,或者项目,三层架构,到现在的MVC架构。随着用户访问量越来越多,系统业务越来越多,会出现以下问题:
1.修改完大量代码后,不敢更新,因为都是集成在一起,互相耦合性非常高,一处报错,满盘皆挂;
2.整个项目文件夹,层级越来越多,对新来的同事很不友好,文件不可避免的会乱放,重复的过多,甚至为了紧急更新,会把很多原本的需要编译的代码,挪到一般处理程序中,更有甚将.cs文件代码前置到.aspx页面来躲避编译
时间越长,越会发现,整个代码结构像一锅粥一样;
3.会有很多地方需要记录日志、邮件、短信等等很多需要异步的操作,如果访问量过高,会把这个系统拖垮。
上述问题出现一定时间后,一定会重构整个,进行业务分离,SOA架构服务化,这就涉及到多个应用相互之间的通信,常见的方式,是通过API的方式进行数据交互。
这种做法实时性很高,但是对单个业务系统的高峰期压力还是非常大的,需要对业务API系统进行负载均衡,这时候,如果说把一些无需及时返回且耗时的操作,提取出来,进行异步处理的话,消息队列就派上用场了,而这种异步处理的方式大大的节省了服务器的请求响应时间,引入的消息队列就成了消息处理的缓冲区。消息队列引入的异步通信机制,使得发送方和接收方都不用等待对方返回成功消息,就可以继续执行下面的代码,从而提高了数据处理的能力。尤其是当访问量和数据流量较大的情况下,就可以结合消息队列与后台任务,通过避开高峰期对大数据进行处理,就可以有效降低数据库和程序处理数据的负荷。
文章有点长,请跟着步骤一点一点的操作,会发现趣味无穷,别气馁!gogo
一 搭建环境
RabbitMq是由Erlang语言开发,所有到先安装Erlang语言的环境,传送门Erlang安装教程,安装成功后,默认安装后会自动配置一个环境变量ERLANG_HOME ,如果没配置的话,手动配置一下,指向Erlang安装目录就可以了。
安装好Erlang语言环境,我们去下载RabbitMq服务了。地址 http://www.rabbitmq.com/download.html,下载RabbitMq Server。(rabbitmq-server-3.6.11 安装包)
下载完,安装完毕后,打开安装目录到sbin下
路径 C:\Program Files\RabbitMQ Server\rabbitmq_server-3.6.11\sbin
我们右键CMD,用管理员身份打开,然后切到上图这个目录下,执行3行命令
rabbitmq-service install
rabbitmq-service enable
rabbitmq-service start
开启rabbitMq的服务,这时候可以自己查看服务是否开启。
安装好以后,我们使用rabbitmqctl list_users命令,是列出当前服务用户的列表,
刚开始的时候是默认有一个用户guest
我们可以自己添加用户,并且设置密码,设置权限,设置管理员操作,还可以删除用户,更改密码
rabbitmqctl add_user yekai yekaiwudi 添加用户,账号yekai,密码yekaiwudi
rabbitmqctl set_permissions yekai ".*" ".*" ".*" 给yekai这个用户设置对所有消息队列设置和配置,读,写的权限
rabbitmqctl set_user_tags feige administrator 给yekai这个用户设置成管理员
rabbitmqctl delete_user yekai 这个是删除用户
rabbitmqctl change_password yekai yekaigogo 修改yekai的密码
运行下面命令来启用管理插件:rabbitmq-plugins enable rabbitmq_management
默认端口:http://localhost:15672/#/
打开后用刚才设置的账号密码登录,登录成功的页面就是可以监控的后台
综上,RabbitMq的环境已经部署完毕,一些基本命令已经熟悉了,下面开始使用
二 基本使用
在.NET中使用RabbitMQ需要下载RabbitMQ的客户端程序集,可以到官网下载,下载解压后就可以得到RabbitMQ.Client.dll,这就是RabbitMQ的客户端。
在使用RabitMQ之前,需要对下面的几个基本概念说明一下:
RabbitMQ是一个消息代理。他从消息生产者(producers)那里接收消息,然后把消息送给消息消费者(consumer)在发送和接收之间,他能够根据设置的规则进行路由,缓存和持久化。
如果用VS2012+,可以直接从nuget控制台命令,进行添加
Install-Package RabbitMq.Client -version 3.6.5
由于主源中还没有version 3.6.11版本,因此我们添加 version 3.6.5
生产(Producing)意思就是发送,发送消息的程序就是一个生产者(producer)。
队列(queue)就是邮箱的名称。消息通过你的应用程序和RabbitMQ进行传输,它们只能存储在队列(queue)中。 队列(queue)容量没有限制,你要存储多少消息都可以——基本上是一个无限的缓冲区。多个生产者(producers)能够把消息发送给同一个队列,同样,多个消费者(consumers)也能从同一个队列(queue)中获取数据。
消费(Consuming)和获取消息是一样的意思。一个消费者(consumer)就是一个等待获取消息的程序,如下图
通常,消息生产者、消息消费者和消息代理不在同一台机器上。
下面,我们用.net代码,来分别做一个制造者,发送消息的控制台,一个消费者,接收消息的控制台,当然,我们在本机做一下实验。
/// <summary>
/// 消息生产者,客户端消息存入队列中
/// </summary>
class Program
{
static void Main(string[] args)
{
// 1、创建链接工厂,设置目标、用户、密码
RabbitMQ.Client.ConnectionFactory factory = new RabbitMQ.Client.ConnectionFactory();
factory.HostName = "127.0.0.1";
factory.UserName = "yekai";
factory.Password = "yekaigogo"; // 2、开启当前服务设置的用户的链接
using (var connection = factory.CreateConnection())
{
// 链接开启一个频道
using (var channel = connection.CreateModel())
{
// 创建一个队列
// 参数说明:队列名,是否持久化,是否唯一,是否自动删除,参数列表
channel.QueueDeclare("firstQueue", false, false, false, null);
byte[] body = null; // 消息主体
// 消息是以二进制数组的形式传输的,所以如果消息是实体对象的话,需要序列化然后转化为二进制数组
for (int i = ; i < ; i++)
{
body = System.Text.Encoding.UTF8.GetBytes(string.Format("这是第------{0}------条消息",i));
// 发布消息
channel.BasicPublish("", "firstQueue", null, body); Console.Write("成功发送第-----" + i + "-----条消息!");
}
Console.ReadKey();
}
}
}
}
上述是消费者控制台代码,我下面那个循环时测试的10W条数据,不断的发送和另一个控制台不断的获取消息,测试下来还不错性能。。。这个例子发送的消息比较简单,直接转成二进制就可以了,但是如果我们
用到对象的话,就要先反序列化,再转成二进制。
当队列中有数据的话,用rabbitmqctl list_queues,可以列出所有队列名称,和队列中的消息数量
接下来我们再编写一个消费者端
/// <summary>
/// 消息消费者,读取消息队列中的数据
/// </summary>
class Program
{
static void Main(string[] args)
{
// 1、创建链接工厂,设置目标、用户、密码
RabbitMQ.Client.ConnectionFactory factory = new RabbitMQ.Client.ConnectionFactory();
factory.HostName = "127.0.0.1";
factory.UserName = "yekai";
factory.Password = "yekaigogo"; // 记录用时,开始记录时间
System.Diagnostics.Stopwatch myWatch = new System.Diagnostics.Stopwatch();
myWatch.Start();
// 2、开启当前服务设置的用户的链接
using (var connection = factory.CreateConnection())
{
// 链接开启一个频道
using (var channel = connection.CreateModel())
{
// 连接到指定队列
// 参数说明:队列名,是否持久化,独占的queue,不使用时是否自动删除,其他参数
channel.QueueDeclare("firstQueue", false, false, false, null); // 定义消息接受者
var customer = new RabbitMQ.Client.QueueingBasicConsumer(channel);
// 从指定队列获取数据
channel.BasicConsume("firstQueue", true, customer);
// 开始不断循环出队列的消息
while (true)
{
RabbitMQ.Client.Events.BasicDeliverEventArgs basicDeliverEventArgs = customer.Queue.Dequeue();
// 将消息二进制转回字符串
string msg = Encoding.UTF8.GetString(basicDeliverEventArgs.Body);
Console.WriteLine(msg);
}
}
}
//停止记录时间
myWatch.Stop();
//显示运行时间
Console.WriteLine(myWatch.Elapsed + "共用时" + myWatch.ElapsedTicks + "毫秒" + myWatch.ElapsedMilliseconds);
}
}
运行的消息生产者客户端后,往队列firstQueue中发送了10W条消息,我们再运行消费者端。
可见,队列firstQueue中的消息正在不断取出,而且速度很快。
这些是一些RabbitMq的一些基本使用,后面会陆续增加深入的学习心得。
eg:虽然说使用消息队列一定程度上缓解了系统的耦合度,但是弊端也很严重,假如RabbitMq的服务器出现问题,消息队列写入不进去,那么发送客户端根本无法控制,在这期间的数据丢失怎么恢复?如下图
欢迎探讨
RabbitMQ 应用一的更多相关文章
- 消息队列——RabbitMQ学习笔记
消息队列--RabbitMQ学习笔记 1. 写在前面 昨天简单学习了一个消息队列项目--RabbitMQ,今天趁热打铁,将学到的东西记录下来. 学习的资料主要是官网给出的6个基本的消息发送/接收模型, ...
- RabbitMq应用二
在应用一中,基本的消息队列使用已经完成了,在实际项目中,一定会出现各种各样的需求和问题,rabbitmq内置的很多强大机制和功能会帮助我们解决很多的问题,下面就一个一个的一起学习一下. 消息响应机制 ...
- 如何优雅的使用RabbitMQ
RabbitMQ无疑是目前最流行的消息队列之一,对各种语言环境的支持也很丰富,作为一个.NET developer有必要学习和了解这一工具.消息队列的使用场景大概有3种: 1.系统集成,分布式系统的设 ...
- RabbitMq应用一的补充(RabbitMQ的应用场景)
直接进入正题. 一.异步处理 场景:发送手机验证码,邮件 传统古老处理方式如下图 这个流程,全部在主线程完成,注册->入库->发送邮件->发送短信,由于都在主线程,所以要等待每一步完 ...
- RabbitMq应用一
RabbitMq应用一 RabbitMQ的具体概念,百度百科一下,我这里说一下我的理解,如果有少或者不对的地方,欢迎纠正和补充. 一个项目架构,小的时候,一般都是传统的单一网站系统,或者项目,三层架构 ...
- 缓存、队列(Memcached、redis、RabbitMQ)
本章内容: Memcached 简介.安装.使用 Python 操作 Memcached 天生支持集群 redis 简介.安装.使用.实例 Python 操作 Redis String.Hash.Li ...
- 消息队列性能对比——ActiveMQ、RabbitMQ与ZeroMQ(译文)
Dissecting Message Queues 概述: 我花了一些时间解剖各种库执行分布式消息.在这个分析中,我看了几个不同的方面,包括API特性,易于部署和维护,以及性能质量..消息队列已经被分 ...
- windows下 安装 rabbitMQ 及操作常用命令
rabbitMQ是一个在AMQP协议标准基础上完整的,可服用的企业消息系统.它遵循Mozilla Public License开源协议,采用 Erlang 实现的工业级的消息队列(MQ)服务器,Rab ...
- RabbitMQ + PHP (三)案例演示
今天用一个简单的案例来实现 RabbitMQ + PHP 这个消息队列的运行机制. 主要分为两个部分: 第一:发送者(publisher) 第二:消费者(consumer) (一)生产者 (创建一个r ...
- RabbitMQ + PHP (二)AMQP拓展安装
上篇说到了 RabbitMQ 的安装. 这次要在讲案例之前,需要安装PHP的AMQP扩展.不然可能会报以下两个错误. 1.Fatal error: Class 'AMQPConnection' not ...
随机推荐
- IDEA一些自动补全方式
第一种:系统自带:可以CTRL + j 可以查看 psvm 也就是public static void main的首字母. 依次还有在方法体内键入for会有一个fori的提示,选中然后tab键,就会自 ...
- org.slf4j:slf4j-api:添加日志管理
org.slf4j:slf4j-api:添加日志管理 转 https://blog.csdn.net/wolfking0608/article/details/77855624 一个好的程序, 完 ...
- osgearth 编译日志
1>------ 已启动生成: 项目: ZERO_CHECK, 配置: Debug x64 ------1> Checking Build System1> CMake does n ...
- Spring cloud微服务安全实战-6-4权限控制改造
授权,权限的控制 令牌里的scope包含fly就有权限访问.根据Oauth的scope来做权限控制, 要让@PreAuthorize生效,就要在启动类里面写一个注解. 里面有一个属性叫做,就是在方法的 ...
- html div高度100%无效
移动端相关: div高度继承自父元素——>body——>html 解决方案: html,body { height: 100%;margin: 0; padding: 0;} 然后对应的d ...
- __proto__和prototype的一些理解
var Person = function(name) { this.name = name; } var p = new Person(); new操作符的操作是 var p = {} p.__pr ...
- CSS网站框架及样式命名规范
CSS网站框架 复位:reset.css 基础:base.css 或 basic.css (字体大小.颜色.背景.行高.列表样式.按钮样式.表格样式等等) 布局:layout.css (非结构的布局) ...
- consul分布式集群搭建&简单功能测试&故障恢复【h】
环境准备五台机器: 操作系统 IP Ubuntu 16.04.3 LTS x86_64 192.168.1.185 Ubuntu 16.10 x86_64 192.168.3.152 Ubuntu 1 ...
- 【VS开发】从sockaddr中取得客户端或者数据源的Ip地址和端口号
在socket编程中,服务器端accept()等待一个客户端的连接,当连接成功后,accept拷贝客户端的地址信息到sin_addr里面,我们如何从sin_addr取得此客户端的Ip地址和端口号呢? ...
- va_start(),va_end()函数应用
原理解释: VA_LIST 是在C语言中解决变参问题的一组宏,在<stdarg.h>头文件下. VA_LIST的用法: (1)首先在函数里定义一具VA_LIST型的变 ...