RabbitMQ简单入手

一、RabbitMQ介绍
  RabbitMQ是一款基于AMQP(消息队列协议),由Erlang开发的开源消息队列组件。是一款优秀的消息队列组件,他由两部分组成:服务端和客户端,客户端支持多种语言的驱动,如:.Net、JAVA、Erlang等。

RabbitMQ安装部署
  以上对RabbitMQ简介,接下来我们通过实际搭建消息队列服务实践。RabbitMQ服务端能运行于Window、Linux和Mac平台,客户端也支持多种技术的实现。本次我们将在Linux之CentOS7平台搭建。
1、安装Erlang运行环境
    由于RabbitMQ使用Erlang技术开发,所以需要先安装Erlang运行环境后,才能安装消息队列服务。

(1)配置系统能正常访问公网,设置默认网关
route add default gw 192.168.1.1
    (2)安装erlang
su -c ‘rpm -Uvh http://download.fedoraproject.org/pub/epel/7/x86_64/e/epel-release-7-5.noarch.rpm‘sudo yum install erlang
    (3)检查erlang是否安装成功
erl
4)安装成功
    

2、安装RabbitMQ服务端
    (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版本:
rpm –import https://www.rabbitmq.com/rabbitmq-signing-key-public.ascyum install rabbitmq-server-3.6.0-1.noarch.rpm
    (3)启用web管理插件
rabbitmq-plugins enable rabbitmq_management
    (4)启动RabbitMQ
chkconfig rabbitmq-server on/sbin/service rabbitmq-server start
    (5)防火墙开通端口
# 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/
rabbitmqctl add_user test testrabbitmqctl set_user_tags test administrator
rabbitmqctl set_permissions -p / test “.” “.” “.*”

1、Web应用生产业务日志
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、日志服务接收日志消息

private void btnReceive_Click(object sender, EventArgs e)
{
isConnected = true;
using (var channel = connection.CreateModel())
{
channel.QueueDeclare(“MyLog”, false, false, false, null);

            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";

            }
        }
    }

四、RabbitMQ的基本用法
使用RabbitMQ客户端就必需在项目中引用其相关的组件,这里可以通过NuGet安装或从官网下载再引用均可,方法很简单,不再重述;
1.普通用法:采用默认的exchange(交换机,或称路由器)+默认的exchange类型:direct+noAck(自动应答,接收就应答)

///
/// 消息发送者,一般用在客户端
///
class RabbitMQPublish
{
static void Main(string[] args)
{
var factory = new ConnectionFactory();//创建连接工厂并初始连接
factory.HostName = “localhost”;
factory.UserName = “zwj”;
factory.Password = “www.zuowenjun.cn”;
using (var connection = factory.CreateConnection())//创建一个连接
{
using (var channel = connection.CreateModel()) //创建一个通道
{
channel.QueueDeclare(“hello”, false, false, false, null);//创建一个队列
string message = “”;
while (message!=”exit”)
{
Console.Write(“Please enter the message to be sent:”);
message = Console.ReadLine();
var body = Encoding.UTF8.GetBytes(message);
channel.BasicPublish(“”, “hello”, null, body); //发送消息
Console.WriteLine(“set message: {0}”, message);
}
}
}
}
}
///
/// 消费者,一般用在服务端
///
class RabbitMQConsume
{
static void Main(string[] args)
{
var factory = new ConnectionFactory();//创建连接工厂并初始连接
factory.HostName = “localhost”;
factory.UserName = “zwj”;
factory.Password = “www.zuowenjun.cn”;
using (var connection = factory.CreateConnection())//创建一个连接
{
using (var channel = connection.CreateModel())//创建一个通道
{
channel.QueueDeclare(“hello”, false, false, false, null);//创建一个队列
var consumer = new QueueingBasicConsumer(channel);//创建一个消费者
channel.BasicConsume(“hello”, true, consumer);//开启消息者与通道、队列关联
Console.WriteLine(” waiting for message.”);
while (true)
{
var ea = (BasicDeliverEventArgs)consumer.Queue.Dequeue();//接收消息并出列
var body = ea.Body;//消息主体
var message = Encoding.UTF8.GetString(body);
Console.WriteLine(“Received {0}”, message);
if (message == “exit”)
{
Console.WriteLine(“exit!”);
break;
}
}
}
}
}
}

