没有合适的资源?快使用搜索试试~ 我知道了~
资源详情
资源评论
资源推荐
AMQP 概论
AMQP
是应用层协议的一个开放标准,为面向消息的中间件设计。基于此协议的客户端与消息
中间件可传递消息,并不受客户端/中间件不同产品,不同的开发语言等条件的限制。目标
是实现一种在全行业广泛使用的标准消息中间件技术,以便降低企业和系统集成的开销,并
且向大众提供工业级的集成服务。主要实现有 RabbitMQ。
包括的要素
生产者、消费者、消息
生产者:消息的创建者,发送到 rabbitmq;
消费者:连接到 rabbitmq,订阅到队列上,消费消息,持续订阅(basicConsumer)和单条
订阅(basicGet).
消息:包含有效载荷和标签,有效载荷指要传输的数据,,标签描述了有效载荷,并且
rabbitmq 用它来决定谁获得消息,消费者只能拿到有效载荷,并不知道生产者是谁。
信道
信道,概念:信道是生产消费者与 rabbit 通信的渠道,生产者 publish 或是消费者 subscribe
一个队列都是通过信道来通信的。信道是建立在 TCP 连接上的虚拟连接,什么意思呢?就是
说 rabbitmq 在一条 TCP 上建立成百上千个信道来达到多个线程处理,这个 TCP 被多个线程
共享,每个线程对应一个信道,信道在 rabbit 都有唯一的 ID ,保证了信道私有性,对应上唯
一的线程使用。
疑问:为什么不建立多个 TCP 连接呢?原因是 rabbit 保证性能,系统为每个线程开辟一
个 TCP 是非常消耗性能,每秒成百上千的建立销毁 TCP 会严重消耗系统。所以 rabbitmq 选
择建立多个信道(建立在 tcp 的虚拟连接)连接到 rabbit 上。
交换器、队列、绑定、路由键
队列通过路由键(routing key,某种确定的规则)绑定到交换器,生产者将消息发布
到交换器,交换器根据绑定的路由键将消息路由到特定队列,然后由订阅这个队列的消费者
进行接收。
常见问题
如果消息达到无人订阅的队列会怎么办?消息会一直在队列中等待,RabbitMq 默认队
列是无限长度的。
多个消费者订阅到同一队列怎么办?消息以循环的方式发送给消费者,每个消息只会
发送给一个消费者。
消息路由到了不存在的队列怎么办?一般情况下,凉拌,RabbitMq 会忽略,当这个消
息不存在,也就是这消息丢了。
消息的确认
消费者收到的每一条消息都必须进行确认(自动确认和自行确认)。
消费者在声明队列时,可以指定 autoAck 参数,当 autoAck=false 时,RabbitMQ 会等待
消费者显式发回 ack 信号后才从内存(和磁盘,如果是持久化消息的话)中移去消息。否则,
RabbitMQ 会在队列中消息被消费后立即删除它。
采用消息确认机制后,只要令 autoAck=false,消费者就有足够的时间处理消息(任务),
不用担心处理消息过程中消费者进程挂掉后消息丢失的问题,因为 RabbitMQ 会一直持有消
息直到消费者显式调用 basicAck 为止。
当 autoAck=false 时,对于 RabbitMQ 服务器端而言,队列中的消息分成了两部分:一部
分是等待投递给消费者的消息;一部分是已经投递给消费者,但是还没有收到消费者 ack 信
号的消息。如果服务器端一直没有收到消费者的 ack 信号,并且消费此消息的消费者已经断
开连接,则服务器端会安排该消息重新进入队列,等待投递给下一个消费者(也可能还是原
来的那个消费者)。
RabbitMQ 不会为未 ack 的消息设置超时时间,它判断此消息是否需要重新投递给消费
者的唯一依据是消费该消息的消费者连接是否已经断开。这么设计的原因是 RabbitMQ 允许
消费者消费一条消息的时间可以很久很久。
交换器类型
共有四种 direct,fanout,topic,headers,其种 headers(几乎和 direct 一样)不实用,可以忽
略。
Direct
路由键完全匹配,消息被投递到对应的队列,每个 amqp 的实现都必须有一个 direct 交
换器,包含一个空白字符串名称的默认交换器。声明一个队列时,会自动绑定到默认交换器,
并且以队列名称作为路由键:channel->basic_public($msg,’ ’,’queue-name’)
Fanout
消息广播到绑定的队列
Topic
通过使用“*”和“#”,使来自不同源头的消息到达同一个队列,”.”将路由键分为了
几个标识符,“*”匹配 1 个,“#”匹配一个或多个。例如日志处理:
假设有交换器 log-exchange,
日志级别有 error,info,warning,
应用模块有 user,order,email,
服务器有 A、B、C、D
路由键的规则为 服务器+“.”+日志级别+“.”+应用模块名,如:A. info .email。
1、要关注 A 服务器发送的所有应用错误的消息,怎么做?
声明队列名称为“a-app-error-queue”并绑定到交换器上:channel. queueBind
(‘a-app-error-queue’,’logs-change’,’A.error.*’)
2、关注 B 服务器发送的的所有日志,怎么办?
声明队列名称为“b-all-queue”并绑定到交换器上:channel. queueBind
(b-all-queue’,’logs-change’,’ B.#’)或 channel. queueBind (b-all-queue’,’logs-change’,’ B.*.*’)
3、关注所有服务器发送的 email 的所有日志,怎么办?
声明队列名称为“email-all-queue”并绑定到交换器上:channel. queueBind (email
-all-queue’,’logs-change’,’ *.*.emal’)
4、想要接收所有日志:channel->queue_bind(‘all-log’,’logs-change’,’#’)
虚拟主机
虚拟消息服务器,vhost,本质上就是一个 mini 版的 mq 服务器,有自己的队列、交换
器和绑定,最重要的,自己的权限机制。Vhost 提供了逻辑上的分离,可以将众多客户端进
行区分,又可以避免队列和交换器的命名冲突。Vhost 必须在连接时指定,rabbitmq 包含缺
省 vhost:“/”,通过缺省用户和口令 guest 进行访问。
rabbitmq 里创建用户,必须要被指派给至少一个 vhost,并且只能访问被指派内的队列、
交换器和绑定。Vhost 必须通过 rabbitmq 的管理控制工具创建。
RabbitMQ 在 Windows 下安装和运行
1、下载 Erlang:
http://www.erlang.org/downloads/19.2
2、下载 Windows 版 RabbitMq:
http://www.rabbitmq.com/releases/rabbitmq-server/v3.6.6/rabbitmq-server-3.6.6.exe
3、安装并配置环境变量:
增加变量 ERLANG_HOME C:\Program Files\erl8.2
path 下添加 %ERLANG_HOME%\bin,如
增加变量 RABBITMQ_BASE C:\Program Files\RabbitMQ Server\rabbitmq_server-3.6.6
path 下添加 %RABBITMQ_BASE%\sbin;%RABBITMQ_BASE%\ebin
4、在开始菜单中启动服务
5、可以在安装目录的 sbin 下运行 rabbitmqctl.bat status 检测是否安装成功
原生 Java 客户端进行消息通信
Direct
参见代码 no-spring 模块包 cn.enjoyedu.exchange.direct 中:
DirectProducer:direct
类型交换器的生产者
NormalConsumer:
普通的消费者
MulitBindConsumer:
队列绑定到交换器上时,是允许绑定多个路由键的,也就是多重
绑定
MulitChannelConsumer:
一个连接下允许有多个信道
MulitConsumerOneQueue:
一个队列多个消费者,则会表现出消息在消费者之间的轮询
发送。
Fanout
消息广播到绑定的队列
参见代码 no-spring 模块包 cn.enjoyedu.exchange.fanout 中:
通过测试表明,不管我们如何调整生产者和消费者的路由键,都对消息的接受没有影响。
Topic
参见代码 no-spring 模块包 cn.enjoyedu.exchange.topic 中:
通过使用“*”和“#”,使来自不同源头的消息到达同一个队列,”.”将路由键分为了
几个标识符,“*”匹配 1 个,“#”匹配一个或多个。例如日志处理:
假设有交换器 log-exchange,
日志级别有 error,info,warning,
应用模块有 user,order,email,
服务器有 A、B、C、D
路由键的规则为 服务器+“.”+日志级别+“.”+应用模块名,如:A. info .email。
1、要关注 A 服务器发送的所有应用错误的消息,怎么做?
声明队列名称为“a-app-error-queue”并绑定到交换器上:channel. queueBind
(‘a-app-error-queue’,’logs-change’,’A.error.*’)
2、关注 B 服务器发送的的所有日志,怎么办?
声明队列名称为“b-all-queue”并绑定到交换器上:channel. queueBind
(b-all-queue’,’logs-change’,’ B.#’)或 channel. queueBind (b-all-queue’,’logs-change’,’ B.*.*’)
3、关注所有服务器发送的 email 的所有日志,怎么办?
声明队列名称为“email-all-queue”并绑定到交换器上:channel. queueBind (email
-all-queue’,’logs-change’,’ *.*.emal’)
剩余28页未读,继续阅读
萌新小白爱学习
- 粉丝: 16
- 资源: 311
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论0