简体   繁体   English

Laravel + Redis 通过 SSL 缓存?

[英]Laravel + Redis Cache via SSL?

I am trying to connect to Redis with predis 1.1 and SSL, using information https://github.com/nrk/predis , where in the example the following configuration is used:我正在尝试使用 predis 1.1 和 SSL 连接到 Redis,使用信息https://github.com/nrk/predis ,在示例中使用以下配置:

// Named array of connection parameters:
$client = new Predis\Client([
  'scheme' => 'tls',
  'ssl'    => ['cafile' => 'private.pem', 'verify_peer' => true],
]);

My Laravel configuration looks like below:我的 Laravel 配置如下所示:

'redis' => [
        'client' => 'predis',
        'cluster' => env('REDIS_CLUSTER', false),

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

        'options' => [
            'cluster' => 'redis',
            'parameters' => ['password' => env('REDIS_PASSWORD', null)],
            'scheme' => 'tls',
        ],
    ],

Unfortunately I am getting the following error:不幸的是我收到以下错误:

ConnectionException in AbstractConnection.php line 155:
Error while reading line from the server. [tcp://MY_REDIS_SERVER_URL:6380]

Suggestions are appreciated:)建议表示赞赏:)

I was able to get it to work!我能够让它工作!

You need to move 'scheme' from 'options' to 'default' :您需要将 'scheme' 从'options'移动到'default'

My working config:我的工作配置:

'redis' => [
    'client' => 'predis',
    'cluster' => env('REDIS_CLUSTER', false),

    'default' => [
        'scheme' => 'tls',
        'host' => env('REDIS_HOST', 'localhost'),
        'password' => env('REDIS_PASSWORD', null),
        'port' => env('REDIS_PORT', 6379),
        'database' => 0,
    ],

    'options' => [
        'parameters' => ['password' => env('REDIS_PASSWORD', null)],
    ],
],

Note: I had also removed the 'cluster' option from 'options' , but I don't suspect this to be the make-or-break with this problem.注意:我还从'options'中删除了'cluster'选项,但我不怀疑这是这个问题的成败。

In my final-final config, I changed it to: 'scheme' => env('REDIS_SCHEME', 'tcp'), and then defined REDIS_SCHEME=tls in my env file instead.在我的最终配置中,我将其更改为: 'scheme' => env('REDIS_SCHEME', 'tcp'),然后在我的 env 文件中定义REDIS_SCHEME=tls

Tested with AWS ElastiCache with TLS enabled.使用启用了 TLS 的 AWS ElastiCache 进行测试。

Edit: The above config only works with single-node redis.编辑:上述配置仅适用于单节点 redis。 If you happen to enable clustering and TLS then you'll need a different config entirely.如果您碰巧启用了集群TLS,那么您将需要完全不同的配置。

'redis' => [
        'client' => 'predis',
        'cluster' => env('REDIS_CLUSTER', false),

        // Note! for single redis nodes, the default is defined here.
        // keeping it here for clusters will actually prevent the cluster config
        // from being used, it'll assume single node only.
        //'default' => [
        //    ...
        //],

        // #pro-tip, you can use the Cluster config even for single instances!
        'clusters' => [
            'default' => [
                [
                    'scheme'   => env('REDIS_SCHEME', 'tcp'),
                    'host'     => env('REDIS_HOST', 'localhost'),
                    'password' => env('REDIS_PASSWORD', null),
                    'port'     => env('REDIS_PORT', 6379),
                    'database' => env('REDIS_DATABASE', 0),
                ],
            ],
            'options' => [ // Clustering specific options
                'cluster' => 'redis', // This tells Redis Client lib to follow redirects (from cluster)
            ]
        ],
        'options' => [
            'parameters' => [ // Parameters provide defaults for the Connection Factory
                'password' => env('REDIS_PASSWORD', null), // Redirects need PW for the other nodes
                'scheme'   => env('REDIS_SCHEME', 'tcp'),  // Redirects also must match scheme
            ],
        ]
    ]