2.负载均衡处理模式:采用默认的exchange(交换机)+智能分发+默认的exchange类型:direct+手动应答
消息生产者/发布者代码与上面相同;
以下是消费者代码:
///
/// 消费者,一般用在服务端
///
class RabbitMQConsume
{
static void Main(string[] args)
{
var factory = new ConnectionFactory();//创建连接工厂并初始连接
factory.HostName = “localhost”;
factory.UserName = “zwj”;
factory.Password = “www.zuowenjun.cn”;
using (var connection = factory.CreateConnection())//创建一个连接
{
using (var channel = connection.CreateModel())//创建一个通道
{
channel.QueueDeclare(“hello”, false, false, false, null);//创建一个队列
channel.BasicQos(0, 1, false);//在一个工作者还在处理消息,并且没有响应消息之前,不要给他分发新的消息。相反,将这条新的消息发送给下一个不那么忙碌的工作者。
var consumer = new QueueingBasicConsumer(channel);//创建一个消费者
channel.BasicConsume(“hello”, false, consumer);//开启消息者与通道、队列关联
Console.WriteLine(” waiting for message.”);
while (true)
{
var ea = (BasicDeliverEventArgs)consumer.Queue.Dequeue();//接收消息并出列
var body = ea.Body;//消息主体
var message = Encoding.UTF8.GetString(body);
Console.WriteLine(“Received {0}”, message);
channel.BasicAck(ea.DeliveryTag, false);
if (message == “exit”)
{
Console.WriteLine(“exit!”);
break;
}
Thread.Sleep(1000);
}
}
}
}
}

3.消息持久化模式:在2的基础上加上持久化,这样即使生产者或消费者或服务端断开,消息均不会丢失

///
/// 消息发送者,一般用在客户端
///
class RabbitMQPublish
{
static void Main(string[] args)
{
var factory = new ConnectionFactory();//创建连接工厂并初始连接
factory.HostName = “localhost”;
factory.UserName = “zwj”;
factory.Password = “www.zuowenjun.cn”;
using (var connection = factory.CreateConnection())//创建一个连接
{
using (var channel = connection.CreateModel()) //创建一个通道
{
channel.QueueDeclare(“hello”, true, false, false, null);//创建一个队列,第2个参数为true表示为持久队列
var properties = channel.CreateBasicProperties();
//properties.SetPersistent(true);这个方法提示过时,不建议使用
properties.DeliveryMode = 2;//1表示不持久,2.表示持久化
string message = “”;
while (message!=”exit”)
{
Console.Write(“Please enter the message to be sent:”);
message = Console.ReadLine();
var body = Encoding.UTF8.GetBytes(message);
channel.BasicPublish(“”, “hello”, properties, body); //发送消息
Console.WriteLine(“set message: {0}”, message);
}
}
}
}
}
///
/// 消费者,一般用在服务端
///
class RabbitMQConsume
{
static void Main(string[] args)
{
var factory = new ConnectionFactory();//创建连接工厂并初始连接
factory.HostName = “localhost”;
factory.UserName = “zwj”;
factory.Password = “www.zuowenjun.cn”;
using (var connection = factory.CreateConnection())//创建一个连接
{
using (var channel = connection.CreateModel())//创建一个通道
{
channel.QueueDeclare(“hello”, true, false, false, null);//创建一个队列,第2个参数为true表示为持久队列
channel.BasicQos(0, 1, false);//在一个工作者还在处理消息,并且没有响应消息之前,不要给他分发新的消息。相反,将这条新的消息发送给下一个不那么忙碌的工作者。
var consumer = new QueueingBasicConsumer(channel);//创建一个消费者
channel.BasicConsume(“hello”, false, consumer);//开启消息者与通道、队列关联
Console.WriteLine(” waiting for message.”);
while (true)
{
var ea = (BasicDeliverEventArgs)consumer.Queue.Dequeue();//接收消息并出列
var body = ea.Body;//消息主体
var message = Encoding.UTF8.GetString(body);
Console.WriteLine(“Received {0}”, message);
channel.BasicAck(ea.DeliveryTag, false);
if (message == “exit”)
{
Console.WriteLine(“exit!”);
break;
}
Thread.Sleep(1000);
}
}
}
}
}

4.广播订阅模式:定义一个交换机,其类型设为广播类型,发送消息时指定这个交换机,消费者的消息队列绑定到该交换机实现消息的订阅,订阅后则可接收消息,未订阅则无法收到消息

