文章目录
- 1.生产者代码
- 2.消费者代码
- 2.1 消费幂等性代码
- 2.2 消费者rpc代码
- 2.3 消费者消费重试
- 2.4 消费者直接交换机代码
- 2.5 基础代码
1.生产者代码
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 . "
\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 . "
\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 消费幂等性代码
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代码
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 消费者消费重试
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 消费者直接交换机代码
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 基础代码
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();
}
}