- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我刚刚开始使用 php-amqplib 和 RabbitMQ,并且想要一种方法来处理由于某种原因而无法处理且被拒绝的消息。我认为人们处理这个问题的一种方式是使用死信队列。我正在尝试设置它,但到目前为止还没有成功,希望有人可以提供一些建议。
我的队列启动看起来有点像:
class BaseAbstract
{
/** @var AMQPStreamConnection */
protected $connection;
/** @var AMQPChannel */
protected $channel;
/** @var array */
protected $deadLetter = [
'exchange' => 'dead_letter',
'type' => 'direct',
'queue' => 'delay_queue',
'ttl' => 10000 // in milliseconds
];
protected function initConnection(array $config)
{
try {
$this->connection = AMQPStreamConnection::create_connection($config);
$this->channel = $this->connection->channel();
// Setup dead letter exchange and queue
$this->channel->exchange_declare($this->deadLetter['exchange'], $this->deadLetter['type'], false, true, false);
$this->channel->queue_declare($this->deadLetter['queue'], false, true, false, false, false, new AMQPTable([
'x-dead-letter-exchange' => $this->deadLetter['exchange'],
'x-dead-letter-routing-key' => $this->deadLetter['queue'],
'x-message-ttl' => $this->deadLetter['ttl']
]));
$this->channel->queue_bind($this->deadLetter['queue'], $this->deadLetter['exchange']);
// Set up regular exchange and queue
$this->channel->exchange_declare($this->getExchangeName(), $this->getExchangeType(), true, true, false);
$this->channel->queue_declare($this->getQueueName(), true, true, false, false, new AMQPTable([
'x-dead-letter-exchange' => $this->deadLetter['exchange'],
'x-dead-letter-routing-key' => $this->deadLetter['queue']
]));
if (method_exists($this, 'getRouteKey')) {
$this->channel->queue_bind($this->getQueueName(), $this->getExchangeName(), $this->getRouteKey());
} else {
$this->channel->queue_bind($this->getQueueName(), $this->getExchangeName());
}
} catch (\Exception $e) {
throw new \RuntimeException('Cannot connect to the RabbitMQ service: ' . $e->getMessage());
}
return $this;
}
// ...
}
我认为应该设置我的死信交换和队列,然后还设置我的常规交换和队列(使用扩展类提供的 getRouteKey、getQueueName 和 getExchangeName/Type 方法)
当我尝试处理如下消息时:
public function process(AMQPMessage $message)
{
$msg = json_decode($message->body);
if (empty($msg->payload) || empty($msg->payload->run)) {
$message->delivery_info['channel']->basic_nack($message->delivery_info['delivery_tag'], false, true);
return;
}
// removed for post brevity, but compose $cmd variable
exec($cmd, $output, $returned);
if ($returned !== 0) {
$message->delivery_info['channel']->basic_ack($message->delivery_info['delivery_tag']);
} else {
$message->delivery_info['channel']->basic_nack($message->delivery_info['delivery_tag']);
}
}
但我返回错误 出了点问题:无法连接到 RabbitMQ 服务:PRECONDITION_FAILED - 虚拟主机“/”中队列“delay_queue”的不等价 arg“x-dead-letter-exchange”:收到“dead_letter” ' 但当前是 ''
这是我设置死字的方式吗?我在周围看到的不同例子似乎都显示出一些不同的处理方式,但似乎都不适合我。所以我显然误解了这里的一些东西,我很感激任何建议。 :)
最佳答案
设置(永久)队列和交换是您希望在部署代码时一次做的事情,而不是每次您想要使用它们时。将它们想象成您的数据库模式 - 虽然协议(protocol)提供“声明”而不是“创建”,但您通常应该编写代码,假设事物以特定方式配置。您可以将代码的第一部分构建到安装脚本中,或使用 the web- and CLI-based management plugin使用简单的 JSON 格式管理这些。
您看到的错误可能是尝试在不同时间使用不同参数声明相同队列的结果 - “声明”不会替换或重新配置现有队列,它将参数视为“前提条件” “被检查。您需要删除并重新创建队列,或通过管理 UI 对其进行管理,以更改其现有参数。
当您想动态在您的代理中创建项目时,运行时声明变得更有用。您可以给他们起您知道的唯一名称,或者传递 null
作为名称以接收随机生成的名称(人们有时指的是创建“匿名队列”,但每个RabbitMQ 中的队列有一个名称,即使您没有选择它)。
如果我没看错的话,你的“模式”看起来像这样:
# Dead Letter eXchange and Queue
Exchange: DLX
Queue: DLQ; dead letter exchange: DLX, with key "DLQ"; automatic expiry
Binding: copy messages arriving in DLX to DLQ
# Regular eXchange and Queue
Exchange: RX
Queue: RQ; dead letter exchange: DLX, with key "DLQ"
Binding: copy messages from RX to RQ, optionally filtered by routing key
当消息在 RQ 中被“nacked”时,它将被传递给 DLX,其路由 key 被覆盖为“DLQ”。然后它将被复制到 DLQ。如果它从 DLQ 中被取消,或在该队列中等待时间过长,它将被路由到自身。
我会用两种方式简化:
x-dead-letter-routing-key
选项。常规队列的配置不需要知道死信交换是否有零个、一个或多个队列附加到它,所以不应该知道另一个队列的名称。如果您希望 nacked 消息直接进入一个队列,只需将其设为“fanout exchange”(忽略路由键)或绑定(bind)键设置为 #
(这是一个匹配所有路由键的通配符)。另一种可能是将 x-dead-letter-routing-key
设置为 regular 队列的名称,即标记它来自哪个队列。但在您有一个用例之前,我会保持简单并使用其原始路由 key 留下消息。
关于php - 用 php-amqplib 和 RabbitMQ 写死字?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52948122/
我有类似下面的代码: ... id: myComponent signal updateState() property variant modelList: [] Repeater { mo
我正在处理一些我无法展示的私有(private)代码,但我已经制作了一些示例代码来描述我的问题: 主.c: #include #include #include #include typede
这个问题在这里已经有了答案: 关闭10 年前。 Possible Duplicate: what are the differences in die() and exit() in PHP? 我想
在编写 Perl 模块时,在模块内部使用 croak/die 是一个好习惯吗? 毕竟,如果调用者不使用 eval block ,模块可能会使调用它的程序崩溃。 在这些情况下,最佳做法是什么? 最佳答案
我有一些搜索线程正在存储结果。我知道当线程启动时,JVM native 代码会代理在操作系统上创建新 native 线程的请求。这需要 JVM 之外的一些内存。当线程终止并且我保留对它的引用并将其用作
我刚刚花了很多时间调试一个我追溯到 wantarray() 的问题。 .我已将其提炼为这个测试用例。 (忽略 $! 在这种情况下不会有任何有用信息的事实)。我想知道为什么wantarray在第二个示例
我看到一些代码是这样做的: if(something){ echo 'exit from program'; die; } ...more code 和其他只使用 die 的人: if
我正在尝试将此表格用于: 如果任何 $_POST 变量等于任何其他 $_POST 变量抛出错误。 如果只有几个,那不是问题,但我有大约 20 个左右所以如果我想这样做,我将不得不像这样 但这
每次我运行: hadoop dfsadmin -report 我得到以下输出: Configured Capacity: 0 (0 KB) Present Capacity: 0 (0 KB) DFS
我是一名优秀的程序员,十分优秀!