usingphp-amqplib先决条件本教程假设RabbitMQ运行在标准端口(5672)。如果您使用不同的主机、端口或凭据,则需要调整连接设置。如果您在学习本教程时遇到困难,可以通过邮件列表联系我们。在前面的教程中,我们构建了一个简单的日志系统。我们能够向许多接收者广播日志消息。要开始本教程,我们将向其添加一个功能-我们将只能订阅消息的子集。例如,我们只能将关键错误消息直接指向日志文件(以节省磁盘空间),同时仍然能够在控制台上打印所有日志消息。绑定(Bindings)在前面的例子中,我们已经创建了绑定。你可能还记得代码:$channel->queue_bind($queue_name,'logs');绑定是交换器和队列之间的关系。这可以简单理解为:队列对来自本次交换的消息感兴趣。绑定可以采用额外的routing_key参数。为了避免与$channel::basic_publish参数混淆,我们将其称为绑定键。这就是我们如何使用键创建绑定:$binding_key='black';$channel->queue_bind($queue_name,$exchange_name,$binding_key);绑定键的含义取决于交换类型。我们之前使用的fanoutexchange会忽略它的值。直接交换我们之前教程中的日志系统将所有消息广播给所有消费者。我们想扩展它以允许根据特定的严重级别过滤消息。例如,我们可能希望将日志消息写入磁盘的脚本仅接收严重错误,而不是将磁盘空间浪费在警告或信息日志消息上。我们正在使用扇出开关,它不会给我们带来很大的灵活性——它只会进行无意识的广播。我们将改用直接开关。直接交换背后的路由算法很简单——消息被传递到一个队列,该队列的绑定键与消息的路由键完全匹配。为了说明这一点,请考虑以下设置:在这个设置中,我们可以看到两个队列绑定到它的直接交换器X。第一个队列绑定了绑定密钥orange,第二个绑定有两个绑定,一个绑定了black和其他与关键绿色。在这样的设置中,向Exchange发送路由消息的路由键orange将被路由到队列Q1。带有黑色或绿色路由键的消息将转到Q2。所有其他消息将被丢弃。多重绑定用同一个绑定键绑定多个队列是完全合法的。在我们的示例中,我们可以在绑定绑定键X和Q1之间添加绑定。在这种情况下,直接交换器将充当扇出交换器并将消息发送到所有匹配的队列。向Q1和Q2发送一条路由密钥为black的消息。发出日志我们将使用这个模型作为我们的日志系统。我们会将消息发送到直接交换,而不是扇出交换。我们将提供日志严重性作为路由键。这样,接收脚本将能够选择它想要接收的严重性。让我们先关注发布日志。与往常一样,我们需要先创建一个交换:$channel->exchange_declare('direct_logs','direct',false,false,false);我们准备发送消息:$channel->exchange_declare('direct_logs','direct',false,false,false);$channel->basic_publish($msg,'direct_logs',$severity);为了简化事情,我们假设严重错误可以是信息、警告、错误。订阅接收消息将与之前的教程相同,但有一个例外-我们将为我们感兴趣的每个严重性创建一个新绑定。foreach($severitiesas$severity){$channel->queue_bind($queue_name,'direct_logs',$severity);}代码全部放一起:emit_log_direct.php源码:channel();$channel->exchange_declare('direct_logs','direct',false,false,false);$severity=isset($argv[1])&&!empty($argv[1])?$argv[1]:'info';$data=implode('',array_slice($argv,2));if(empty($data))$data="HelloWorld!";$msg=newAMQPMessage($data);$channel->basic_publish($msg,'direct_logs',$severity);echo"[x]Sent",$severity,':',$data,"\n";$channel->close();$connection->close();?>receive_logs_direct.php源码:channel();$channel->exchange_declare('direct_logs','direct',false,false,false);列表($queue_name,,)=$channel->queue_declare("",false,false,true,false);$severities=array_slice($argv,1);if(empty($severities)){file_put_contents('php://stderr',"Usage:$argv[0][info][warning][error]\n");exit(1);}foreach($severitiesas$severity){$channel->queue_bind($queue_name,'direct_logs',$severity);}echo'[*]等待日志。要退出,请按CTRL+C',"\n";$callback=function($msg){echo'[x]',$msg->delivery_info['routing_key'],':',$msg->body,"\n";};$channel->basic_consume($queue_name,'',false,true,false,false,$callback);while(count($channel->callbacks)){$channel->wait();}$channel->close();$connection->close();?>如果你只想保存警告和错误(不不包含信息)将消息记录到文件中,只需打开控制台并输入:phpreceive_logs_direct.phpwarningerror>logs_from_rabbit.log如果你想在屏幕上看到所有的日志消息,打开一个新的终端并执行:phpreceive_logs_direct.phpinfowarningerror#=>[*]Waitingforlogs。要退出按CTRL+C例如触发错误日志信息:phpemit_log_direct.phperror"Run.Run.Oritwillexplode."#=>[x]Sent'error':'Run.跑步。否则会爆炸'(全部源码emit_log_direct.php源码和receive_logs_direct.php源码)学习如何根据模式监听消息,可以看下一章:RabbitMQ+PHP教程五(专题)翻译自RabbitMQ——RabbitMQ教程-路由
