现在的位置: 首页 > 综合 > 正文

RabbitMQ学习(七)Ubuntu环境安装与.NET客户端测试

2019年10月14日 ⁄ 综合 ⁄ 共 6106字 ⁄ 字号 评论关闭

转载请注明出处:jiq•钦's technical Blog

1、下载RabbitMQ Server安装包

Ubuntu环境下的安装包rabbitmq-server_3.3.5-1_all.deb的下载地址在这里:http://www.rabbitmq.com/install-debian.html

Ubuntu自9.04版本之后默认会安装RabbitMQ,但是版本会较老,所以我们需要安装上面的最新的安装包。

下载后直接双击安装即可,Erlang环境都是有的。

安装好了之后启动命令是:

invoke-rc.d rabbitmq-server start

停止命令是:

invoke-rc.d rabbitmq-server stop

2、编写.Net客户端测试程序

发送程序Send.cs代码是:

namespace RabbitMQ.SendReceive
{
    class Program
    {
        static void Main(string[] args)
        {
            ConnectionFactory factory = new ConnectionFactory() { HostName = "192.168.1.103" };
            using (IConnection conn = factory.CreateConnection())
            {
                using (IModel channel = conn.CreateModel())
                {
                    channel.QueueDeclare("hello", false, false, false, null);

                    string mesg = "hello RabbitMQ";
                    byte[] body = Encoding.UTF8.GetBytes(mesg);

                    channel.BasicPublish("", "hello", null, body);
                    Console.WriteLine(" [x] Sent {0}", mesg);
                }
            }
        }
    }
}

接收程序Receive.cs代码是:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;

namespace RabbitMQ.SendReceive
{
    class Program
    {
        static void Main(string[] args)
        {
            ConnectionFactory factory = new ConnectionFactory() { HostName = "192.168.1.103" };
            using (IConnection conn = factory.CreateConnection())
            {
                using (IModel channel = conn.CreateModel())
                {
                    channel.QueueDeclare("hello", false, false, false, null);

                    QueueingBasicConsumer consumer = new QueueingBasicConsumer(channel);
                    channel.BasicConsume("hello", true, consumer);
                    Console.WriteLine(" [*]Waiting for message...");

                    while (true)
                    { 
                        var queueItem = (BasicDeliverEventArgs)consumer.Queue.Dequeue();

                        byte[] body = queueItem.Body;
                        string mesg = Encoding.UTF8.GetString(body);
                        Console.WriteLine(" [x] Received {0}", mesg);
                    }
                }
            }
        }
    }
}

注意需要先在这里(地址)下载rabbitmq-dotnet-client-3.3.5-dotnet-3.0,然后引入RabbitMQ.Client.dll和RabbitMQ.ServiceModel.dll两个DLL。

3、运行测试代码

我的测试代码是跑在Windows7上面的,而RabbitMQ Broker安装在Ubuntu的虚拟机上面,以桥接方式进行网络连接。

运行代码会出现访问被拒绝的异常。官网上有一段话:

Default user access

The broker creates a user guest with password guest.
Unconfigured clients will in general use these credentials. By default, these credentials can only be used when connecting to the broker as localhost so you will need to take action before connecting fromn any other machine.

意思是说未配置的客户端默认会以guest的身份(密码也是guest)作为访问消息中心(RabbitMQ Broker)的验证,但是这只在client和RabbitMQ Broker在同一台机器上的时候才有效,即才能够访问,要是跨机器,还需要做其他工作。

3.1、首先来看如何解决guest用户只能本机访问的问题:

"guest" user can only connect via localhost

By default, the guest user is prohibited from connecting to the broker remotely; it can only connect over a loopback interface
(i.e. localhost). This applies both to AMQP and to any other protocols enabled via plugins. Any other users you create will
not (by default) be restricted in this way.

This is configured via the loopback_users item in the configuration
file
.

If you wish to allow the guest user to connect from a remote host, you should set the loopback_users configuration
item to []. A complete rabbitmq.config which
does this would look like:

[{rabbit, [{loopback_users, []}]}].

这个上面已经说得很清楚了,默认情况下RabbitMQ的配置中loopback_users这个配置项需要修改为空[],因为默认的是配置为guest了,修改为空之后就没有guest只能本机访问这个限制了。

每一种发布版配置文件所在的位置都不一样,下面是常见的操作系统配置文件所在位置:

  • Generic UNIX - $RABBITMQ_HOME/etc/rabbitmq/
  • Debian/Ubuntu - /etc/rabbitmq/
  • RPM - /etc/rabbitmq/
  • Mac OS X (Macports) - ${install_prefix}/etc/rabbitmq/,
    the Macports prefix is usually /opt/local
  • Windows - %APPDATA%\RabbitMQ\

