在 Symfony 中创建缓存提供程序 class

Create a Cache Provider class in Symfony

我们的 Symfony 3.4 应用程序上有内存缓存:

cache:
    app: cache.adapter.memcached
    default_memcached_provider: "%app.memcached.dsn%"

但是,我们被要求使用多个缓存服务器,因此只传递一个 DSN 是不行的。

看这里 (https://symfony.com/blog/new-in-symfony-3-3-memcached-cache-adapter),我看到你可以用这样的代码创建它:

$client = MemcachedAdapter::createConnection(array(
    // format => memcached://[user:pass@][ip|host|socket[:port]][?weight=int]
    // 'weight' ranges from 0 to 100 and it's used to prioritize servers
    'memcached://my.server.com:11211'
    'memcached://rmf:abcdef@localhost'
    'memcached://127.0.0.1?weight=50'
    'memcached://username:the-password@/var/run/memcached.sock'
    'memcached:///var/run/memcached.sock?weight=20'
)); 

但是,这不是自动装配的。

我认为我们需要创建一个提供程序 class,或者以某种方式让它在实例化后调用 addServer($dsn)。我还在随机帖子中看到以下内容:

memcache:
    class: Memcached
    calls:
        - [ addServer, [ %app.memcached.dsn.1% ]]
        - [ addServer, [ %app.memcached.dsn.2% ]]

然而它并没有真正帮助,或者我错过了一些东西。

有人可以帮忙吗?如何创建此提供程序 class?

您可以将上面的代码片段作为服务配置复制到您的 services.yaml,大致如下所示:

# app/config/services.yaml

services:
    app.memcached_client:
        class: Memcached
        factory: 'Symfony\Component\Cache\Adapter\MemcachedAdapter::createConnection'
        arguments: [['memcached://my.server.com:11211', 'memcached://rmf:abcdef@localhost']]

    app.memcached_adapter:
        class: Symfony\Component\Cache\Adapter\MemcachedAdapter
        arguments:
            - '@app.memcached_client'

然后在您的配置中,您应该能够使用工厂创建的客户端引用适配器,例如类似于:

# app/config/config.yaml

framework:
    cache:
        app: app.memcached_adapter

您也可以覆盖默认别名 cache.adapter.memcached 而不是拥有自己的适配器。

您使用 Memcached::addServer 的方法可能也有效,但就像使用 MemcachedAdapter::createConnection 一样,这将 return 需要传递给缓存适配器的客户端。这就是为什么有第二个服务app.memcached_adapter,用于缓存配置。

请注意,我还没有对此进行测试,因此这是一个粗略的大纲,而不是一个完整的解决方案,

对于我的一个项目 运行 Symfony 3.4,配置更简单:

创建将用作客户端的服务:

app.memcached_client:
    class: Memcached
    factory: ['AppBundle\Services\Memcached', 'createConnection']
    arguments: ['memcached://%memcache_ip%:%memcache_port%']

AppBundle\Services\Memcached 可以像这样拥有我需要的所有自定义逻辑:

class Memcached
{
    public static function createConnection($dns)
    {
        $options = [
            'persistent_id' => 'some id'
        ];

        // Some more custom logic. Maybe adding some custom options
        // For example for AWS Elasticache

        if (defined('Memcached::OPT_CLIENT_MODE') && defined('Memcached::DYNAMIC_CLIENT_MODE')) {
            $options['CLIENT_MODE'] = \Memcached::DYNAMIC_CLIENT_MODE;
        }

        return \Symfony\Component\Cache\Adapter\MemcachedAdapter::createConnection($dns, $options);
    }
}

然后我在 config.yml:

中使用了该服务
framework:
    cache:
        default_memcached_provider: app.memcached_client