RabbitMQ 实战教程



1、简介
    MQ(Message Queue)消息队列,用于应用系统解耦、消息异步分发。
    RabbitMQ是一个在AMQP基础上完整的,可复用的企业消息系统。
    其优点如下。
1)Reliability-可靠性高。
2)Flexible Routing-路由灵活。
3)Clustering-支持集群。
4)Federation-支持互联。
5)Tracing-便于追踪。
    本文档是关于RabbitMQ的安装与使用实践。
    实践环境:Window7 x64系统。

2、Erlang安装
    RabbitMQ由ERLANG实现,故需要安装Erlang。
1)下载Erlang
    下载官网:
http://www.erlang.org/download.html
    实践安装版本:otp_win32_17.4.exe。
2)安装Erlang
    运行Exe按照提示一路Next安装下来。
3)配置Erlang
    本机安装目录:C:\Program Files (x86)\erl6.3。
    环境变量Path中添加C:\Program Files (x86)\erl6.3\bin。

4)检测Erlang
    命令行中输入erl命令可检测Erlang是否安装成功。

3、RabbitMQ安装
    对应RabbitMQ的版本为V3.4.3。
1)下载RabbitMQ
    对应官网:http://www.rabbitmq.com/download.html
    下载安装包:rabbitmq-server-3.4.3.exe。
2)安装RabbitMQ
    运行Exe,一路Next安装完毕。
3)安装完成查看

4、RabbitMQ启动

1)启动管理插件
    运行RabbitMQ Command Prompt(sbin dir)。
    输入rabbitmq-plugins enable rabbitmq_management,启动管理插件。

2)启动管理服务
    运行RabbitMQ Service - start。
3)登录管理界面
    浏览器输入:http://localhost:15672/#/。

    用户名:guest,密码guest。


5、消息发送代码
    示例代码采用Java,对应IDE为Eclipse。
    Java需要用到RabbitMQ的jar包。
    jar包下载地址:http://www.rabbitmq.com/java-client.html。
    对应版本与Rabbit Server一致V3.4.3。

    发送代码见Send.java。

  1. import java.io.IOException;  
  2. import com.rabbitmq.client.Channel;    
  3. import com.rabbitmq.client.Connection;    
  4. import com.rabbitmq.client.ConnectionFactory;    
  5.   
  6. public class Send {    
  7.     private final static String QUEUE_NAME = "rabbit";  
  8.       
  9.     public static void main(String[] args) throws IOException {    
  10.         ConnectionFactory factory = new ConnectionFactory();  
  11.         factory.setHost("127.0.0.1");  
  12.         factory.setPort(5672);  
  13.         factory.setUsername("guest");  
  14.         factory.setPassword("guest");  
  15.         Connection connection = factory.newConnection();  
  16.         Channel channel = connection.createChannel();  
  17.           
  18.         channel.queueDeclare(QUEUE_NAME, falsefalsefalsenull);    
  19.         String message = "Hello Rabbit!";    
  20.         channel.basicPublish("", QUEUE_NAME, null, message.getBytes());    
  21.         System.out.println(" [x] Sent '" + message + "'");  
  22.           
  23.         channel.close();    
  24.         connection.close();    
  25.     }    
  26. }  
import java.io.IOException;
import com.rabbitmq.client.Channel;  
import com.rabbitmq.client.Connection;  
import com.rabbitmq.client.ConnectionFactory;  

public class Send {  
    private final static String QUEUE_NAME = "rabbit";
    
    public static void main(String[] args) throws IOException {  
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("127.0.0.1");
        factory.setPort(5672);
        factory.setUsername("guest");
        factory.setPassword("guest");
        Connection connection = factory.newConnection();
        Channel channel = connection.createChannel();
        
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);  
        String message = "Hello Rabbit!";  
        channel.basicPublish("", QUEUE_NAME, null, message.getBytes());  
        System.out.println(" [x] Sent '" + message + "'");
        
        channel.close();  
        connection.close();  
    }  
}

    运行结束结果。
    打印出: [x] Sent 'Hello Rabbit!'。

    进入管理界面,可以看到已经创建了一个名叫rabbit的消息队列,,消息Ready标志为1。


6、消息接受代码
    对应程序代码Recv.java。

  1. import com.rabbitmq.client.Channel;    
  2. import com.rabbitmq.client.Connection;    
  3. import com.rabbitmq.client.ConnectionFactory;    
  4. import com.rabbitmq.client.QueueingConsumer;    
  5.   
  6. public class Reqv {    
  7.     private final static String QUEUE_NAME = "rabbit";  
  8.       
  9.     public static void main(String[] argv) throws Exception {    
  10.     
  11.         ConnectionFactory factory = new ConnectionFactory();  
  12.         factory.setHost("localhost");  
  13.         factory.setPort(5672);  
  14.         factory.setUsername("guest");  
  15.         factory.setPassword("guest");  
  16.         Connection connection = factory.newConnection();    
  17.         Channel channel = connection.createChannel();  
  18.           
  19.         channel.queueDeclare(QUEUE_NAME, falsefalsefalsenull);  
  20.         QueueingConsumer consumer = new QueueingConsumer(channel);    
  21.         channel.basicConsume(QUEUE_NAME, true, consumer);  
  22.           
  23.         while (true) {    
  24.             QueueingConsumer.Delivery delivery = consumer.nextDelivery();    
  25.             String message = new String(delivery.getBody());    
  26.             System.out.println(" [x] Received '" + message + "'");    
  27.         }    
  28.     }  
  29. }  
import com.rabbitmq.client.Channel;  
import com.rabbitmq.client.Connection;  
import com.rabbitmq.client.ConnectionFactory;  
import com.rabbitmq.client.QueueingConsumer;  

