RabbitMQ消息队列应用

 消息通信组件Net分布式系统的核心中间件之一,应用与系统高并发,各个组件之间解耦的依赖的场景。本框架采用消息队列中间件主要应用于两方面:一是解决部分高并发的业务处理;二是通过消息队列传输系统日志。目前业界使用较多的消息队列组件有RabbitMQ、ActiveMQ、MSMQ、kafka、zeroMQ等,本文对系统架构之MQ Component诠释,并采用RabbitMQ作为消息队列中间件。

图1- 消息队列组件示意图


一、RabbitMQ介绍

  RabbitMQ是一款基于AMQP(消息队列协议),由Erlang开发的开源消息队列组件。是一款优秀的消息队列组件,他由两部分组成:服务端和客户端,客户端支持多种语言的驱动,如:.Net、JAVA、Erlang等。RabbitMQ与其他消息队列组件性能比较,在此不作介绍,网上有大把的资料。


二、RabbitMQ原理简介

图2- RabbitMQ结构示意图

  RabbitMQ中间件分为服务端(RabbitMQ Server)和客户端(RabbitMQ Client),服务端可以理解为是一个消息的代理消费者,客户端又分为消息生产者(Producer)和消息消费者(Consumer)。

  1、消息生产者(Producer):主要生产消息并将消息基于TCP协议,通过建立Connection和Channel,将消息传输给RabbitMQ Server,对于Producer而言基本就完成了工作。

  2、服务端(RabbitMQ Server):主要负责处理消息路由、分发、入队列、缓存和出列。主要由三部分组成:Exchange、RoutingKey、Queue。

    (1)Exchange:用于接收消息生产者发送的消息,有三种类型的exchange:direct, fanout,topic,不同类型实现了不同的路由算法;

    A. direct exchange:将与routing key 比配的消息,直接推入相对应的队列,创建队列时,默认就创建同名的routing key。

    B. fanout exchange:是一种广播模式,忽略routingkey的规则。

    C. topic exchange:应用主题,根据key进行模式匹配路由,例如:若为abc*则推入到所有abc*相对应的queue;若为abc.#则推入到abc.xx.one ,abc.yy.two对应的queue。

    (2)RoutingKey:是RabbitMQ实现路由分发到各个队列的规则,并结合Binging提供于Exchange使用将消息推送入队列;

    (3)Queue:是消息队列,可以根据需要定义多个队列,设置队列的属性,比如:消息移除、消息缓存、回调机制等设置,实现与Consumer通信;

  3、消息消费者(Consumer):主要负责消费Queue的消息,同样基于TCP协议,通过建立Connection和Channel与Queue传输消息,一个消息可以给多个Consumer消费;

  4、关键名词说明:Connection、Channel、Binging等;

    (1)Connection:是建立客户端与服务端的连接。

    (2)Channel:是基于Connection之上建立通信通道,因为每次Connection建立TCP协议通信开销及性能消耗较大,所以一次建立Connection后,使用多个Channel通道通信减少开销和提高性能。

    (3)Binging:是一个捆绑定义,将exchange和queue捆绑,定义routingkey相关策略。


三、RabbitMQ安装部署

  以上对RabbitMQ简介,接下来我们通过实际搭建消息队列服务实践。RabbitMQ服务端能运行于Window、Linux和Mac平台,客户端也支持多种技术的实现。本次我们将在Linux之CentOS7平台搭建。

  1、安装Erlang运行环境

    由于RabbitMQ使用Erlang技术开发,所以需要先安装Erlang运行环境后,才能安装消息队列服务。

    (1)配置系统能正常访问公网,设置默认网关

1
route add default gw 192.168.1.1

    (2)安装erlang

    (3)检查erlang是否安装成功

1
erl

    (4)安装成功

    

  2、安装RabbitMQ服务端

    (1)下载安装包

1
wget http://www.rabbitmq.com/releases/rabbitmq-server/v3.6.0/rabbitmq-server-3.6.0-1.noarch.rpm

    (2)安装和配置RabbitMQ服务端,3.6.0版本:

