2.hello rabbitmq
作者
微信:tangy8080
电子邮箱:914661180@qq.com
更新时间:2019-07-22 22:49:50 星期一
欢迎您订阅和分享我的订阅号,订阅号内会不定期分享一些我自己学习过程中的编写的文章
如您在阅读过程中发现文章错误,可添加我的微信 tangy8080 进行反馈.感谢您的支持。

文章主题
从一个最简单的hello rabbitmq开始,逐步了解rabbitmq
本文源码:http://admin@gitblit.honeysuckle.site/r/public/rabbitmq/Solution2.git
前置条件
已经构建好了一个rabbitmq集群
正文
认识rabbitmq
首先,rabbitmq是一个消息中间件.它主要解决了应用耦合、异步处理、流量削锋等问题。
它具有以下特点:
- 解耦
假如现在您需要做一个通知中心,您需要将您的消息通知到 A,B,C.
经验稍差的同学可能会直接代码引用,通知中心直接引用A,B,C的代码.一旦有新的消息,直接调用A B C的逻辑处理.但是这样带来一个问题,现在如果D也需要收到消息.难道通知中心再引用一次D吗? 这显然是一种糟糕的设计.
一种比较优雅的实现就是观察者模式.A,B,C观察通知中心的消息.如果有新的消息.则做出相应的逻辑. 如果D现在需要知道通知中心的消息,那么它只需要订阅通知中心的消息就可以了.通知中心的逻辑是不需要动的
异步化
多应用对消息队列中同一消息进行处理,应用间并发处理消息,相比串行处理,减少处理时间削峰
广泛应用于秒杀或抢购活动中,避免流量过大导致应用系统挂掉的情况
专业术语
- 生产:生产意味着就是发送。 发送消息的程序是一个生产者
- 队列:这里的队列是指一个名称,但是名称所代表的队列实体寄存在RabbitMQ服务器端中。 虽然消息流过RabbitMQ和您的应用程序,但它们只能存储在队列中。 队列只受主机的内存和磁盘的限制,它本质上是一个大的消息缓冲区。 许多生产者可以发送消息到一个队列,许多消费者可以尝试从一个队列接收数据
- 消费:消费具有与接收相似的含义。 消费者是一个主要等待接收消息的程序
工作原理

使用 Net/C# 客户端完成hello rabbitmq
生产者:
using RabbitMQ.Client;
using System;
using System.Text;
namespace Server
{
class Program
{
static void Main(string[] args)
{
var connectionFactory = new ConnectionFactory
{
Port = 5672,
VirtualHost = "test",
HostName = "192.168.161.160",
UserName = "test",
Password = "123456",
AutomaticRecoveryEnabled = true,
TopologyRecoveryEnabled = true
};
using (var connection = connectionFactory.CreateConnection())
using (var channel = connection.CreateModel())
{
channel.QueueDeclare(queue: "hello",
durable: false,
exclusive: false,
autoDelete: false,
arguments: null);
string message = "Hello RabbitMQ!";
var body = Encoding.UTF8.GetBytes(message);
channel.BasicPublish(exchange: "",
routingKey: "hello",
basicProperties: null,
body: body);
Console.WriteLine(" [x] Sent {0}", message);
}
Console.WriteLine(" Press [enter] to exit.");
Console.ReadLine();
}
}
}
1.定义连接参数
- ConnectionFactory用来创建rabbitmq连接,相比通道来说.连接是高成本的.
- Port: rabbitmq Server TCP监听端口,由于我们使用nginx做了负载均衡.这里写的是Nginx监听端口
- VirtualHost: rabbitmq支持虚拟主机,各个虚拟主机之间相互隔离.
- HostName:主机地址, 由于我们使用nginx做了负载均衡.这里写的是虚拟IP
- UserName,Password 用户名和密码
- AutomaticRecoveryEnabled:启用自动连接恢复,当服务端或者客户端异常断开后将尝试自动重连
- TopologyRecoveryEnabled: 连接恢复交换机,队列,绑定和消费者
2.创建一个连接
您可以在创建连接时执行主机列表
//
// 摘要:
// Create a connection using a list of hostnames using the configured port. By default
// each hostname is tried in a random order until a successful connection is found
// or the list is exhausted using the DefaultEndpointResolver. The selection behaviour
// can be overriden by configuring the EndpointResolverFactory.
//
// 参数:
// hostnames:
// List of hostnames to use for the initial connection and recovery.
//
// 返回结果:
// Open connection
//
// 异常:
// T:RabbitMQ.Client.Exceptions.BrokerUnreachableException:
// When no hostname was reachable.
public IConnection CreateConnection(IList<string> hostnames);
3.创建1-N个通道
通道是建立在连接的基础上的,相对连接来说.通道是低成本.
4.交换机
因为rabbitmq已经有了自定义的ampq default exchange,这里暂时不申明交换机
5.定义队列
如果队列不存在,则会创建队列.如果两个程序要求创建同一个队列(队列名称相同) 但指定了不同的参数,则后面的定义队列请求会收到异常
channel.QueueDeclare(queue: "hello",
durable: false,
exclusive: false,
autoDelete: false,
arguments: null);
- queue: 队列名称
- durable: 是否持久化,申明为false.当前连接关闭后队列将被销毁
- exclusive:是否是独占的,不允许其他连接访问
- autoDelete :是否自动删除,true,自动删除,自动删除的前提:至少有一个消息者连接到这个队列,之后所有与这个队列连接的消息都断开时,才会自动删除,,
备注:生产者客户端创建这个队列,或者没有消息者客户端连接这个队列时,不会自动删除这个队列
6.发送消息
channel.BasicPublish(exchange: "",
routingKey: "hello",
basicProperties: null,
body: body);
- 服务器发送消息不会直接发送到队列中(Queue),而是直接发送给交换机(Exchange),然后根据确定的规则,RabbitMQ将会决定消息该投递到哪个队列。这些规则称为路由键(routing key),队列通过路由键绑定到交换机上。
消费者:
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System;
using System.Text;
class Receive
{
public static void Main()
{
var connectionFactory = new ConnectionFactory
{
Port = 5672,
VirtualHost = "test",
HostName = "192.168.161.160",
UserName = "test",
Password = "123456",
AutomaticRecoveryEnabled = true,
TopologyRecoveryEnabled = true
};
using (var connection = connectionFactory.CreateConnection())
using (var channel = connection.CreateModel())
{
channel.QueueDeclare(queue: "hello",
durable: false,
exclusive: false,
autoDelete: false,
arguments: null);
var consumer = new EventingBasicConsumer(channel);
consumer.Received += (model, ea) =>
{
var body = ea.Body;
var message = Encoding.UTF8.GetString(body);
Console.WriteLine(" [x] Received {0}", message);
};
channel.BasicConsume(queue: "hello", true, consumer: consumer);
Console.WriteLine(" Press [enter] to exit.");
Console.ReadLine();
}
}
}