public class Reqv {  
    private final static String QUEUE_NAME = "rabbit";
    
    public static void main(String[] argv) throws Exception {  
  
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("localhost");
        factory.setPort(5672);
        factory.setUsername("guest");
        factory.setPassword("guest");
        Connection connection = factory.newConnection();  
        Channel channel = connection.createChannel();
        
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);
        QueueingConsumer consumer = new QueueingConsumer(channel);  
        channel.basicConsume(QUEUE_NAME, true, consumer);
        
        while (true) {  
            QueueingConsumer.Delivery delivery = consumer.nextDelivery();  
            String message = new String(delivery.getBody());  
            System.out.println(" [x] Received '" + message + "'");  
        }  
    }
}

    运行结果,打印如下。
     [x] Received 'Hello Rabbit!'
    进入管理端界面查看,消息Ready标志为0。

7、总结
    通过实践,感觉RabbitMQ简单易用,支持消息的异步发送,可以解耦两个强关联的应用系统。


示例二:

MQ是消费-生产者模型的一个典型的代表,一端往消息队列中不断写入消息,而另一端则可以读取或者订阅队列中的消息。RabbitMQ是信息传输的中间者。本质上,他从生产者接收消息,转发这些消息给消费者。换句话说,RabbitMQ能够按根据你指定的规则进行消息转发、缓冲、和持久化。

在项目中,将一些无需即时返回且耗时的操作提取出来,进行了异步处理,而这种异步处理的方式大大的节省了服务器的请求响应时间,从而提高了系统的吞吐量。

常见术语

producer(生产者),consumer(消费者),broker(RabbitMQ服务)并不需要部署在同一台机器上,实际上在大多数实际的应用中,也不会部署在同一台机器上。

生产者(Producer)

一个发送消息的程序是一个producer(生产者)。
一般用下图表示生产者:

队列(Queue)

队列类似邮箱。依存于RabbitMQ内部。虽然消息通过RabbitMQ在你的应用中传递,但是它们只能存储在队列中。队列不受任何限制,可以存储任何数量的消息—本质上是一个无限制的缓存。不同的生产者可以通过同一个队列发送消息,此外,不同的消费者也可以从同一个队列上接收消息。
一般用下图表示队列:

消费者(Consumer)

消费者属于等待接收消息的程序。
一般使用下图表示消费者:

案例实战

准备工作

使用Maven进行管理

 
  1. <dependency>
  2. <groupId>com.rabbitmq</groupId>
  3. <artifactId>amqp-client</artifactId>
  4. <version>3.6.3</version>
  5. </dependency>

发送端

发送端,连接到RabbitMQ(此时服务需要启动),发送一条数据,然后退出。

 
  1. package com.lianggzone.rabbitmq.demo.helloworld;
  2.  
  3. import java.io.IOException;
  4. import java.util.concurrent.TimeoutException;
  5. import com.rabbitmq.client.Channel;
  6. import com.rabbitmq.client.Connection;
  7. import com.rabbitmq.client.ConnectionFactory;
  8.  
  9. public class Send {
  10. private final static String QUEUE_NAME = "hello";
  11. public static void main(String[] args) throws IOException, TimeoutException {
  12. // 创建连接
  13. ConnectionFactory factory = new ConnectionFactory();
  14. // 设置MabbitMQ, 主机ip或者主机名
  15. factory.setHost("localhost");
  16. // 创建一个连接
  17. Connection connection = factory.newConnection();
  18. // 创建一个通道
  19. Channel channel = connection.createChannel();
  20. // 指定一个队列
  21. channel.queueDeclare(QUEUE_NAME, false, false, false, null);
  22. // 发送消息
  23. String message = "Hello World!";
  24. channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
  25. System.out.println(" [x] Sent '" + message + "'");
  26. // 关闭频道和连接
  27. channel.close();
  28. connection.close();
  29. }
  30. }

接受端

接受端,不断等待服务器推送消息,然后在控制台输出。

 
  1. package com.lianggzone.rabbitmq.demo.helloworld;
  2.  
  3. import java.io.IOException;
  4. import java.util.concurrent.TimeoutException;
  5.  
  6. import com.rabbitmq.client.AMQP;
  7. import com.rabbitmq.client.Channel;
  8. import com.rabbitmq.client.Connection;
  9. import com.rabbitmq.client.ConnectionFactory;
  10. import com.rabbitmq.client.Consumer;
  11. import com.rabbitmq.client.DefaultConsumer;
  12. import com.rabbitmq.client.Envelope;
  13.  
  14. public class Recv {
  15. private final static String QUEUE_NAME = "hello";
  16. public static void main(String[] args) throws IOException, TimeoutException {
  17. // 创建连接
  18. ConnectionFactory factory = new ConnectionFactory();
  19. // 设置MabbitMQ, 主机ip或者主机名
  20. factory.setHost("localhost");
  21. // 创建一个连接
  22. Connection connection = factory.newConnection();
  23. // 创建一个通道
  24. Channel channel = connection.createChannel();
  25. // 指定一个队列
  26. channel.queueDeclare(QUEUE_NAME, false, false, false, null);
  27. System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
  28. // 创建队列消费者
  29. Consumer consumer = new DefaultConsumer(channel) {
  30. @Override
  31. public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties,
  32. byte[] body) throws IOException {
  33. String message = new String(body, "UTF-8");
  34. System.out.println(" [x] Received '" + message + "'");
  35. }
  36. };
  37. channel.basicConsume(QUEUE_NAME, true, consumer);
  38. }
  39. }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值