作者文章

fwq

FWQ
Docker教程
RabbitMQ中的AMQP协议规范
一、概述 1.1 本文档的目标 此文档定义了一个网络协议-高级消息队列协议(AMQP), 它使一致的客户端程序可以与一致的消息中间件服务器进行通信. 我们面对的是这个领域有经验的技术读者,同时还提供了足够的规范和指南.技术工程师可以根据这些文档,在任何硬件平台上使用各种编程语言来构建遵从该协议的解决方案。   1.2 摘要 1.2.1 为什么使用AMQP? AMQP在一致性客户端和消息中间件(也称为”brokers”)之间创建了全功能的互操作. 我们的目标是实现一种在全行业广泛使用的标准消息中间件技术,以降低企业和系统集成的开销,并且向大众提供工业级的集成服务。 我们的宗旨是通过AMQP,让消息中间件的能力最终被网络本身所具有,并且通过消息中间件的广泛使用发展出一系列有用的应用程序. 1.2.2 AMQP范围 为了完全实现消息中间件的互操作性,需要充分定义网络协议和消息代理服务的功能语义。 因此,AMQP通过如下来定义了网络协议(AMQP是协议!)和服务端服务: 一套确定的消息交换功能,也就是“高级消息交换协议模型”。AMQP模型包括一套用于路由和存储消息的功能模块,以及一套在这些模块之间交换消息的规则 一个网络线级协议(数据传输格式),AMQP促使客户端可使用AMQ模型来与服务器交互. 可以只实现AMQP协议规范中的的部分语义,但是我们相信这些明确的语义有助于理解这个协议。 1.2.3 高级消息队列模型(AMQ 模型) 我们需要明确定义服务器语义,因为所有服务器实现都应该与这些语义保持一致性,否则就无法进行互操作.  因此AMQ 模型定义了一系列模块化组件和标准规则来进行协作. 有三种类型的组件可以连接服务器处理链来创建预期的功能:…
2024-11-24 阅读全文 →
FWQ
Docker教程
PHP中的AMQP类
一定要注意php安装AMQP的版本,版本不同使用的方法不一样。在官方网站就有2个版本的AMQP 千万不要出现这种情况,找到一个官方的版本,然后按照example,怎么调试都不通….按照PHP安装 AMQP扩展 安装的AMQP扩展是最新的,现在和PHP官方给出的第二版本,也有一些区别。主要体现在exchange和queue中有个declare的方法,分别更改成declarExchange()和declarQueue().   一、AMQPConnection ::__construct ([ array $credentials = array() ] ) 这方法比较简单,credentials的英文含义是“凭证”,但我喜欢把它理解为config。这些配置包括如下: host、vhost、port、login、password、read_timeout、write_timeout、connect_timeout,如果config省略,php会使用默认的这5个值,初始化,强烈建议带上config初始化,其中read_timeout、write_timeout、connect_timeout这三个值是最新版本才有的,PHP官方现在还没有,单位都是(秒) ::connect ( void )  、  ::pconnect ( void ) ::disconnect ( void )  …
2024-11-24 阅读全文 →
FWQ
Docker教程
RabbitMQ的原理与操作示例
AMPQ协议为了能够满足各种消息队列需求,在概念上比较复杂。首先,rabbitMQ启动默认是没有任何配置的,需要客户端连接上去,设置交换机等才能工作。不把这些基础概念弄清楚,后面程序设计就容易产生问题。   vhosts : 虚拟主机。 一个RabbitMQ的实体上可以有多个vhosts,用户与权限设置就是依附于vhosts。对一般PHP应用,不需要用户权限设定,直接使用默认就存在的”/”就可以了,用户可以使用默认就存在的”guest”。一个简单的配置示例: $conn_args = array(     'host' => '127.0.0.1',     'port' => '5672',     'login' => 'guest',     'password' => 'guest',     'vhost'=>'/' );…
2024-11-24 阅读全文 →
FWQ
Docker教程
RabbitMQ AMQP 消息模型攻略
AMQP 的消息模型如下图所示: 通过此图我们可以知道, 一个消息的发送流程有如下几个步骤: 消息生产者将消息发布(Publish)到 Exchange 中. Exchange 根据队列的绑定关系将消息分发到不同的 Queue 中. AMQP broker 根据订阅规则将消息发送给消费者 或 消费者自行根据需要从消息队列中获取消息.   Exchange 和 Exchange 类型 Exchange 的主要任务是接收消息并将消息路由到0个或多个 Queue 中, 而路由的算法受 Exchange 类型和绑定(binding) 关系的影响. AMQP 0-9-1…
2024-11-24 阅读全文 →
FWQ
Docker教程
RabbitMQ的PHP教程之入门 (一)
从网上也看了一些关于RabbitMQ的翻译版的教程,觉得有点啰嗦了。所以基于官方 http://www.rabbitmq.com/tutorials/tutorial-one-php.html做一个简单的备注说明,同时也是本人对学习RabbitMQ的一个总结。本人是从事PHP开发的,所以教程中的代码,都是使用PHP来实现,同时丢弃官网使用composer中的AMQPLIB,因为这个AMQPLIB对一些方法进行了封装,不只直观,所以本人使用原生的类、方法进行备注说明,这样更易于理解过程。   安装Rabbit参考:RabbitMQ的安装 安装Rabbit PHP扩展参考:PHP安装 AMQP扩展 PHP中的AMQP类的使用方法参考:PHP中的AMQP类 这6个教程的学习前提,你需要先了解 RabbitMQ AMQP 消息模型攻略 学习RabbitMQ必需要知道,以下几个知识点,也是RabbitMQ的灵魂: RabbitMQ是使用erlang开发,实现AMQP模型,使用mnesia数据库持久化数据。 理解Vhost、exchange、channel、queue、route key、producer、consumer,以及之间的相互关系。 理解exchange中的四种类型,direct、fanout、topic、headers。 如果能够充分理解3点,那么我觉得你已经学会RabbitMQ,接下来的6个教程,我更偏向把它理解成是RabbitMQ的应用场景,通过这六个场景的学习,能够深入我们的骨髓,在遇到技术问题的时候,我们能够恰当的选择RabbitMQ,那么我们就开始吧。 入门 本教程实现了从Producer发送消息,consumer接受消息的过程,也是RabbitMQ的基础的应用。 connect 下面的代码,将在每个.php文件,都应该有。为了简短篇幅,就在这入门篇,做统一的说明。在其他的章节中不再重复。 $config = [ 'host' => '192.168.80.122',…
2024-11-24 阅读全文 →
FWQ
Docker教程
RabbitMQ的PHP教程之工作队列 (二)
在上一篇文章中,简单实现了消息的发送与接受(参考:RabbitMQ的PHP教程之入门 (一)),但在实际的应用中,很少会使用,本人也不建议使用,因为这种隐藏式的申明,很容易给人造成困扰。但它展示了RabbitMQ的工作原理。   本人将介绍RabbitMQ work queues (工作队列),首先举例说明下工作队列的使用场景。有个高并发的某某活动,因为并发量很高,Mysql的写入的性能不能满足吞吐(其他类似于mongo的库除外),此时,可用借助RabbitMQ的工作队列来处理,将直接写入mysql的数据,以消息的形式先发送到RabbitMq的工作队列中,消费端从队列中消费数据入库,这样:1)客户端不需要考虑mysql的瓶颈,队列做为一个缓冲区。2)可用加入多个消费者,加速消费工作队列,避免造成工作队列消息积压。 我们再hello world的发送、接收的代码中,我做了几点调整。 指定exchange,并显式申明它的类型。 将exchange持久化,这样那怕Rabbit重启,exchange也不会消失。 将queue持久化,这样那怕Rabbit重启,queue也不会消失(包括queue中的消息) 在exchange  publish消息时,指定 route key,同时在queue中绑定rout key,这样exchange在转发消息时,能够将消息转发到与route key匹配的的队列中。 我们看具体的代码 send.php $conn = new \AMQPConnection($config); $conn->connect(); $channel = new…
2024-11-24 阅读全文 →
FWQ
Docker教程
RabbitMQ的PHP教程之发布/订阅 (三)
订阅模式可以理解为广播模式:即exchange会将消息转发到所有绑定到这个exchange的队列上。针对这种广播模式,RabbitMQ增加了exchange Type的选项 AMQP_EX_TYPE_FANOUT,这种类型在发送消息,queue bind时,都将忽略route key,也就是说不需要设置 route key。   举了实际应用的场景,比方说用户注册(注销,更改姓名等)新浪,同时需要开通微博、博客、邮箱等等,如果不采用队列,按照常规的线性处理,可能注册用户会特别的慢,因为在注册的时候,需要调各种其他服务器接口,如果服务很多的话,可能客户端就超时了。如果采用普通的队列,可能在处理上也会特别的慢(不是最佳方案)。如果采用订阅模式,则是最优的选择。 看下面的处理过程: 用户提交username、pwd….等之类的基本信息,将数据提交register.php中. register.php对数据进行校验,符合注册要求,生成uid,并将和基本信息json后,发布一条信息,同时直接显示用户注册成功。 exchange中的多个队列,如(queue.process、queue.boke、queue.weibo、queue.email)都接受到了这个消息,根据各业务自身的逻辑来处理。 下面来看下代码,和RabbitMQ的PHP教程之工作队列 (二) 的主要区别: 不在send.php中申明队列,因为发布 / 订阅模式下,是可以随时添加新的订阅队列。 exchange的Type指定为fanout(广播模式) 队列不需要指定route key,绑定exchange。 send.php $channel = new \AMQPChannel($conn); $channel->qos(0,0); $exchange…
2024-11-24 阅读全文 →
FWQ
Docker教程
RabbitMQ的PHP教程之Routing (四)
关于这一篇的教程,主要是针对Route Key的使用。在第二篇的文章中,我们使用direct类型的exchange实现工作队列。在这个基础之上,我们再进行一个扩展:即一个队列绑定多个route key,这样绑定多个route key的队列就能接收到不同route key的消息。但有一点是固定不变的,就是一个message只能有一个route key. 一个message最多只能有一个route key ,一个queue可以绑定多少个route key 举个实际的使用场景,日志系统(引用官方),假设产生一条日志的级别有debug, info, notice, warning, error, critical, alert, emergency八种级别(按照psr-3的日志标准,日志的级别有8个),我们希望日志消息发送到exchange后,warning, error, critical, alert, emergency转发到queue.log.error队列,notice转发到queue.log.notice队列,debug、info转发到queue.log.debug中。 此时需要使用到queue与多个route之间的绑定。 send.php $channel = new \AMQPChannel($conn);…
2024-11-24 阅读全文 →
FWQ
Docker教程
RabbitMQ的PHP教程之topic (五)
学习完了RabbitMQ的PHP教程之Routing (四),route的核心思想就是告诉我们,queue是可以绑定多少routeKey,同时接收多个routeKey的消息,在文章的末尾,我也总结exchange、routeKey、queue、message之间的对应关系 。在文中有以下几行代码:   $queue->bind('exchange.log','warning'); $queue->bind('exchange.logs','error'); $queue->bind('exchange.logs','critical'); $queue->bind('exchange.logs','alert'); $queue->bind('exchange.logs','emergency'); 我们搞PHP也知道,这种写法太过于死板。如果接收的消息routeKey很多,那我们就的一行行添加(当然你可以采用foreach循环),如果我们要对日志的来源进行再分类,比方说有register、login、mail等等,那么久需要bind很多的routeKey,大概会如下: $queue->bind('exchange.log','register.warning'); $queue->bind('exchange.logs','register.error'); $queue->bind('exchange.logs','register.critical'); $queue->bind('exchange.logs','register.alert'); $queue->bind('exchange.logs','register.emergency'); ....... $queue->bind('exchange.log','mail.warning'); $queue->bind('exchange.logs','mail.error'); $queue->bind('exchange.logs','mail.critical'); $queue->bind('exchange.logs','mail.alert'); $queue->bind('exchange.logs','mail.emergency'); 那么我们有没有一种办法来处理这种情况呢,这就是本章的学习的exchange中topic类型。 使用topic类型后,routKey支持模糊匹配,但仅支持以下2种写法: *(星号)可以代表一个单词 #(井号)可以代表零个或多个单词 //请务必注意是单词,此时的routeKey是使用.链接的字符串。 我还是举例说明吧,假设我们有一个需求,需要对日志的来源进行分类处理。 不管是从register、login还是mail中,warning,…
2024-11-24 阅读全文 →