概述
RabbitMQ入门到精通,作为RabbitMQ入门是一个很好的范例.
RabbitMQ是一个由erlang开发的AMQP(Advanced Message Queue )的开源实现,是一种应用程序对应用程序的通信方法.应用程序通过读写出入队列的消息(针对应用程序的数据)来通信,而无需专用连接来链接它们.目前类似于RabbitMQ的消息中间件有很多, RabbitMq、ActiveMq、ZeroMq、kafka都是可选择,RabbitMQ解决的问题
- 信息的发送者和接收者如何维持这个连接,如果一方的连接中断,这期间的数据如何方式丢失
- 如何降低发送者和接收者的耦合度
- 如何让Priority高的接收者先接到数据
- 如何做到load balance?有效均衡接收者的负载
- 如何有效的将数据发送到相关的接收者?也就是说将接收者subscribe 不同的数据,如何做有效的filter
- 如何做到可扩展,甚至将这个通信模块发到cluster上
- 如何保证接收者接收到了完整,正确的数据
RabbitMQ基本概念
架构
名词解释:
- RabbitMQ Server: RabbitMQ 服务核心,是一种投递服务,在应用程序(生成者)与服务器(消费者)之间扮演着路由器的角色,接收生成者消息,同时将消费者路由至消费者
- ClientA&B:生成者,生成消息,消息的构成:有效载荷payload(数据的载体),标签label(描述payload,包含消费者相关信息)
- Client1&2&3:消费者,消费消息(注:消息到达消费者时,其label已经清空,也就是消费者不能识别消息来自何处)
RabbitMQ server 构成
- Connection:TCP连接.生成者与消费者通过TCP与RabbitMQ连接
- Channel:信道,虚拟连接,一个Connection下可建立无数Channel,消息在Channel中进行传输(Channel节约通信开销,提高性能,Connection比喻成电缆,Channel就是独立光纤)
- Exchange&Binding&Queue:交换,绑定,队列.AMQP的三大构成要素.生产者把消息发布到交换器上,消息最终到达队列,并被消费者接收,绑定决定了消息如何从路由器路由到特定的队列.交换器分
- vhost:一个vhost对应一个独立的RabbitMQ Server,实现逻辑上的分离,互相干扰
概念补充:
Exchange
一个消息的传递
- 生成者发布Messgae至Exchange,指定RootingKey(或者为空串),同时绑定Queue(也绑定RootingKey 与Message 中的RootingKey匹配)--queue需提前申明创建
- 消费者读取Queue中Message进行消费(1.进行消息确认,消息从Queue中删除2.转发,消息转移至下一个消费者3.拒绝,消息删除或转发)
Exchange 有三种类型:direct, fanout,topic,还有一种header
- Direct : 直连,通过RoutingKey匹配Queue
- Fanout:广播,忽略RoutingKey匹配,发送至所有Queue
- Topic:规则匹配.按照一定的规则匹配RoutingKey
- header:用键值对取代RootingKey进行匹配
安装好的RabbitMQ有几个默认Exchange(好像是8个)
RabbitMQ安装
window下安装RabbitMQ
- 下载Erlang,安装(exe直接安装,zip安装需要配系统变量ERLANG_HOME)
- 下载RabbitMQ.下一步安装...
- 激活RabbitMQ管理插件,cmd 执行"C:\Program Files\RabbitMQ Server\rabbitmq_server-3.6.6\sbin\rabbitmq-plugins.bat" enable rabbitmq_management
- 重启RabbitMQ cmd执行net stop RabbitMQ && net start RabbitMQ
- 访问http://localhost:15672 使用guest/guest(guest账户在localhost下具有所有权限)登录进入ui界面
RabbitMQ基本使用
为方便测试使用ui创建一个全权限账户zl/123(也可以使用
RabbitMQ 命令)
Direct
package producerAndconsume;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.TimeUnit;
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.QueueingConsumer;
/**
* Hello world!
*
*/
public class DirectMQ
{
//交换器名称
public final static String EXCHANGE_NAME = "test.amq.dir