Explaining the above:解释以上内容:

  • 'client' => 'predis' : This specifies the PHP Library Redis driver to use (predis). 'client' => 'predis' :指定要使用的 PHP 库 Redis 驱动程序 (predis)。
  • 'cluster' => 'redis' : This tells Predis to assume server-side clustering. 'cluster' => 'redis' :这告诉 Predis 假设服务器端集群。 Which just means "follow redirects" (eg -MOVED responses).这只是意味着“跟随重定向”(例如-MOVED响应)。 When running with a cluster, a node will respond with a -MOVED to the node that you must ask for a specific key.当与集群一起运行时,节点将以-MOVED响应您必须请求特定密钥的节点。
  • If you don't have this enabled with Redis Clusters, Laravel will throw a -MOVED exception 1/ n times, n being the number of nodes in Redis cluster (it'll get lucky and ask the right node every once in awhile)如果您没有在 Redis 集群中启用此功能,Laravel 将抛出一个-MOVED异常 1/ n次, n是 Redis 集群中的节点数(它会很幸运并每隔一段时间询问正确的节点)
  • 'clusters' => [...] : Specifies a list of nodes, but setting just a 'default' and pointing it to the AWS 'Configuration endpoint' will let it find any/all other nodes dynamically (recommended for Elasticache, because you don't know when nodes are comin' or goin'). 'clusters' => [...] :指定节点列表,但仅设置“默认”并将其指向AWS“配置端点”将使其动态查找任何/所有其他节点(推荐用于 Elasticache,因为你不知道节点什么时候来或去)。
  • 'options' : For Laravel, can be specified at the top-level, cluster-level, and node option. 'options' :对于 Laravel,可以在顶级、集群级和节点选项中指定。 (they get combined in Illuminate before being passed off to Predis) (它们在被传递给 Predis 之前在 Illuminate 中组合)
  • 'parameters' : These 'override' the default connection settings/assumptions that Predis uses for new connections. 'parameters' :这些“覆盖” Predis 用于新连接的默认连接设置/假设。 Since we set them explicitly for the 'default' connection, these aren't used.由于我们为“默认”连接明确设置了它们,因此不使用它们。 But for a cluster setup, they are critical.但对于集群设置,它们至关重要。 A 'master' node may send back a redirect ( -MOVED ) and unless the parameters are set for password and scheme it'll assume defaults, and that new connection to the new node will fail. “主”节点可能会发回重定向( -MOVED ),除非为passwordscheme设置了参数,否则它将假定为默认值,并且与新节点的新连接将失败。

Thank you CenterOrbit !!谢谢中心轨道!!

I can confirm the first solution does allow Laravel to connect to a Redis server over TLS.我可以确认第一个解决方案确实允许 Laravel 通过 TLS 连接到 Redis服务器 Tested with Redis 3.2.6 on AWS ElastiCache with TLS, configured as single node and single shard.在具有 TLS 的 AWS ElastiCache 上使用 Redis 3.2.6 进行测试,配置为单节点和单分片。

I can also confirm the second solution does allow Laravel to connect to a Redis Cluster over TLS.我还可以确认第二个解决方案确实允许 Laravel 通过 TLS 连接到 Redis集群 Tested with Redis 3.2.6 on AWS ElastiCache with TLS, configured with "Cluster Mode Enabled", 1 shard, 1 replica per shard.在具有 TLS 的 AWS ElastiCache 上使用 Redis 3.2.6 进行测试,配置为“启用集群模式”,1 个分片,每个分片 1 个副本。

I was receiving the following error when I first tried to implement the cluster solution:当我第一次尝试实施集群解决方案时收到以下错误:

Error: Unsupported operand types

I missed the additional set of array brackets when I moved the "default" settings into the "clusters" array.当我将“默认”设置移动到“集群”数组中时,我错过了额外的一组数组括号。

INCORRECT不正确

'clusters' => [
  'default' => [
    'scheme' ...
  ]
]

CORRECT正确的

'clusters' => [
  'default' => [
    [
      'scheme' ...
    ]
  ]
]

I hope this saves someone else a bit of troubleshooting time.我希望这可以为其他人节省一些故障排除时间。

CenterOrbit 接受的解决方案对我有用,因为我使用的是 AWS,所以我必须在我的 .env Laravel 中添加 tls://

tls://username:password@URL:PORT?database=0 Try it. tls://username:password@URL:PORT?database=0 试试吧。 It will work它会起作用

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM