当前位置: 首页 > 后端技术 > PHP

rabbitMq

时间:2023-03-29 21:11:27 PHP

的详细介绍1.历史RabbitMQ是erlang开发的AMQP(高级消息队列)的开源实现。AMQP的出现其实是为了响应大众的需求。虽然在同步消息通信的世界里有很多开放标准(比如COBAR的IIOP,或者SOAP等),但是在异步消息处理中却不是这样。只有大型企业才有一些商业实现(如微软的MSMQ、IBM的WebsphereMQ等),所以在2006年6月,Cisco、Redhat、iMatix等联合制定了AMQP的开放标准。RabbitMQ由RabbitMQTechnologiesLtd开发并提供商业支持。该公司于2010年4月被SpringSource(VMWare的一个部门)收购。2013年5月并入Pivotal。实际上,VMWare、Pivo??tal和EMC本质上是一个家族。不同的是,VMWare是独立上市的子公司,而Pivotal则整合了EMC的部分资源,目前并未上市。RabbitMQ的官方网站是http://www.rabbitmq.com2。应用场景言归正传。RabbitMQ,或者AMQP解决什么问题,或者它的应用场景是什么?对于一个大型的软件系统,它会有很多组件或模块或子系统或(subsystemorComponentorsubmodule)。那么这些模块是如何通信的呢?这与传统的IPC有很大不同。很多传统的IPC在单一系统上,模块耦合度高,不适合扩展性(Scalability);如果使用socket的话,确实可以在不同的机器上部署不同的模块,但是还有很多问题需要解决。例如:1)信息的发送方和接收方如何保持连接?如果一方的连接中断了,这期间数据会如何丢失?2)如何降低sender和receiver之间的耦合度?3)如何让优先级高的接收者先接收到数据?4)如何实现负载均衡?有效地负载平衡接收器?5)如何高效地将数据发送给相关的接收者?也就是说,当接收者订阅不同的数据时,如何做一个有效的过滤。6)如何实现可扩展性,甚至将这个通信模块发送到集群?7)如何保证接收端接收到完整正确的数据?AMDQ协议解决了以上问题,RabbitMQ实现了AMQP。3、系统架构说是系统架构可能不太合适,说是应用场景的系统架构可能更合适。RabbitMQServer:也叫brokerserver,不是送饭的卡车,而是传输服务。原话是RabbitMQ不是快餐车,而是送货服务。他的作用是维护一条从Producer到Consumer的路由,保证数据能够按照指定的方式传输。但是这个保证不是100%的保证,但是对于一般的应用来说已经足够了。当然,对于商业系统,可以再增加一层数据一致性卫士,完全保证系统的一致性。ClientA&B:也叫Producer,数据的发送者。创建消息并将它们发布(发送)到代理服务器(RabbitMQ)。一个Message有两部分:有效负载(payload)和标签(label)。Payload,顾名思义,就是传输的数据。label是exchange的名字或者一个tag,它描述了payload,RabbitMQ也是通过这个label来决定将Message发送给哪个Consumer。AMQP只描述标签,RabbitMQ决定如何使用标签。Client1、2、3:也叫Consumer,数据的接受者。消费者连接到代理服务器(RabbitMQ)并订阅队列。将队列与命名邮箱进行比较。当消息到达邮箱时,RabbitMQ将其??发送给它的订阅者之一,即消费者。当然,可以向多个Consumers发送相同的Message。在此消息中,仅删除了有效载荷和标签。对于消费者来说,它不知道是谁发送了这个信息。即协议本身不支持。但是当然,如??果Producer发送的payload中包含Producer的信息,那就另当别论了。为了让数据从Producer正确传输到Consumer,需要明确三个概念:exchange、queues和bindings。交易所是生产者发布消息的地方。队列是消息结束并被消费者接收的地方绑定是消息如何从交换器路由到特定队列的方式。上图中还有几个概念没有标出,那就是Connection(连接),Channel(通道,通道)。连接:这是一个TCP连接。Producer和Consumer都通过TCP连接到RabbitMQServer。后面我们可以看到,程序的开始就是建立这个TCP连接。通道:虚拟连接。它建立在上述TCP连接之上。数据流在Channel中进行。也就是说一般的情况是程序开始建立TCP连接,第二步就是建立这个Channel。那么,为什么要使用Channel而不是直接使用TCP连接呢?对于操作系统而言,建立和关闭TCP连接的成本很高。TCP连接的频繁建立和关闭对系统的性能影响很大,而TCP连接的数量也是有限的,这也限制了系统处理高并发的能力。但是,在TCP连接中建立Channel没有这样的成本。对于Producer或Consumer,可以同时使用多个Channel进行Publish或Receive。实验表明,1s的数据可以发布10K的数据包。当然,对于不同的硬件环境,不同数据包大小的数据肯定是不同的,但我只是想说明一下,对于普通的消费者或者生产者来说,这就足够了。如果还不够,您应该考虑如何改进拆分设计。4.进一步的细节说明4.1使用ack确认消息的正确传递默认情况下,如果消息已被消费者正确接收,则消息将从队列中删除。当然也可以向多个Consumers发送同一个Message。如果一个队列没有被任何消费者订阅,那么如果队列中有数据到达,数据将被缓存,不会被丢弃。当有Consumer时,数据会立即发送给Consumer,当数据被Consumer正确接收后,数据会从队列中删除。那么什么是正确接收的呢?通过确认。每个消息都必须被确认(confirmation,ack)。我们可以在程序中显示ack,也可以自动ack。如果有数据没有被ack,那么:RabbitMQServer会将这个信息发送给下一个Consumer。如果app有bug忘记了ack,那么RabbitMQServer就不会再给它发送数据了,因为Server认为Consumer的处理能力有限。而且ack机制可以起到节流的作用(Benefittothrottling):在consumer处理完数据后发送ack,甚至是额外延迟后再发送ack,都会有效的平衡consumer的负载。当然,对于实际的例子,比如我们可能会合并一些数据,比如4s内合并数据,然后sleep4s再获取数据。特别是在监控系统的状态时,我们不希望所有的状态都实时传输,而是有一定的延迟。这减少了一些IO,而最终用户却感觉不到。4.2拒绝消息有两种方式,第一种Reject让RabbitMQServer将Message发送给下一个Consumer。第二种是立即从队列中删除Message。4.3创建队列Consumer和Producer都可以通过queue.declare创建队列。对于一个Channel,Consumer不能声明一个队列而是订阅其他队列。当然,你也可以创建一个私有队列。这样,只有应用本身才能使用这个队列。队列也可以自动删除,标记为自动删除的队列会在最后一个Consumer取消订阅后自动删除。那么,如果您创建一个现有队列怎么办?那么它不会有任何影响。需要注意的是没有影响,也就是说,如果第二次创建的参数和第一次不一样,那么虽然操作成功了,但是不会修改队列的属性。那么谁应该负责创建这个队列呢?是消费者还是生产者?如果队列不存在,Consumer当然得不到任何Message。但是如果队列不存在,ProducerPublish的Message会被丢弃。所以,为了不丢失数据,Consumer和Producer都尽量创建队列!反正不管怎样,这个接口都不会有问题。Queue对负载均衡的处理堪称完美。对于多个Consumer,RabbitMQ会以round-robin的方式发送给不同的Consumer。4.4Exchanges从架构图中可以看出,ProcuderPublish的Message进入Exchange。然后通过“routingkeys”,RabbitMQ会找出Message应该放在哪个queue中,queue也是通过routingkeys进行绑定的。Exchange分为三种类型:direct、fanout、topic。每个都实现不同的路由算法。·Directexchange:如果routingkey匹配,则将Message投递到对应的queue中。实际上,队列在创建的时候,会自动以队列的名字作为routingkey绑定exchange。·Fanoutexchange:广播到相应的队列。·Topicexchange:对key进行模式匹配,比如可以将ab传递给所有ab队列。4.5虚拟主机每个虚拟主机本质上是一个RabbitMQServer,有自己的queue、exchagne、bingsrule等。这保证了你可以在多个不同的应用程序中使用RabbitMQ。转载自:http://blog.csdn.net/anzhsoft...