【问题标题】:Laravel Queue via Redis: local.ERROR: read error on connection to 127.0.0.1:6379通过 Redis 的 Laravel 队列:local.ERROR:连接到 127.0.0.1:6379 时出现读取错误
【发布时间】:2020-11-27 11:38:34
【问题描述】:

我试图通过 redis 连接运行 laravel 队列,当工作人员启动几秒钟后,我收到以下错误。

队列命令:

$> php artisan queue:work --tries=1 --queue=test_queue

错误:

local.ERROR: read error on connection to 127.0.0.1:6379 {"exception":"[object] (RedisException(code: 0): read error on connection to 127.0.0.1:6379 at vendor\\laravel\\framework\\src\\Illuminate\\Redis\\Connections\\Connection.php:116)
[stacktrace]
#0 vendor\\laravel\\framework\\src\\Illuminate\\Redis\\Connections\\Connection.php(116): Redis->blPop(Array, 0)
#1 vendor\\laravel\\framework\\src\\Illuminate\\Redis\\Connections\\PhpRedisConnection.php(440): Illuminate\\Redis\\Connections\\Connection->command('blpop', Array)
#2 vendor\\laravel\\framework\\src\\Illuminate\\Redis\\Connections\\PhpRedisConnection.php(179): Illuminate\\Redis\\Connections\\PhpRedisConnection->command('blpop', Array)
#3 vendor\\laravel\\framework\\src\\Illuminate\\Queue\\RedisQueue.php(233): Illuminate\\Redis\\Connections\\PhpRedisConnection->blpop(Array, 0)
#4 vendor\\laravel\\framework\\src\\Illuminate\\Queue\\RedisQueue.php(169): Illuminate\\Queue\\RedisQueue->retrieveNextJob('queues:test_queue')
#5 vendor\\laravel\\framework\\src\\Illuminate\\Queue\\Worker.php(270): Illuminate\\Queue\\RedisQueue->pop('test_queue')
#6 vendor\\laravel\\framework\\src\\Illuminate\\Queue\\Worker.php(123): Illuminate\\Queue\\Worker->getNextJob(Object(Illuminate\\Queue\\RedisQueue), 'test_queue')
#7 vendor\\laravel\\framework\\src\\Illuminate\\Queue\\Console\\WorkCommand.php(112): Illuminate\\Queue\\Worker->daemon('redis', 'test_queue', Object(Illuminate\\Queue\\WorkerOptions))
#8 vendor\\laravel\\framework\\src\\Illuminate\\Queue\\Console\\WorkCommand.php(96): Illuminate\\Queue\\Console\\WorkCommand->runWorker('redis', 'test_queue')
#9 [internal function]: Illuminate\\Queue\\Console\\WorkCommand->handle()
#10 vendor\\laravel\\framework\\src\\Illuminate\\Container\\BoundMethod.php(32): call_user_func_array(Array, Array)
#11 vendor\\laravel\\framework\\src\\Illuminate\\Container\\Util.php(36): Illuminate\\Container\\BoundMethod::Illuminate\\Container\\{closure}()
#12 vendor\\laravel\\framework\\src\\Illuminate\\Container\\BoundMethod.php(90): Illuminate\\Container\\Util::unwrapIfClosure(Object(Closure))
#13 vendor\\laravel\\framework\\src\\Illuminate\\Container\\BoundMethod.php(34): Illuminate\\Container\\BoundMethod::callBoundMethod(Object(Illuminate\\Foundation\\Application), Array, Object(Closure))
#14 vendor\\laravel\\framework\\src\\Illuminate\\Container\\Container.php(590): Illuminate\\Container\\BoundMethod::call(Object(Illuminate\\Foundation\\Application), Array, Array, NULL)
#15 vendor\\laravel\\framework\\src\\Illuminate\\Console\\Command.php(201): Illuminate\\Container\\Container->call(Array)
#16 vendor\\symfony\\console\\Command\\Command.php(255): Illuminate\\Console\\Command->execute(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#17 vendor\\laravel\\framework\\src\\Illuminate\\Console\\Command.php(188): Symfony\\Component\\Console\\Command\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#18 vendor\\symfony\\console\\Application.php(1012): Illuminate\\Console\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#19 vendor\\symfony\\console\\Application.php(272): Symfony\\Component\\Console\\Application->doRunCommand(Object(Illuminate\\Queue\\Console\\WorkCommand), Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#20 vendor\\symfony\\console\\Application.php(148): Symfony\\Component\\Console\\Application->doRun(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#21 vendor\\laravel\\framework\\src\\Illuminate\\Console\\Application.php(93): Symfony\\Component\\Console\\Application->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#22 vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Console\\Kernel.php(131): Illuminate\\Console\\Application->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#23 artisan(37): Illuminate\\Foundation\\Console\\Kernel->handle(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#24 {main}
"}

这是队列配置:

'redis' => [
    'driver' => 'redis',
    'connection' => 'laravel_queues',
    'queue' => env('REDIS_QUEUE', 'default'),
    'retry_after' => 190, 
    'block_for' => 0,
],

这里是连接配置:

'laravel_queues' => [
    'host' => env('REDIS_HOST', 'localhost'),
    'password' => env('REDIS_PASSWORD', null),
    'port' => env('REDIS_PORT', '6379'),
    'database' => 2,
],

编辑 1

Redis 服务器已启动并运行,并且可以正常运行:


编辑 2

按照建议,我在 CLI 上运行 monitor,结果如下:

1596784000.713047 [2 127.0.0.1:62141] "EVAL" "-- Get all of the jobs with an expired \"score\"...\nlocal val = redis.call('zrangebyscore', KEYS[1], '-inf', ARGV[1])\n\n-- If we have values in the array, we will remove them from the first queue\n-- and add them onto the destination queue in chunks of 100, which moves\n-- all of the appropriate jobs onto the destination queue very safely.\nif(next(val) ~= nil) then\n    redis.call('zremrangebyrank', KEYS[1], 0, #val - 1)\n\n    for i = 1, #val, 100 do\n        redis.call('rpush', KEYS[2], unpack(val, i, math.min(i+99, #val)))\n        -- Push a notification for every job that was migrated...\n        for j = i, math.min(i+99, #val) do\n            redis.call('rpush', KEYS[3], 1)\n        end\n    end\nend\n\nreturn val" "3" "LOCALHOSTqueues:test_queue:delayed" "LOCALHOSTqueues:test_queue" "LOCALHOSTqueues:test_queue:notify" "1596784000"
1596784000.713180 [2 lua] "zrangebyscore" "LOCALHOSTqueues:test_queue:delayed" "-inf" "1596784000"
1596784000.713362 [2 127.0.0.1:62141] "EVAL" "-- Get all of the jobs with an expired \"score\"...\nlocal val = redis.call('zrangebyscore', KEYS[1], '-inf', ARGV[1])\n\n-- If we have values in the array, we will remove them from the first queue\n-- and add them onto the destination queue in chunks of 100, which moves\n-- all of the appropriate jobs onto the destination queue very safely.\nif(next(val) ~= nil) then\n    redis.call('zremrangebyrank', KEYS[1], 0, #val - 1)\n\n    for i = 1, #val, 100 do\n        redis.call('rpush', KEYS[2], unpack(val, i, math.min(i+99, #val)))\n        -- Push a notification for every job that was migrated...\n        for j = i, math.min(i+99, #val) do\n            redis.call('rpush', KEYS[3], 1)\n        end\n    end\nend\n\nreturn val" "3" "LOCALHOSTqueues:test_queue:reserved" "LOCALHOSTqueues:test_queue" "LOCALHOSTqueues:test_queue:notify" "1596784000"
1596784000.713563 [2 lua] "zrangebyscore" "LOCALHOSTqueues:test_queue:reserved" "-inf" "1596784000"
1596784000.713972 [2 127.0.0.1:62141] "EVAL" "-- Pop the first job off of the queue...\nlocal job = redis.call('lpop', KEYS[1])\nlocal reserved = false\n\nif(job ~= false) then\n    -- Increment the attempt count and place job on the reserved queue...\n    reserved = cjson.decode(job)\n    reserved['attempts'] = reserved['attempts'] + 1\n    reserved = cjson.encode(reserved)\n    redis.call('zadd', KEYS[2], ARGV[1], reserved)\n    redis.call('lpop', KEYS[3])\nend\n\nreturn {job, reserved}" "3" "LOCALHOSTqueues:test_queue" "LOCALHOSTqueues:test_queue:reserved" "LOCALHOSTqueues:test_queue:notify" "1596784190"
1596784000.714130 [2 lua] "lpop" "LOCALHOSTqueues:test_queue"
1596784000.714340 [2 127.0.0.1:62141] "BLPOP" "LOCALHOSTqueues:test_queue:notify" "0"

【问题讨论】:

  • redis服务器起来了吗?你能通过 netstat 看到,redis 已经启动并使用了端口吗? redis的超时配置是什么?有些信息会很棒..
  • 是的 Redis 服务器已启动并正在运行,请查看更新
  • 好。在您的 REDIS-CLI 中键入“MONITOR”但不带引号,因此您会看到发生在服务器端的任何操作 - 保持打开状态并重新加载连接到 redis 服务器的脚本。您可能会看到连接导致超时。
  • 完成,现在检查。
  • @RaheelHasan,你使用 docker 吗? redis 服务器是否与 php-fpm 在同一个容器中运行?如果不是,您无法使用 127.0.0.1 连接到它,您应该改用容器名称(当然,在它之前将两个容器链接到同一个网络)。请显示您的 docker-compose.yaml 和环境变量。

标签: php laravel redis queue laravel-6


【解决方案1】:

我有一个连接到 Redis docker 的 WebApp 应用程序并遇到了类似的问题。这是我学到的:

我推荐使用 docker-compose(强烈推荐)它帮助解决了我的许多问题。 redis docker 的主机名将是 redis 容器的服务名称 -- 参见下面的“#”

   version: '3.9'
     services:
       php-service:
         image: <your-php-image>

         ports:
           - "8000:8000"
         depends_on:
           - redis
         expose:
           - "8000"

      redis:  # this is going to be the hostname of redis for you php-service
        image: <your-redis-image>
        ports:
          - "6379:6379"
        sysctls:
          net.core.somaxconn: '511'

要从 PHP-WebApp docker 中引用到 redis 主机的连接,请将主机名更改为

 redis://redis:6379/0 # notice the /0 after the port - I couldn't make it work without this -- also notice that the second redis (which is the host name - the first is the protocol name) matches the name of the service in docker-compose

如果 PHP webapp 在 docker 容器外的本地计算机上运行,​​同时尝试连接到在 docker 容器内运行的 redis,请将 redis 主机名更改为

redis://localhost:6379/0 # notice the /0 is still necessary but instead of the service name inside of docker-compose being used as the host, localhost is used

祝你好运,如有任何问题,请发表评论 - 我想我可以提供帮助。

【讨论】:

    猜你喜欢
    • 2017-07-06
    • 2017-05-16
    • 2020-08-27
    • 2019-11-28
    • 1970-01-01
    • 2022-08-21
    • 2023-03-18
    • 2022-11-22
    • 2022-12-21
    相关资源
    最近更新 更多