1
2
rpm --import https://www.rabbitmq.com/rabbitmq-signing-key-public.asc
yum install rabbitmq-server-3.6.0-1.noarch.rpm

    (3)启用web管理插件

1
rabbitmq-plugins enable rabbitmq_management

    (4)启动RabbitMQ

1
2
chkconfig rabbitmq-server on
/sbin/service rabbitmq-server start

    (5)防火墙开通端口

1
2
3
# firewall-cmd --permanent --zone=public --add-port=5672/tcp
# firewall-cmd --permanent --zone=public --add-port=15672/tcp
# firewall-cmd --reload

    (6)rabbitmq默认会创建guest账号,只能用于localhost登录页面管理员,本机访问地址:http://localhost:15672/

1
2
rabbitmqctl add_user test test
rabbitmqctl set_user_tags test administrator<br>rabbitmqctl set_permissions -p / test ".*" ".*" ".*"

      RabbitMQ 管理员页面。


四、RabbitMQ应用

  本章节描述,web应用生产的日志,通过rabbitmq传输,然后日志服务接收消息队列的消息。

    

图3- 功能结构示意图

  本系统采用官方的Client,通过nuget引用。

  

  1、Web应用生产业务日志

1
2
3
4
5
6
7
8
9
10
[HttpPost]
        public ActionResult Create()
        {
            this.HttpContext.Session["mysession"] = DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss");
            var txt = Request.Form["txtSite"].ToString();
            RabbitMQHelper helper = new RabbitMQHelper();
            helper.SendMsg(txt + ",操作日志,时间:" + DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss"));
 
            return RedirectToAction("Index");
        }

  页面效果图。

  2、日志服务接收日志消息

    基于window form开发一个日志处理服务,并将接收的消息打印出来。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
private void btnReceive_Click(object sender, EventArgs e)
        {
            isConnected = true;
            using (var channel = connection.CreateModel())
            {
                channel.QueueDeclare("MyLog"falsefalsefalsenull);
 
                var consumer = new QueueingBasicConsumer(channel);
                channel.BasicConsume("MyLog"true, consumer);
 
                while (isConnected)
                {
                    var ea = (BasicDeliverEventArgs)consumer.Queue.Dequeue();
 
                    var body = ea.Body;
                    var message = Encoding.UTF8.GetString(body);
                    txtMsg.Text += message + "\r\n";
 
                }
            }
        }

  

  3、RabbitMQ页面监控情况

  RabbitMQ自带页面监控工具,通过此工具可以监控MQ的情况:

         

五、总结

  此文大概介绍RabbitMQ搭建和应用于本系统,RabbitMQ还是较为简单,还提供界面监控工具方便运维人员监控。

作者:andon 
出处:http://www.cnblogs.com/Andon_liu 
关于作者:专注于微软平台项目架构、管理。熟悉设计模式、领域驱动、架构设计、敏捷开发和项目管理。现主要从事ASP.NET MVC、WCF/Web API、SOA、MSSQL、redis方面的项目开发、架构、管理工作。 如有问题或建议,请一起学习讨论! 
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。 
如有问题,可以邮件:568773262@qq.com 联系我,谢谢。
 

RabbitMQ消息队列应用的更多相关文章

  1. RabbitMQ消息队列(一): Detailed Introduction 详细介绍

     http://blog.csdn.net/anzhsoft/article/details/19563091 RabbitMQ消息队列(一): Detailed Introduction 详细介绍 ...

  2. RabbitMQ消息队列1: Detailed Introduction 详细介绍

    1. 历史 RabbitMQ是一个由erlang开发的AMQP(Advanced Message Queue )的开源实现.AMQP 的出现其实也是应了广大人民群众的需求,虽然在同步消息通讯的世界里有 ...

  3. (转)RabbitMQ消息队列(九):Publisher的消息确认机制

    在前面的文章中提到了queue和consumer之间的消息确认机制:通过设置ack.那么Publisher能不到知道他post的Message有没有到达queue,甚至更近一步,是否被某个Consum ...

  4. (转)RabbitMQ消息队列(七):适用于云计算集群的远程调用(RPC)

    在云计算环境中,很多时候需要用它其他机器的计算资源,我们有可能会在接收到Message进行处理时,会把一部分计算任务分配到其他节点来完成.那么,RabbitMQ如何使用RPC呢?在本篇文章中,我们将会 ...

  5. (转)RabbitMQ消息队列(六):使用主题进行消息分发

    在上篇文章RabbitMQ消息队列(五):Routing 消息路由 中,我们实现了一个简单的日志系统.Consumer可以监听不同severity的log.但是,这也是它之所以叫做简单日志系统的原因, ...

  6. (转)RabbitMQ消息队列(四):分发到多Consumer(Publish/Subscribe)

    上篇文章中,我们把每个Message都是deliver到某个Consumer.在这篇文章中,我们将会将同一个Message deliver到多个Consumer中.这个模式也被成为 "pub ...

  7. RabbitMQ消息队列(四):分发到多Consumer(Publish/Subscribe)

    上篇文章中,我们把每个Message都是deliver到某个Consumer.在这篇文章中,我们将会将同一个Message deliver到多个Consumer中.这个模式也被成为 "pub ...

  8. RabbitMQ消息队列(九):Publisher的消息确认机制

    在前面的文章中提到了queue和consumer之间的消息确认机制:通过设置ack.那么Publisher能不到知道他post的Message有没有到达queue,甚至更近一步,是否被某个Consum ...

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

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

随机推荐

  1. delphi json(CDS包含了Delta数据包)

    在delphi中,数据集是最常用数据存取方式.因此,必须建立JSON与TDataSet之间的互转关系,实现数据之间通讯与转换.值得注意的是,这只是普通的TDataset与JSON之间转换,由于CDS包 ...

  2. 设置MyEclipse中代码的换行长度

    1.打开Preferences -> Java -> Code Style -> Formatter. 2.选择Edit -> Line Wrapping  -> Max ...

  3. TPL异步并行编程之取消任务

    TPL异步并行编程之简单使用 在上篇随笔里面说明了Task的使用,仅仅是简单使用,有时候把一个任务交给Task去执行,但是呢还是要管理下,比如说:我要叫这个任务停止了,不做了,任务取消了,或者超时了 ...

  4. vc 在edit控件中动态插入数据滚动显示

    内存从网上论坛摘抄整理 思路:给控件设置多行属性,设置垂直滚动条,Auto Vscroll设置为true,放入文本后把插入点设置到末尾 pEdit->LineScroll(pEdit->G ...

  5. Shell echo命令

    Shell echo命令 echo "It is a test" 这里的双引号完全可以省略 .显示变量 read 命令从标准输入中读取一行,并把输入行的每个字段的值指定给 shel ...

  6. J2EE开发框架搭建(2) - springmvc4 + spring4 + hibernate4 整合

    1. 打开hqhop-framework-parent项目下的pom.xml文件.加入springmvc4 , spring4 , hibernate4 ,以及数据源druid的依赖包,插件,依赖包版 ...

  7. 使用Jmeter至WebService压力测试

    使用Jmeter至WebService压力测试   目中我们使用了Jmeter对webservice进行了压力測试,Apache JMeter是Apache组织开发的基于Java的压力測试工具.用于对 ...

  8. 《转载》常用算法经典代码(C++版)

    转自:http://blog.renren.com/blog/311453043/736944237 一.快速排序 void qsort(int x,int y) //待排序的数据存放在a[1]..a ...

  9. iOS视图控制器之间delegate传值教程

    之前在StackOverFlow上看到一篇讲传值(segue传值和delegate传值)的文章,感觉讲的非常清晰,就将delegate部分翻译了一下.有兴趣能够看看. 原文: http://stack ...

  10. CSS 文本框里添加按钮的实现

    有很多人做界面会经常发现设计师设计出这样的界面: 咋一看是一个文本框里加了一个按钮,经过谷歌之后,未发现在文本框里可以添加按钮. 但可以通过div来实现它. 我的做法是先做一个大小的div,然后用带里 ...