1.生产者代码
<?php
namespace app\ controller ;
use app\ BaseController ;
use PhpAmqpLib\ Connection\ AMQPStreamConnection ;
use PhpAmqpLib\ Message\ AMQPMessage ;
use PhpAmqpLib\ Wire\ AMQPTable ;
use think\ facade\ Cache ;
class RabbitMq extends BaseController
{
public function send ( )
{
$queue = "hello_durable_true" ;
$connection = new AMQPStreamConnection ( "localhost" , '5672' , 'guest' , 'guest' , '/' ) ;
$channel = $connection - > channel ( ) ;
$channel - > queue_declare ( $queue , false , true , false , false ) ;
for ( $i = 0 ; $i < 5 ; $i ++ ) {
sleep ( 1 ) ;
$messageBody = "hello,努力,Now time:" . date ( "Y-m-d H:i:s" ) ;
$message = new AMQPMessage ( $messageBody , array ( "content_type" = > "text/plain" , "delivery_mode" = > AMQPMessage: : DELIVERY_MODE_PERSISTENT ) ) ;
$channel - > basic_publish ( $message , '' , $queue ) ;
echo "send Message" . $i . "<br>\n" ;
}
$channel - > close ( ) ;
$connection - > close ( ) ;
return "send success" ;
}
public function send1 ( )
{
$exchange = "logs" ;
$connection = new AMQPStreamConnection ( "localhost" , "5672" , "guest" , "guest" , "/" ) ;
$channel = $connection - > channel ( ) ;
$channel - > exchange_declare ( $exchange , "fanout" , false , false , false ) ;
for ( $i = 0 ; $i < 5 ; $i ++ ) {
sleep ( 1 ) ;
$messageBody = "hello,努力,Now time:" . date ( "Y-m-d H:i:s" ) ;
$message = new AMQPMessage ( $messageBody , array (
"content_type" = > "text/plain" ,
"delivery_mode" = > AMQPMessage: : DELIVERY_MODE_PERSISTENT
) ) ;
$channel - > basic_publish ( $message , $exchange ) ;
echo "Send exchange message:" . $i . "<br>\n" ;
}
$channel - > close ( ) ;
$connection - > close ( ) ;
return "Send Sueccess" ;
}
public function direct ( )
{
$exchange = "direct_logs" ;
$connection = new AMQPStreamConnection ( "127.0.0.1" , "5672" , "guest" , "guest" , "/" ) ;
$channel = $connection - > channel ( ) ;
$channel - > exchange_declare ( $exchange , "direct" , false , false , false ) ;
$messageBody = "error,Now Time:" . date ( "Y-m-d H:i:s" ) ;
$message = new AMQPMessage ( $messageBody , array (
'content_type' = > 'text/plain' ,
'delivery_mode' = > AMQPMessage: : DELIVERY_MODE_PERSISTENT
) ) ;
$channel - > basic_publish ( $message , $exchange , "error" ) ;
$messageBody = "warning, Now Time:" . date ( "h:i:s" ) ;
$message = new AMQPMessage ( $messageBody , array (
'content_type' = > 'text/plain' ,
'delivery_mode' = > AMQPMessage: : DELIVERY_MODE_PERSISTENT ) ) ;
$channel - > basic_publish ( $message , $exchange , "warning" ) ;
$channel - > close ( ) ;
$connection - > close ( ) ;
return 'Send Success' ;
}
public function rpc ( )
{
$connection = new AMQPStreamConnection ( "localhost" , "5672" , "guest" , "guest" , "/" ) ;
$channel = $connection - > channel ( ) ;
list ( $callback_queue , , ) = $channel - > queue_declare ( "callback_queue" , false , false , true , false ) ;
$corr_id = uniqid ( ) ;
$msg = new AMQPMessage ( "rpc client send message" , array (
"correlation_id" = > $corr_id ,
'reply_to' = > $callback_queue
) ) ;
$channel - > basic_publish ( $msg , '' , 'rpc_queue' ) ;
$response = null ;
$channel - > basic_consume ( $callback_queue , '' , false , false , false , false , function ( $reply ) use ( $corr_id , & $response ) {
if ( $reply - > get ( "correlation_id" ) == $corr_id ) {
$response = $reply - > body ;
}
$reply - > delivery_info [ 'channel' ] - > basic_ack ( $reply - > delivery_info [ 'delivery_tag' ] ) ;
} ) ;
while ( ! $response ) {
$channel - > wait ( ) ;
}
var_dump ( $response ) ;
$channel - > close ( ) ;
$connection - > close ( ) ;
}
public function delay ( ) {
$connection = new AMQPStreamConnection ( "localhost" , "5672" , "guest" , "guest" , "/" ) ;
$channel = $connection - > channel ( ) ;
$channel - > exchange_declare ( "dlx_exchange" , "direct" , false , false , false ) ;
$channel - > queue_declare ( "dlx_queue" , false , true , false , false ) ;
$channel - > queue_bind ( "dlx_queue" , "dlx_exchange" , "dlx_routing_key" ) ;
$channel - > exchange_declare ( "delay_exchange" , 'direct' , false , false , false ) ;
$args = new AMQPTable ( ) ;
$args - > set ( 'x-message-ttl' , 5000 ) ;
$args - > set ( "x-max-length" , 1 ) ;
$args - > set ( 'x-dead-letter-exchange' , 'dlx_exchange' ) ;
$args - > set ( 'x-dead-letter-routing-key' , "dlx_routing_key" ) ;
$channel - > queue_declare ( "delay_queue" , false , true , false , false , false , $args ) ;
$channel - > queue_bind ( "delay_queue" , "delay_exchange" , "delay_routing_key" ) ;
$messageBody = "该消息将在5s后发送到延迟队列(" . date ( "h:i:s" ) . ")" ;
$message = new AMQPMessage ( $messageBody , array (
'content_type' = > 'text/plain' ,
'delivery_mode' = > AMQPMessage: : DELIVERY_MODE_PERSISTENT ) ) ;
$channel - > basic_publish ( $message , "delay_exchange" , "delay_routing_key" ) ;
$channel - > close ( ) ;
$connection - > close ( ) ;
return 'Send Success' ;
}
public function retry ( )
{
$connection = new AMQPStreamConnection ( "localhost" , "5672" , "guest" , "guest" , "/" ) ;
$channel = $connection - > channel ( ) ;
$channel - > exchange_declare ( "dlx_exchange" , "direct" , false , false , false ) ;
$channel - > queue_declare ( "dlx_queue" , false , true , false , false ) ;
$channel - > queue_bind ( "dlx_queue" , "dlx_exchange" , "dlx_routing_key" ) ;
$channel - > exchange_declare ( "delay_exchange" , "direct" , false , false , false ) ;
$args = new AMQPTable ( ) ;
$args - > set ( 'x-message-ttl' , 5000 ) ;
$args - > set ( 'x-dead-letter-exchange' , 'dlx_exchange' ) ;
$args - > set ( 'x-dead-letter-routing-key' , 'dlx_routing_key' ) ;
$channel - > queue_declare ( "delay_queue" , false , true , false , false , false , $args ) ;
$channel - > queue_bind ( "delay_queue" , "delay_exchange" , "delay_routing_key" ) ;
$messageBody = "该消息将在5s后发送到延迟队列(" . date ( "h:i:s" ) . ")" ;
$message = new AMQPMessage ( $messageBody , array (
'content_type' = > 'text/plain' ,
'delivery_mode' = > AMQPMessage: : DELIVERY_MODE_PERSISTENT ) ) ;
$headers = new AMQPTable ( [
"retry_nums" = > 0
] ) ;
$message - > set ( 'application_headers' , $headers ) ;
$channel - > basic_publish ( $message , "delay_exchange" , "delay_routing_key" ) ;
$channel - > close ( ) ;
$connection - > close ( ) ;
return 'Send Success' ;
}
public function idempotent ( )
{
$connection = new AMQPStreamConnection ( "localhost" , "5672" , "guest" , "guest" , "/" ) ;
$channel = $connection - > channel ( ) ;
$channel - > exchange_declare ( "dlx_exchange1" , "direct" , false , false , false ) ;
$channel - > queue_declare ( "dlx_queue1" , false , true , false , false ) ;
$channel - > queue_bind ( "dlx_queue1" , "dlx_exchange1" , "dlx_routing_key1" ) ;
$channel - > exchange_declare ( "delay_exchange1" , "direct" , false , false , false ) ;
$args = new AMQPTable ( ) ;
$args - > set ( 'x-message-ttl' , 5000 ) ;
$args - > set ( 'x-dead-letter-exchange' , 'dlx_exchange1' ) ;
$args - > set ( 'x-dead-letter-routing-key' , 'dlx_routing_key1' ) ;
$channel - > queue_declare ( "delay_queue1" , false , true , false , false , false , $args ) ;
$channel - > queue_bind ( "delay_queue1" , "delay_exchange1" , "delay_routing_key1" ) ;
$messageBody = "重复消息发送(" . date ( "h:i:s" ) . ")" ;
$message = new AMQPMessage ( $messageBody , array (
'content_type' = > 'text/plain' ,
'delivery_mode' = > AMQPMessage: : DELIVERY_MODE_PERSISTENT ) ) ;
$corr_id = uniqid ( ) ;
$headers = new AMQPTable ( [
"correlation_id" = > $corr_id
] ) ;
$message - > set ( 'application_headers' , $headers ) ;
Cache: : set ( $corr_id , $corr_id , 3600 ) ;
$channel - > basic_publish ( $message , "delay_exchange1" , "delay_routing_key1" ) ;
$channel - > basic_publish ( $message , "delay_exchange1" , "delay_routing_key1" ) ;
$channel - > close ( ) ;
$connection - > close ( ) ;
return 'Send Success' ;
}
}
2.消费者代码
2.1 消费幂等性代码
<?php
namespace app\ command ;
use PhpAmqpLib\ Connection\ AMQPStreamConnection ;
use PhpAmqpLib\ Wire\ AMQPTable ;
use think\ console\ Command ;
use think\ console\ Input ;
use think\ console\ input\ Argument ;
use think\ console\ input\ Option ;
use think\ console\ Output ;
use think\ facade\ Cache ;
class Idempotentnd extends Command
{
protected function configure ( )
{
$this - > setName ( 'idempotent' )
- > setDescription ( 'the idempotent command' ) ;
}
protected function execute ( Input $input , Output $output )
{
$exchange = "dlx_exchange1" ;
$connection = new AMQPStreamConnection ( "localhost" , "5672" , "guest" , "guest" , "/" ) ;
$channel = $connection - > channel ( ) ;
$channel - > exchange_declare ( $exchange , 'direct' , false , false , false ) ;
$channel - > queue_declare ( "dlx_queue1" , false , true , false , false ) ;
$channel - > queue_bind ( "dlx_queue1" , $exchange , "dlx_routing_key1" ) ;
$channel - > exchange_declare ( "delay_exchange1" , "direct" , false , false , false ) ;
$args = new AMQPTable ( ) ;
$args - > set ( 'x-message-ttl' , 5000 ) ;
$args - > set ( 'x-dead-letter-exchange' , 'dlx_exchange1' ) ;
$args - > set ( 'x-dead-letter-routing-key' , 'dlx_routing_key1' ) ;
$channel - > queue_declare ( "delay_queue1" , false , true , false , false , false , $args ) ;
$channel - > queue_bind ( "delay_queue1" , "delay_exchange1" , "delay_routing_key1" ) ;
$channel - > basic_consume ( "dlx_queue1" , '' , false , false , false , false , function ( $msg ) use ( $output , $channel ) {
$msg_headers = $msg - > get ( 'application_headers' ) - > getNativeData ( ) ;
$corr_id = $msg_headers [ 'correlation_id' ] ;
if ( Cache: : get ( $corr_id ) === null ) {
$body = "该消息已消费,不再消费" ;
$output - > writeln ( date ( "h:i:s" ) . $body . PHP_EOL ) ;
$msg - > delivery_info [ 'channel' ] - > basic_ack ( $msg - > delivery_info [ 'delivery_tag' ] ) ;
return ;
}
$body = $msg - > body ;
$output - > writeln ( "生产者发送的消息:" . date ( "h:i:s" ) . " Received " . $body . PHP_EOL ) ;
$msg - > delivery_info [ 'channel' ] - > basic_ack ( $msg - > delivery_info [ 'delivery_tag' ] ) ;
Cache: : delete ( $corr_id ) ;
} ) ;
while ( count ( $channel - > callbacks ) ) {
$channel - > wait ( ) ;
}
$channel - > close ( ) ;
$connection - > close ( ) ;
}
}
2.2 消费者rpc代码
<?php
declare ( strict_types = 1 ) ;
namespace app\ command ;
use PhpAmqpLib\ Connection\ AMQPStreamConnection ;
use PhpAmqpLib\ Message\ AMQPMessage ;
use think\ console\ Command ;
use think\ console\ Input ;
use think\ console\ input\ Argument ;
use think\ console\ input\ Option ;
use think\ console\ Output ;
class RpcCommand extends Command
{
protected function configure ( )
{
$this - > setName ( 'rpc' )
- > setDescription ( 'the rpc command' ) ;
}
protected function execute1 ( Input $input , Output $output )
{
$queue = "rpc_queue" ;
$connection = new AMQPStreamConnection ( "localhost" , "5672" , "guest" , "guest" , "/" ) ;
$channel = $connection - > channel ( ) ;
$channel - > queue_declare ( $queue , false , false , true , false ) ;
$channel - > basic_qos ( null , 1 , null ) ;
$channel - > basic_consume ( $queue , '' , false , false , false , false , function ( $msg ) use ( $output ) {
$output - > writeln ( "Received:" . $msg - > body . PHP_EOL ) ;
$reply = new AMQPMessage (
"rpc server replay message" ,
array (
"correlation_id" = > $msg - > get ( 'correlation_id' )
)
) ;
$msg - > delivery_info [ 'channel' ] - > basic_publish ( $reply , '' , $msg - > get ( 'reply_to' ) ) ;
$msg - > delivery_info [ 'channel' ] - > basic_ack ( $msg - > delivery_info [ 'delivery_tag' ] ) ;
} ) ;
while ( count ( $channel - > callbacks ) ) {
$channel - > wait ( ) ;
}
$channel - > close ( ) ;
$connection - > close ( ) ;
}
protected function execute ( Input $input , Output $output )
{
$queue = "rpc_queue" ;
$connection = new AMQPStreamConnection ( "localhost" , "5672" , "guest" , "guest" , "/" ) ;
$channel = $connection - > channel ( ) ;
$channel - > queue_declare ( $queue , false , false , true , false ) ;
$channel - > basic_qos ( null , 1 , null ) ;
$channel - > basic_consume ( $queue , '' , false , false , false , false , function ( $msg ) use ( $output ) {
$output - > writeln ( " Received " . $msg - > body . PHP_EOL ) ;
$reply = new AMQPMessage (
"rpc server replay message" ,
array ( 'correlation_id' = > $msg - > get ( 'correlation_id' ) )
) ;
$msg - > delivery_info [ 'channel' ] - > basic_publish (
$reply , '' , $msg - > get ( 'reply_to' ) ) ;
$msg - > delivery_info [ 'channel' ] - > basic_ack ( $msg - > delivery_info [ 'delivery_tag' ] ) ;
} ) ;
while ( count ( $channel - > callbacks ) ) {
$channel - > wait ( ) ;
}
$channel - > close ( ) ;
$connection - > close ( ) ;
}
}
2.3 消费者消费重试
<?php
declare ( strict_types = 1 ) ;
namespace app\ command ;
use PhpAmqpLib\ Connection\ AMQPStreamConnection ;
use PhpAmqpLib\ Wire\ AMQPTable ;
use think\ console\ Command ;
use think\ console\ Input ;
use think\ console\ input\ Argument ;
use think\ console\ input\ Option ;
use think\ console\ Output ;
class RetryCommand extends Command
{
protected function configure ( )
{
$this - > setName ( 'retry' )
- > setDescription ( 'the retry command' ) ;
}
protected function execute ( Input $input , Output $output )
{
$exchange = "dlx_exchange" ;
$connection = new AMQPStreamConnection ( "localhost" , "5672" , "guest" , "guest" , "/" ) ;
$channel = $connection - > channel ( ) ;
$channel - > exchange_declare ( $exchange , 'direct' , false , false , false ) ;
$channel - > queue_declare ( "dlx_queue" , false , true , false , false ) ;
$channel - > queue_bind ( "dlx_queue" , $exchange , "dlx_routing_key" ) ;
$channel - > exchange_declare ( "delay_exchange" , "direct" , false , false , false ) ;
$channel - > basic_consume ( "dlx_queue" , '' , false , false , false , false , function ( $msg ) use ( $output , $channel ) {
$body = $msg - > body ;
$output - > writeln ( date ( "h:i:s" ) . " Received " . $body . PHP_EOL ) ;
$msg - > delivery_info [ 'channel' ] - > basic_ack ( $msg - > delivery_info [ 'delivery_tag' ] ) ;
$msg_headers = $msg - > get ( 'application_headers' ) - > getNativeData ( ) ;
if ( intval ( $msg_headers [ 'retry_nums' ] ) > 3 ) {
$body = "重试次数超过3次,则入库告警" ;
$output - > writeln ( date ( "h:i:s" ) . " Error " . $body . PHP_EOL ) ;
} else {
$headers = new AMQPTable ( [
"retry_nums" = > intval ( $msg_headers [ 'retry_nums' ] ) + 1
] ) ;
$msg - > set ( 'application_headers' , $headers ) ;
$channel - > basic_publish ( $msg , "delay_exchange" , "delay_routing_key" ) ;
}
} ) ;
while ( count ( $channel - > callbacks ) ) {
$channel - > wait ( ) ;
}
$channel - > close ( ) ;
$connection - > close ( ) ;
}
}
2.4 消费者直接交换机代码
<?php
namespace app\ command ;
use PhpAmqpLib\ Connection\ AMQPStreamConnection ;
use think\ console\ Command ;
use think\ console\ Input ;
use think\ console\ input\ Argument ;
use think\ console\ input\ Option ;
use think\ console\ Output ;
class Direct1 extends Command
{
protected function configure ( )
{
$this - > setName ( 'directRabbitMQ1' )
- > setDescription ( 'the directRabbitMQ1 command' ) ;
}
protected function execute ( Input $input , Output $output )
{
$exchange = "direct_logs" ;
$connection = new AMQPStreamConnection ( '127.0.0.1' , 5672 , 'guest' , 'guest' , '/' ) ;
$channel = $connection - > channel ( ) ;
$channel - > exchange_declare ( $exchange , 'direct' , false , false , false ) ;
list ( $queue , , ) = $channel - > queue_declare ( '' , false , false , true , false ) ;
$channel - > queue_bind ( $queue , $exchange , 'info' ) ;
$channel - > queue_bind ( $queue , $exchange , 'error' ) ;
$channel - > queue_bind ( $queue , $exchange , 'warning' ) ;
$channel - > basic_consume ( $queue , '' , false , false , false , false , function ( $msg ) use ( $output ) {
sleep ( 3 ) ;
$output - > writeln ( " Received " . $msg - > body . PHP_EOL ) ;
$msg - > delivery_info [ 'channel' ] - > basic_ack ( $msg - > delivery_info [ 'delivery_tag' ] ) ;
} ) ;
while ( count ( $channel - > callbacks ) ) {
$channel - > wait ( ) ;
}
$channel - > close ( ) ;
$connection - > close ( ) ;
}
}
2.5 基础代码
<?php
namespace app\ command ;
use PhpAmqpLib\ Connection\ AMQPStreamConnection ;
use think\ console\ Command ;
use think\ console\ Input ;
use think\ console\ Output ;
class Rabbitmq extends Command
{
public function configure ( )
{
$this - > setName ( "mq" ) - > setDescription ( "the mq command" ) ;
}
protected function execute ( Input $input , Output $output )
{
$queue = "hello_durable_true" ;
$connection = new AMQPStreamConnection ( "localhost" , "5672" , "guest" , "guest" ) ;
$channel = $connection - > channel ( ) ;
$channel - > queue_declare ( $queue , false , true , false , false ) ;
$channel - > basic_consume ( $queue , '' , false , false , false ,
false , function ( $msg ) use ( $output ) {
sleep ( 3 ) ;
$output - > writeln ( "Received" . $msg - > body . PHP_EOL ) ;
$msg - > delivery_info [ 'channel' ] - > basic_ack ( $msg - > delivery_info [ 'delivery_tag' ] ) ;
} ) ;
while ( count ( $channel - > callbacks ) ) {
$channel - > wait ( ) ;
}
$channel - > close ( ) ;
$connection - > close ( ) ;
}
}