思考两个问题
- 我们在发布消息的时候,routingKey为什么是hello 而不是其他的
- 我们在进行消费的时候好像也没有建立queue和exchange的绑定,为啥还是可以收到消息
答案在这里:

回到原理图,看下这里我们是如何定义各个角色的
1.Client 我们这里是生产者,即生产者部分的代码
2.Exchange 没有显式定义交互机,但它是存在的.名称为AMQP default.在创建virtual host时会自动创建
3.queue 我们这里定义了名称为 hello的队列
4.Recive 我们这里是消费者部分的代码
引用链接
https://www.rabbitmq.com/tutorials/tutorial-one-dotnet.html
https://www.rabbitmq.com/dotnet-api-guide.html
2.hello 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 ...
随机推荐
- 查看Java的汇编指令
在IDEA配置VM options,打印汇编指令 -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly windows系统 下载插件 hsdis-amd6 ...
- MYSQL基础知识的复习3
聚合函数 max():求最大值 例:求最高工资 select max(sal) from emp; min():求最小值 例:求最小工资 select min(sal) from emp; avg() ...
- 第2章_神经网络入门_2-5&2-6 数据处理与模型图构建
目录 神经元的TF实现 安装 神经网络的TF实现 神经元的TF实现 安装 版本: Python 2.7 tf 1.8.0 Linux 略 demo 神经网络的TF实现 # py36 tf 2.1. # ...
- USB2514集线器调试总结
一般的MCU不会留有太多的USB口,但在实际项目中又会遇到需要很多个USB口的情况,这时就会用到USB集线器来扩展USB口了.USB2514这个芯片是我在工作中用的比较多的,但是问题很多,从来没有调稳 ...
- 【Android初级】如何动态添加菜单项(附源码+避坑)
我们平时在开发过程中,为了灵活多变,除了使用静态的菜单,还有动态添加菜单的需求.今天要分享的功能如下: 在界面的右上角有个更多选项,点开后,有两个子菜单:关于和退出 点击"关于", ...
- WinForm中实现按Enter将光标移动到下一个文本框
首先窗体加载出来是上面这个样子.有五个文本框,我们要实现的功能就是输入姓名后按Enter,使光标直接定位到手机号中. 在页面加载的时候我们就要获取所有文本框控件,并添加回车事件 private voi ...
- __del__ PyPy和CPython的不同点 动态编译(注意不是解释) 析构函数被调用的次数
小结 1.cpy的垃圾回收会对调用__del__多次:pypy仅仅一次: https://www.liaoxuefeng.com/wiki/1016959663602400/1016966024263 ...
- 监听套接字描述字 已连接套接字描述字 和打电话的情形非常不一样的地方 完成了 TCP 三次握手,操作系统内核就为这个客户生成一个已连接套接字
1. accept: 电话铃响起了-- 当客户端的连接请求到达时,服务器端应答成功,连接建立,这个时候操作系统内核需要把这个事件通知到应用程序,并让应用程序感知到这个连接.这个过程,就好比电信运营商完 ...
- oracle模糊查询mysql的区别
https://blog.csdn.net/weixin_38673554/article/details/86503982#_1 oracle与使用mysql的区别 https://www.cnbl ...
- 【实战】ZooKeeper 实战
1. 前言 这篇文章简单给演示一下 ZooKeeper 常见命令的使用以及 ZooKeeper Java客户端 Curator 的基本使用.介绍到的内容都是最基本的操作,能满足日常工作的基本需要. 如 ...