尝试 pushRaw 时出现 AMQP 错误:未定义的索引:名称
AMQP error while attempting pushRaw: Undefined index: name
我正在将 Laravel 从 5.4.*
升级到 5.5.0
。 RabbitMQ 在 5.4
中工作得非常好,但现在当我尝试 运行 使用队列的功能时,它在日志中显示以下错误:
AMQP error while attempting pushRaw: Undefined index: name
日志中没有其他信息。这是我的 .env
:
RABBITMQ_HOST=localhost
RABBITMQ_PORT=5672
RABBITMQ_VHOST=/
RABBITMQ_LOGIN=test
RABBITMQ_PASSWORD=test
RABBITMQ_QUEUE=reporting
RABBITMQ_JOB_QUEUE=dev
这是我的配置 queue.php
:
'worker' => [
'driver' => 'rabbitmq',
'factory_class' => Enqueue\AmqpLib\AmqpConnectionFactory::class,
'host' => env('RABBITMQ_HOST'),
'port' => env('RABBITMQ_PORT'),
'vhost' => env('RABBITMQ_VHOST'),
'login' => env('RABBITMQ_LOGIN'),
'password' => env('RABBITMQ_PASSWORD'),
'queue' => env('RABBITMQ_JOB_QUEUE'),
'options' => [
'exchange' => [
'name' => env('RABBITMQ_EXCHANGE_NAME', null),
/*
* Determine if exchange should be created if it does not exist.
*/
'declare' => env('RABBITMQ_EXCHANGE_DECLARE', true),
/*
* Read more about possible values at https://www.rabbitmq.com/tutorials/amqp-concepts.html
*/
'type' => env('RABBITMQ_EXCHANGE_TYPE', \Interop\Amqp\AmqpTopic::TYPE_DIRECT),
'passive' => env('RABBITMQ_EXCHANGE_PASSIVE', false),
'durable' => env('RABBITMQ_EXCHANGE_DURABLE', true),
'auto_delete' => env('RABBITMQ_EXCHANGE_AUTODELETE', false),
'arguments' => env('RABBITMQ_EXCHANGE_ARGUMENTS'),
],
'queue' => [
/*
* Determine if queue should be created if it does not exist.
*/
'declare' => env('RABBITMQ_QUEUE_DECLARE', true),
/*
* Determine if queue should be binded to the exchange created.
*/
'bind' => env('RABBITMQ_QUEUE_DECLARE_BIND', true),
/*
* Read more about possible values at https://www.rabbitmq.com/tutorials/amqp-concepts.html
*/
'passive' => env('RABBITMQ_QUEUE_PASSIVE', false),
'durable' => env('RABBITMQ_QUEUE_DURABLE', true),
'exclusive' => env('RABBITMQ_QUEUE_EXCLUSIVE', false),
'auto_delete' => env('RABBITMQ_QUEUE_AUTODELETE', false),
'arguments' => env('RABBITMQ_QUEUE_ARGUMENTS'),
],
],
],
这是 composer.json
中 RabbitMQ
的版本:
"vladimir-yuldashev/laravel-queue-rabbitmq": "6.0.0",
我的 Laravel 版本是 5.5.0
。我试图推入队列的任务是:
\Mail::to($user->email)->queue(new MailPriceRequest($priceRequests));
这里出了什么问题?有帮助吗?
编辑:
这里是 MailPriceRequest
class:
class MailPriceRequest extends Mailable implements ShouldQueue
{
use Queueable, SerializesModels;
/**
* @var
*/
public $title;
/**
* @var
*/
public $items;
/**
* @var array
*/
public $groupedPriceRequests = [];
/**
* @var
*/
public $grouped;
/**
* @var string
*/
public $groupName = '';
/**
* @var
*/
public $emailSubject;
/**
* MailPriceRequest constructor.
* @param $transportOrders
*/
public function __construct($priceRequests)
{
$this->items = $priceRequests;
}
/**
* Build the message.
*
* @return $this
*/
public function build()
{
$this->setPriceRequests();
$this->setTitle();
$this->setGrouped();
$this->setSubject();
return $this->subject($this->emailSubject)->view('emails.price-requests.overview');
}
/**
* @return $this
*/
public function setSubject()
{
$this->emailSubject = $this->getOrderNumber();
return $this;
}
/**
* @return $this
*/
public function setGrouped()
{
$this->grouped = $this->groupedPriceRequests;
return $this;
}
/**
* @return $this
*/
public function setTitle()
{
$this->title = 'title';
return $this;
}
/**
* @return $this
*/
public function setPriceRequests()
{
$this->groupByCarrier();
return $this;
}
/**
* @return $this
*/
public function groupByCarrier()
{
$transformer = \App::make(PriceRequestMailTransformer::class);
foreach ($this->items as $priceRequest) {
if (!array_key_exists($priceRequest->carrier_name, $this->groupedPriceRequests)) {
$this->groupedPriceRequests[$priceRequest->carrier_name] = [
'price_requests' => []
];
}
$transformed = $transformer->transform($priceRequest);
$this->groupedPriceRequests[$priceRequest->carrier_name]['price_requests'][] = $transformed;
}
return $this;
}
/**
* @return string|null
*/
private function getOrderNumber()
{
if (count($this->items) > 1) {
return ' - ' . $this->items->first()->order_number . ' - and more references';
}
if (count($this->items) == 1) {
return ' - ' . $this->items->first()->order_number;
}
return null;
}
}
我找到了解决方案。
在 [options][queue]
数组中添加了这一行:
'name' => env('RABBITMQ_EXCHANGE_NAME', env('RABBITMQ_QUEUE'))
关于 rabbitmq 配置的文档,在 Laravel .env 中设置如下;
RABBITMQ_HOST=localhost
RABBITMQ_PORT=5672
RABBITMQ_VHOST=/
RABBITMQ_LOGIN=test
RABBITMQ_PASSWORD=test
RABBITMQ_QUEUE=reporting
RABBITMQ_JOB_QUEUE=dev
# Exchange name is a required field.
RABBITMQ_EXCHANGE_NAME=yourexchangename
在您的 queue.php 文件中设置交换名称环境变量。
'worker' => [
'driver' => 'rabbitmq',
'factory_class' => Enqueue\AmqpLib\AmqpConnectionFactory::class,
'host' => env('RABBITMQ_HOST'),
'port' => env('RABBITMQ_PORT'),
'vhost' => env('RABBITMQ_VHOST'),
'login' => env('RABBITMQ_LOGIN'),
'password' => env('RABBITMQ_PASSWORD'),
'queue' => env('RABBITMQ_JOB_QUEUE'),
'options' => [
'exchange' => [
// Exchange name is a required field.
'name' => env('RABBITMQ_EXCHANGE_NAME', null),
/*
* Determine if exchange should be created if it does not exist.
*/
'declare' => env('RABBITMQ_EXCHANGE_DECLARE', true),
/*
* Read more about possible values at https://www.rabbitmq.com/tutorials/amqp-concepts.html
*/
'type' => env('RABBITMQ_EXCHANGE_TYPE', \Interop\Amqp\AmqpTopic::TYPE_DIRECT),
'passive' => env('RABBITMQ_EXCHANGE_PASSIVE', false),
'durable' => env('RABBITMQ_EXCHANGE_DURABLE', true),
'auto_delete' => env('RABBITMQ_EXCHANGE_AUTODELETE', false),
'arguments' => env('RABBITMQ_EXCHANGE_ARGUMENTS'),
],
'queue' => [
'name' => env('RABBITMQ_EXCHANGE_NAME', env('RABBITMQ_QUEUE')),
/*
* Determine if queue should be created if it does not exist.
*/
'declare' => env('RABBITMQ_QUEUE_DECLARE', true),
/*
* Determine if queue should be binded to the exchange created.
*/
'bind' => env('RABBITMQ_QUEUE_DECLARE_BIND', true),
/*
* Read more about possible values at https://www.rabbitmq.com/tutorials/amqp-concepts.html
*/
'passive' => env('RABBITMQ_QUEUE_PASSIVE', false),
'durable' => env('RABBITMQ_QUEUE_DURABLE', true),
'exclusive' => env('RABBITMQ_QUEUE_EXCLUSIVE', false),
'auto_delete' => env('RABBITMQ_QUEUE_AUTODELETE', false),
'arguments' => env('RABBITMQ_QUEUE_ARGUMENTS'),
],
],
],
为Laravel
定义rabbitmq驱动的另一个例子
'connections' => [
// ...
'rabbitmq' => [
'driver' => 'rabbitmq',
/*
* Set to "horizon" if you wish to use Laravel Horizon.
*/
'worker' => env('RABBITMQ_WORKER', 'default'),
'dsn' => env('RABBITMQ_DSN', null),
/*
* Could be one a class that implements \Interop\Amqp\AmqpConnectionFactory for example:
* - \EnqueueAmqpExt\AmqpConnectionFactory if you install enqueue/amqp-ext
* - \EnqueueAmqpLib\AmqpConnectionFactory if you install enqueue/amqp-lib
* - \EnqueueAmqpBunny\AmqpConnectionFactory if you install enqueue/amqp-bunny
*/
'factory_class' => Enqueue\AmqpLib\AmqpConnectionFactory::class,
'host' => env('RABBITMQ_HOST', '127.0.0.1'),
'port' => env('RABBITMQ_PORT', 5672),
'vhost' => env('RABBITMQ_VHOST', '/'),
'login' => env('RABBITMQ_LOGIN', 'guest'),
'password' => env('RABBITMQ_PASSWORD', 'guest'),
'queue' => env('RABBITMQ_QUEUE', 'default'),
'options' => [
'exchange' => [
'name' => env('RABBITMQ_EXCHANGE_NAME'),
/*
* Determine if exchange should be created if it does not exist.
*/
'declare' => env('RABBITMQ_EXCHANGE_DECLARE', true),
/*
* Read more about possible values at https://www.rabbitmq.com/tutorials/amqp-concepts.html
*/
'type' => env('RABBITMQ_EXCHANGE_TYPE', \Interop\Amqp\AmqpTopic::TYPE_DIRECT),
'passive' => env('RABBITMQ_EXCHANGE_PASSIVE', false),
'durable' => env('RABBITMQ_EXCHANGE_DURABLE', true),
'auto_delete' => env('RABBITMQ_EXCHANGE_AUTODELETE', false),
'arguments' => env('RABBITMQ_EXCHANGE_ARGUMENTS'),
],
'queue' => [
/*
* Determine if queue should be created if it does not exist.
*/
'declare' => env('RABBITMQ_QUEUE_DECLARE', true),
/*
* Determine if queue should be binded to the exchange created.
*/
'bind' => env('RABBITMQ_QUEUE_DECLARE_BIND', true),
/*
* Read more about possible values at https://www.rabbitmq.com/tutorials/amqp-concepts.html
*/
'passive' => env('RABBITMQ_QUEUE_PASSIVE', false),
'durable' => env('RABBITMQ_QUEUE_DURABLE', true),
'exclusive' => env('RABBITMQ_QUEUE_EXCLUSIVE', false),
'auto_delete' => env('RABBITMQ_QUEUE_AUTODELETE', false),
'arguments' => env('RABBITMQ_QUEUE_ARGUMENTS'),
],
],
/*
* Determine the number of seconds to sleep if there's an error communicating with rabbitmq
* If set to false, it'll throw an exception rather than doing the sleep for X seconds.
*/
'sleep_on_error' => env('RABBITMQ_ERROR_SLEEP', 5),
/*
* Optional SSL params if an SSL connection is used
* Using an SSL connection will also require to configure your RabbitMQ to enable SSL. More details can be founds here: https://www.rabbitmq.com/ssl.html
*/
'ssl_params' => [
'ssl_on' => env('RABBITMQ_SSL', false),
'cafile' => env('RABBITMQ_SSL_CAFILE', null),
'local_cert' => env('RABBITMQ_SSL_LOCALCERT', null),
'local_key' => env('RABBITMQ_SSL_LOCALKEY', null),
'verify_peer' => env('RABBITMQ_SSL_VERIFY_PEER', true),
'passphrase' => env('RABBITMQ_SSL_PASSPHRASE', null),
],
],
// ...
],
我正在将 Laravel 从 5.4.*
升级到 5.5.0
。 RabbitMQ 在 5.4
中工作得非常好,但现在当我尝试 运行 使用队列的功能时,它在日志中显示以下错误:
AMQP error while attempting pushRaw: Undefined index: name
日志中没有其他信息。这是我的 .env
:
RABBITMQ_HOST=localhost
RABBITMQ_PORT=5672
RABBITMQ_VHOST=/
RABBITMQ_LOGIN=test
RABBITMQ_PASSWORD=test
RABBITMQ_QUEUE=reporting
RABBITMQ_JOB_QUEUE=dev
这是我的配置 queue.php
:
'worker' => [
'driver' => 'rabbitmq',
'factory_class' => Enqueue\AmqpLib\AmqpConnectionFactory::class,
'host' => env('RABBITMQ_HOST'),
'port' => env('RABBITMQ_PORT'),
'vhost' => env('RABBITMQ_VHOST'),
'login' => env('RABBITMQ_LOGIN'),
'password' => env('RABBITMQ_PASSWORD'),
'queue' => env('RABBITMQ_JOB_QUEUE'),
'options' => [
'exchange' => [
'name' => env('RABBITMQ_EXCHANGE_NAME', null),
/*
* Determine if exchange should be created if it does not exist.
*/
'declare' => env('RABBITMQ_EXCHANGE_DECLARE', true),
/*
* Read more about possible values at https://www.rabbitmq.com/tutorials/amqp-concepts.html
*/
'type' => env('RABBITMQ_EXCHANGE_TYPE', \Interop\Amqp\AmqpTopic::TYPE_DIRECT),
'passive' => env('RABBITMQ_EXCHANGE_PASSIVE', false),
'durable' => env('RABBITMQ_EXCHANGE_DURABLE', true),
'auto_delete' => env('RABBITMQ_EXCHANGE_AUTODELETE', false),
'arguments' => env('RABBITMQ_EXCHANGE_ARGUMENTS'),
],
'queue' => [
/*
* Determine if queue should be created if it does not exist.
*/
'declare' => env('RABBITMQ_QUEUE_DECLARE', true),
/*
* Determine if queue should be binded to the exchange created.
*/
'bind' => env('RABBITMQ_QUEUE_DECLARE_BIND', true),
/*
* Read more about possible values at https://www.rabbitmq.com/tutorials/amqp-concepts.html
*/
'passive' => env('RABBITMQ_QUEUE_PASSIVE', false),
'durable' => env('RABBITMQ_QUEUE_DURABLE', true),
'exclusive' => env('RABBITMQ_QUEUE_EXCLUSIVE', false),
'auto_delete' => env('RABBITMQ_QUEUE_AUTODELETE', false),
'arguments' => env('RABBITMQ_QUEUE_ARGUMENTS'),
],
],
],
这是 composer.json
中 RabbitMQ
的版本:
"vladimir-yuldashev/laravel-queue-rabbitmq": "6.0.0",
我的 Laravel 版本是 5.5.0
。我试图推入队列的任务是:
\Mail::to($user->email)->queue(new MailPriceRequest($priceRequests));
这里出了什么问题?有帮助吗?
编辑:
这里是 MailPriceRequest
class:
class MailPriceRequest extends Mailable implements ShouldQueue
{
use Queueable, SerializesModels;
/**
* @var
*/
public $title;
/**
* @var
*/
public $items;
/**
* @var array
*/
public $groupedPriceRequests = [];
/**
* @var
*/
public $grouped;
/**
* @var string
*/
public $groupName = '';
/**
* @var
*/
public $emailSubject;
/**
* MailPriceRequest constructor.
* @param $transportOrders
*/
public function __construct($priceRequests)
{
$this->items = $priceRequests;
}
/**
* Build the message.
*
* @return $this
*/
public function build()
{
$this->setPriceRequests();
$this->setTitle();
$this->setGrouped();
$this->setSubject();
return $this->subject($this->emailSubject)->view('emails.price-requests.overview');
}
/**
* @return $this
*/
public function setSubject()
{
$this->emailSubject = $this->getOrderNumber();
return $this;
}
/**
* @return $this
*/
public function setGrouped()
{
$this->grouped = $this->groupedPriceRequests;
return $this;
}
/**
* @return $this
*/
public function setTitle()
{
$this->title = 'title';
return $this;
}
/**
* @return $this
*/
public function setPriceRequests()
{
$this->groupByCarrier();
return $this;
}
/**
* @return $this
*/
public function groupByCarrier()
{
$transformer = \App::make(PriceRequestMailTransformer::class);
foreach ($this->items as $priceRequest) {
if (!array_key_exists($priceRequest->carrier_name, $this->groupedPriceRequests)) {
$this->groupedPriceRequests[$priceRequest->carrier_name] = [
'price_requests' => []
];
}
$transformed = $transformer->transform($priceRequest);
$this->groupedPriceRequests[$priceRequest->carrier_name]['price_requests'][] = $transformed;
}
return $this;
}
/**
* @return string|null
*/
private function getOrderNumber()
{
if (count($this->items) > 1) {
return ' - ' . $this->items->first()->order_number . ' - and more references';
}
if (count($this->items) == 1) {
return ' - ' . $this->items->first()->order_number;
}
return null;
}
}
我找到了解决方案。
在 [options][queue]
数组中添加了这一行:
'name' => env('RABBITMQ_EXCHANGE_NAME', env('RABBITMQ_QUEUE'))
关于 rabbitmq 配置的文档,在 Laravel .env 中设置如下;
RABBITMQ_HOST=localhost
RABBITMQ_PORT=5672
RABBITMQ_VHOST=/
RABBITMQ_LOGIN=test
RABBITMQ_PASSWORD=test
RABBITMQ_QUEUE=reporting
RABBITMQ_JOB_QUEUE=dev
# Exchange name is a required field.
RABBITMQ_EXCHANGE_NAME=yourexchangename
在您的 queue.php 文件中设置交换名称环境变量。
'worker' => [
'driver' => 'rabbitmq',
'factory_class' => Enqueue\AmqpLib\AmqpConnectionFactory::class,
'host' => env('RABBITMQ_HOST'),
'port' => env('RABBITMQ_PORT'),
'vhost' => env('RABBITMQ_VHOST'),
'login' => env('RABBITMQ_LOGIN'),
'password' => env('RABBITMQ_PASSWORD'),
'queue' => env('RABBITMQ_JOB_QUEUE'),
'options' => [
'exchange' => [
// Exchange name is a required field.
'name' => env('RABBITMQ_EXCHANGE_NAME', null),
/*
* Determine if exchange should be created if it does not exist.
*/
'declare' => env('RABBITMQ_EXCHANGE_DECLARE', true),
/*
* Read more about possible values at https://www.rabbitmq.com/tutorials/amqp-concepts.html
*/
'type' => env('RABBITMQ_EXCHANGE_TYPE', \Interop\Amqp\AmqpTopic::TYPE_DIRECT),
'passive' => env('RABBITMQ_EXCHANGE_PASSIVE', false),
'durable' => env('RABBITMQ_EXCHANGE_DURABLE', true),
'auto_delete' => env('RABBITMQ_EXCHANGE_AUTODELETE', false),
'arguments' => env('RABBITMQ_EXCHANGE_ARGUMENTS'),
],
'queue' => [
'name' => env('RABBITMQ_EXCHANGE_NAME', env('RABBITMQ_QUEUE')),
/*
* Determine if queue should be created if it does not exist.
*/
'declare' => env('RABBITMQ_QUEUE_DECLARE', true),
/*
* Determine if queue should be binded to the exchange created.
*/
'bind' => env('RABBITMQ_QUEUE_DECLARE_BIND', true),
/*
* Read more about possible values at https://www.rabbitmq.com/tutorials/amqp-concepts.html
*/
'passive' => env('RABBITMQ_QUEUE_PASSIVE', false),
'durable' => env('RABBITMQ_QUEUE_DURABLE', true),
'exclusive' => env('RABBITMQ_QUEUE_EXCLUSIVE', false),
'auto_delete' => env('RABBITMQ_QUEUE_AUTODELETE', false),
'arguments' => env('RABBITMQ_QUEUE_ARGUMENTS'),
],
],
],
为Laravel
定义rabbitmq驱动的另一个例子'connections' => [
// ...
'rabbitmq' => [
'driver' => 'rabbitmq',
/*
* Set to "horizon" if you wish to use Laravel Horizon.
*/
'worker' => env('RABBITMQ_WORKER', 'default'),
'dsn' => env('RABBITMQ_DSN', null),
/*
* Could be one a class that implements \Interop\Amqp\AmqpConnectionFactory for example:
* - \EnqueueAmqpExt\AmqpConnectionFactory if you install enqueue/amqp-ext
* - \EnqueueAmqpLib\AmqpConnectionFactory if you install enqueue/amqp-lib
* - \EnqueueAmqpBunny\AmqpConnectionFactory if you install enqueue/amqp-bunny
*/
'factory_class' => Enqueue\AmqpLib\AmqpConnectionFactory::class,
'host' => env('RABBITMQ_HOST', '127.0.0.1'),
'port' => env('RABBITMQ_PORT', 5672),
'vhost' => env('RABBITMQ_VHOST', '/'),
'login' => env('RABBITMQ_LOGIN', 'guest'),
'password' => env('RABBITMQ_PASSWORD', 'guest'),
'queue' => env('RABBITMQ_QUEUE', 'default'),
'options' => [
'exchange' => [
'name' => env('RABBITMQ_EXCHANGE_NAME'),
/*
* Determine if exchange should be created if it does not exist.
*/
'declare' => env('RABBITMQ_EXCHANGE_DECLARE', true),
/*
* Read more about possible values at https://www.rabbitmq.com/tutorials/amqp-concepts.html
*/
'type' => env('RABBITMQ_EXCHANGE_TYPE', \Interop\Amqp\AmqpTopic::TYPE_DIRECT),
'passive' => env('RABBITMQ_EXCHANGE_PASSIVE', false),
'durable' => env('RABBITMQ_EXCHANGE_DURABLE', true),
'auto_delete' => env('RABBITMQ_EXCHANGE_AUTODELETE', false),
'arguments' => env('RABBITMQ_EXCHANGE_ARGUMENTS'),
],
'queue' => [
/*
* Determine if queue should be created if it does not exist.
*/
'declare' => env('RABBITMQ_QUEUE_DECLARE', true),
/*
* Determine if queue should be binded to the exchange created.
*/
'bind' => env('RABBITMQ_QUEUE_DECLARE_BIND', true),
/*
* Read more about possible values at https://www.rabbitmq.com/tutorials/amqp-concepts.html
*/
'passive' => env('RABBITMQ_QUEUE_PASSIVE', false),
'durable' => env('RABBITMQ_QUEUE_DURABLE', true),
'exclusive' => env('RABBITMQ_QUEUE_EXCLUSIVE', false),
'auto_delete' => env('RABBITMQ_QUEUE_AUTODELETE', false),
'arguments' => env('RABBITMQ_QUEUE_ARGUMENTS'),
],
],
/*
* Determine the number of seconds to sleep if there's an error communicating with rabbitmq
* If set to false, it'll throw an exception rather than doing the sleep for X seconds.
*/
'sleep_on_error' => env('RABBITMQ_ERROR_SLEEP', 5),
/*
* Optional SSL params if an SSL connection is used
* Using an SSL connection will also require to configure your RabbitMQ to enable SSL. More details can be founds here: https://www.rabbitmq.com/ssl.html
*/
'ssl_params' => [
'ssl_on' => env('RABBITMQ_SSL', false),
'cafile' => env('RABBITMQ_SSL_CAFILE', null),
'local_cert' => env('RABBITMQ_SSL_LOCALCERT', null),
'local_key' => env('RABBITMQ_SSL_LOCALKEY', null),
'verify_peer' => env('RABBITMQ_SSL_VERIFY_PEER', true),
'passphrase' => env('RABBITMQ_SSL_PASSPHRASE', null),
],
],
// ...
],