假如默认位置没有配置文件,自己新建一个即可。

我的Ubuntu就没有配置文件,我就自己新建了一个,内容只需要写上我要修改的这个配置项即可。

这样我WIndows7上面的测试代码就可以正常运行了!!!

3.2 创建新的用户 *:

It is advisable to delete the guest user
or 
change
the password
 to something private, particularly if your broker is accessible publicly.

可以看到一般来说建议删掉guest用户,或者修改guest用户的代码。

另外提一句,客户端访问RabbitMQ broker是需要用户名、密码、端口号,虚拟机名称等信息的,为什么我上面的测试代码没有这些信息呢???

All factory properties have default values. The default value for a property will be used if the property remains unassigned prior to creating a connection:
• username: "guest"
• password: "guest"
• virtual-host: "/"
• protocol: AMQP 0-9-1
• hostname: localhost
• port: 5672

现在我们已经决定将guest用户删除掉,然后创建其他的用户来进行RabbitMQ broker的访问。


RabbitMQ broker在逻辑上划分为多个virtual hosts,即虚拟主机,然后存在多个用户,每个用户针对每个虚拟机的各种资源(比如交换机、队列等)都有特定的访问权限(配置、读、写),每次创建了一个新的用户,需要配置其对指定虚拟机(默认初始化只有 “/” 一个虚拟机)的权限。

所有创建虚拟机,创建用户,配置用户权限的操作都是通过rabbitmqctl命令来完成,详细介绍参考这里

下面是我实际操作的一个例子,创建了用户jiyiqin,创建了我的项目要用到的一个专用的虚拟机cProxy,然后赋予jiyiqin用户针对虚拟机cProxy的所有配置和读写权限。

注意:我的Ubuntu系统启动时会自动启动RabbitMQ broker服务。

root@ubuntu:~# rabbitmqctl add_user jiyiqin passok
Creating user "jiyiqin" ...
...done.
root@ubuntu:~# rabbitmqctl add_vhost cProxy
Creating vhost "cProxy" ...
...done.
root@ubuntu:~# rabbitmqctl set_permissions -p /cProxy jiyiqin ".*" ".*" ".*"
Setting permissions for user "jiyiqin" in vhost "/cProxy" ...
Error: no_such_vhost: /cProxy
root@ubuntu:~# rabbitmqctl list_vhosts
Listing vhosts ...
/
cProxy
test
...done.
root@ubuntu:~# rabbitmqctl set_permissions -p cProxy jiyiqin ".*" ".*" ".*"
Setting permissions for user "jiyiqin" in vhost "cProxy" ...
...done.
root@ubuntu:~# 

好了,这下就可以开始编写RabbitMQ的客户端(我的测试代码是.NET客户端),通过jiyiqin这个用户来访问RabbitMQ broker了:

发送端代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RabbitMQ.Client;

namespace RabbitMQ.SendReceive
{
    class Program
    {
        static void Main(string[] args)
        {
            //ConnectionFactory factory = new ConnectionFactory() { HostName = "192.168.1.103" };
            ConnectionFactory factory = new ConnectionFactory();
            factory.Uri = "amqp://jiyiqin:passok@192.168.1.103:5672/cProxy";
            using (IConnection conn = factory.CreateConnection())
            {
                using (IModel channel = conn.CreateModel())
                {
                    channel.QueueDeclare("hello", false, false, false, null);

                    string mesg = "hello RabbitMQ";
                    byte[] body = Encoding.UTF8.GetBytes(mesg);

                    channel.BasicPublish("", "hello", null, body);
                    Console.WriteLine(" [x] Sent {0}", mesg);
                }
            }
        }
    }
}

接收端代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;

namespace RabbitMQ.SendReceive
{
    class Program
    {
        static void Main(string[] args)
        {
            //ConnectionFactory factory = new ConnectionFactory() { HostName = "192.168.1.103" };
            ConnectionFactory factory = new ConnectionFactory();
            factory.Uri = "amqp://jiyiqin:passok@192.168.1.103:5672/cProxy";

            using (IConnection conn = factory.CreateConnection())
            {
                using (IModel channel = conn.CreateModel())
                {
                    channel.QueueDeclare("hello", false, false, false, null);

                    QueueingBasicConsumer consumer = new QueueingBasicConsumer(channel);
                    channel.BasicConsume("hello", true, consumer);
                    Console.WriteLine(" [*]Waiting for message...");

                    while (true)
                    { 
                        var queueItem = (BasicDeliverEventArgs)consumer.Queue.Dequeue();

                        byte[] body = queueItem.Body;
                        string mesg = Encoding.UTF8.GetString(body);
                        Console.WriteLine(" [x] Received {0}", mesg);
                    }
                }
            }
        }
    }
}

抱歉!评论已关闭.