///
/// 消息发送者/生产者,一般用在客户端
///
class RabbitMQPublish
{
static void Main(string[] args)
{
var factory = new ConnectionFactory();//创建连接工厂并初始连接
factory.HostName = “localhost”;
factory.UserName = “zwj”;
factory.Password = “www.zuowenjun.cn”;
using (var connection = factory.CreateConnection())//创建一个连接
{
using (var channel = connection.CreateModel()) //创建一个通道
{
channel.ExchangeDeclare(“publish”, “fanout”,true);//定义一个交换机,且采用广播类型,并设为持久化
string queueName = channel.QueueDeclare(“hello”, true, false, false, null);//创建一个队列,第2个参数为true表示为持久队列,这里将结果隐式转换成string
var properties = channel.CreateBasicProperties();
//properties.SetPersistent(true);这个方法提示过时,不建议使用
properties.DeliveryMode = 2;//1表示不持久,2.表示持久化
string message = “”;
while (message!=”exit”)
{
Console.Write(“Please enter the message to be sent:”);
message = Console.ReadLine();
var body = Encoding.UTF8.GetBytes(message);
channel.BasicPublish(“publish”, “hello”, properties, body); //发送消息,这里指定了交换机名称,且routeKey会被忽略
Console.WriteLine(“set message: {0}”, message);
}
}
}
}
}
///
/// 消费者,一般用在服务端
///
class RabbitMQConsume
{
static void Main(string[] args)
{
var factory = new ConnectionFactory();//创建连接工厂并初始连接
factory.HostName = “localhost”;
factory.UserName = “zwj”;
factory.Password = “www.zuowenjun.cn”;
using (var connection = factory.CreateConnection())//创建一个连接
{
using (var channel = connection.CreateModel())//创建一个通道
{
channel.ExchangeDeclare(“publish”, “fanout”, true);//定义一个交换机,且采用广播类型,并持久化该交换机,并设为持久化
string queueName = channel.QueueDeclare(“hello”, true, false, false, null);//创建一个队列,第2个参数为true表示为持久队列
channel.QueueBind(queueName, “publish”, “”);//将队列绑定到名publish的交换机上,实现消息订阅
channel.BasicQos(0, 1, false);//在一个工作者还在处理消息,并且没有响应消息之前,不要给他分发新的消息。相反,将这条新的消息发送给下一个不那么忙碌的工作者。
var consumer = new QueueingBasicConsumer(channel);//创建一个消费者
channel.BasicConsume(queueName, false, consumer);//开启消息者与通道、队列关联
Console.WriteLine(” waiting for message.”);
while (true)
{
var ea = (BasicDeliverEventArgs)consumer.Queue.Dequeue();//接收消息并出列
var body = ea.Body;//消息主体
var message = Encoding.UTF8.GetString(body);
Console.WriteLine(“Received {0}”, message);
channel.BasicAck(ea.DeliveryTag, false);//应答
if (message == “exit”)
{
Console.WriteLine(“exit!”);
break;
}
Thread.Sleep(1000);
}
}
}
}
}

5.主题订阅模式:定义一个交换机,其类型设为主题订阅类型,发送消息时指定这个交换机及RoutingKey,消费者的消息队列绑定到该交换机并匹配到RoutingKey实现消息的订阅,订阅后则可接收消息,未订阅则无法收到消息

///
/// 消息发送者/生产者,一般用在客户端
///
class RabbitMQPublish
{
static void Main(string[] args)
{
var factory = new ConnectionFactory();//创建连接工厂并初始连接
factory.HostName = “localhost”;
factory.UserName = “zwj”;
factory.Password = “www.zuowenjun.cn”;
using (var connection = factory.CreateConnection())//创建一个连接
{
using (var channel = connection.CreateModel()) //创建一个通道
{
channel.ExchangeDeclare(“publish-topic”, “topic”, true);//定义一个交换机,且采用广播类型,并持久化该交换机
channel.QueueDeclare(“hello-mq”, true, false, false, null);//创建一个队列,第2个参数为true表示为持久队列
var properties = channel.CreateBasicProperties();
//properties.SetPersistent(true);这个方法提示过时,不建议使用
properties.DeliveryMode = 2;//1表示不持久,2.表示持久化
string message = “”;
while (message!=”exit”)
{
Console.Write(“Please enter the message to be sent:”);
message = Console.ReadLine();
var body = Encoding.UTF8.GetBytes(message);
channel.BasicPublish(“publish-topic”, “hello.test”, properties, body); //发送消息,这里指定了交换机名称,且routeKey会被忽略
Console.WriteLine(“set message: {0}”, message);
}
}
}
}
}
///
/// 消费者,一般用在服务端
///
class RabbitMQConsume
{
static void Main(string[] args)
{
var factory = new ConnectionFactory();//创建连接工厂并初始连接
factory.HostName = “localhost”;
factory.UserName = “zwj”;
factory.Password = “www.zuowenjun.cn”;
using (var connection = factory.CreateConnection())//创建一个连接
{
using (var channel = connection.CreateModel())//创建一个通道
{
channel.ExchangeDeclare(“publish-topic”, “topic”,true);//定义一个交换机,且采用广播类型,并持久化该交换机
string queueName = channel.QueueDeclare(“hello-mq”, true, false, false, null);//创建一个队列,第2个参数为true表示为持久队列
channel.QueueBind(queueName, “publish-topic”, “*.test”);//将队列绑定到路由上,实现消息订阅
channel.BasicQos(0, 1, false);//在一个工作者还在处理消息,并且没有响应消息之前,不要给他分发新的消息。相反,将这条新的消息发送给下一个不那么忙碌的工作者。
var consumer = new QueueingBasicConsumer(channel);//创建一个消费者
channel.BasicConsume(queueName, false, consumer);//开启消息者与通道、队列关联
Console.WriteLine(” waiting for message.”);
while (true)
{
var ea = (BasicDeliverEventArgs)consumer.Queue.Dequeue();//接收消息并出列
var body = ea.Body;//消息主体
var message = Encoding.UTF8.GetString(body);
Console.WriteLine(“Received {0}”, message);
channel.BasicAck(ea.DeliveryTag, false);//应答
if (message == “exit”)
{
Console.WriteLine(“exit!”);
break;
}
Thread.Sleep(1000);
}
}
}
}
}

猜你喜欢

转载自blog.csdn.net/weixin_42812598/article/details/81238681