Java for Web学习笔记(九二):消息和集群(7)RabbitMQ和消息模式(上)

学习目的

RabbitMQ是AMQP的一个实现。我们将跟随rabbitMQ官网上的例子,了解AMQP所支持的不同消息队列模式,以及代码如何实现。

安装RabbitMQ Server

Ubuntu自带的RabbitMQ Server,安装如下

sudo apt-get install rabbitmq-server
sudo service rabbitmq-server start
sudo rabbitmq-plugins enable rabbitmq_management 开启管理
sudo service rabbitmq-server restart
sudo rabbitmqctl add_user test 123456 添加用户test,密码为123456
sudo rabbitmqctl set_user_tags test administrator 将test为设置为administrator
sudo rabbitmqctl set_permissions -p / test ".*" ".*" ".*" 设置权限

我们打开http://localhost:15672/就可以进行rabbitmq的web界面,可以用刚配置的账号进行登录,也可以用guest进行登录。缺省的guest也是一个administrator,我们可以用它在web登录,在web上创建用户。基于安全,我们可以将缺省的guest用户删除。

sudo rabbitmqctl delete_user guest

使用RabbitMQ的java client

在pom.xml中加入

<dependency>
    <groupId>com.rabbitmq</groupId>
    <artifactId>amqp-client</artifactId>
    <version>5.0.0</version>
</dependency>

不同的队列模式

极简模式,类似FIFO

网上资料众多,我们通过抓包来了解一下各个步骤。client和server之间有多种队列模式,我们先通过最简单的方式来看看client和server之间的交互,并对一些概念有初步的了解。具体请参阅[1]

简单模式:发布者将消息放入指定的queue,接收者将消息从指定的queue中取走

publisher

/* 【1】和client和Server之间建立连接
 * client -> server:Protocol-Header 9-1,告知client支持的min version =1, max version =9
 * client <- server:Connection Start,给出server的一些情况,包括支持的验证的mechanism为AMQPLAIN和PLAIN
 * client -> server:Connection Start-OK,根据相关的账号密码,以及mechanism(小例子为PLAIN),需要注意:不要使用guest/guest账号,会报告(Login was refused using authentication mechanism PLAIN)。我们无法使用guest/guest账号在页面上登录,故认为guest的密码并发是guest,我们可以重设这个密码,或者简单地采用其他用户账号登陆即可。
 * client <- server:Connection Tune,给出tune信息,如channel-max(0),frame-max(131072),heartbeat(60)
 * client -> server:Connection Tune-OK
 * client -> server:Connection Open
 * client <- server:Connection Open-OK */
//缺省的port为5671,virtualHost为/,我们也可以通过factory.setUri("amqp://userName:password@hostName:portNumber/virtualHost")来一次性设置。
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("191.8.1.107");
factory.setUsername("test");
factory.setPassword("123456");
Connection connection = factory.newConnection();

//【2】创建channel。一个连接中,可以多条channel。从编程的角度看,对每条channel我们可以设置其某些属性,这样就不需要为每次发送或者接收进行设置。
Channel channel = connection.createChannel();

//【3】声明队列:声明队列发布到那个queue,Rabbitmq Server中的队列是client创建的,如果不存在,将创建该队列。一个channel可以发布到若干给队列,根据队列的名字(routing_key)路由,这里private final static String QUEUE_NAME = "hello";这里建立一个queue,queue的名字为“hello”,在direct模式下,只有接收者route-id也为hello才会接收到。一旦接收,消息就从队列中删除。 
channel.queueDeclare(QUEUE_NAME, false, false, false, null);

//【4】发布消息 ,当basicPublish第一个参数exchange为"",简单模式不设置此参数,第二参数为routekey,表明将放在队列hello中。 
String message = "Hello World!";
channel.basicPublish("", QUEUE_NAME, null, message.getBytes()); 

... ...

channel.close();
connection.close();

deliver

接收方的代码小例子如下
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("191.8.1.107");
factory.setUsername("test");
factory.setPassword("123456");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
//这里仍需要declare,如果recv的启动在send之前,而server上没有"hello"的队列,会报错
channel.queueDeclare(QUEUE_NAME, false, false, false, null);

Consumer consumer = new DefaultConsumer(channel){
    // handleDelivery是一个异步触发
    @Override
    public void handleDelivery(String consumerTag, Envelope envelope, BasicProperties properties, byte[] body) 
                throws IOException {
        String message = new String(body, "UTF-8");
        log.info(" [x] Received '" + message + "'");
    }                 
};
channel.basicConsume(QUEUE_NAME, true, consumer); //Start a non-nolocal, non-exclusive consumer

...同样地,结束时应该关闭  
channel.close();
connection.close();


相关链接: 我的Professional Java for Web Applications相关文章


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值