У нас есть memcache в нашем приложении 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'
));
Однако это не автоматическое подключение.
Я считаю, что нам нужно либо создать класс поставщика, либо каким-то образом заставить его выполнять вызовы addServer($dsn)
после создания экземпляра. Я также видел следующее в случайных постах:
memcache:
class: Memcached
calls:
- [ addServer, [ %app.memcached.dsn.1% ]]
- [ addServer, [ %app.memcached.dsn.2% ]]
Однако на самом деле это не помогает, или я что-то упустил.
Кто-нибудь может помочь? Как мне создать этот класс провайдера?
Вы можете скопировать приведенный выше фрагмент кода в качестве конфигурации службы в свой 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
, он вернет клиента, который необходимо передать адаптеру кеша. Поэтому есть второй сервис app.memcached_adapter
, который используется в конфигурации кеша.
Имейте в виду, что я не тестировал это, так что это скорее приблизительный набросок, чем полностью рабочее решение,
Я только что исправил опечатку в конфиге сервиса. При перечитывании это выглядело странно. См. symfony.com/doc/current/service_container/factories.html
Большое спасибо, я настрою его утром и, надеюсь, все будет готово к нашему утреннему стендапу! :-D
Это сработало, большое спасибо! Мне просто пришлось добавить дополнительные []
вокруг двух хостов, аргументы - это массив, поэтому он решил, что второй хост был вторым аргументом!
Я заговорил слишком рано! :-( Я смог очистить кеш в терминале без исключений и т. д., Но когда я загрузил сайт, я получил следующее: Argument 1 passed to Symfony\Component\Cache\Adapter\MemcachedAdapter::__construct() must be an instance of Memcached, string given
, и, посмотрев сгенерированный код, я увидел этот return $this->services['cache.app'] = new \Symfony\Component\Cache\Adapter\TraceableAdapter(new \Symfony\Component\Cache\Adapter\MemcachedAdapter('kRTmoLLARw'));
, я понятия не имею, почему вместо этого есть строка нашего клиента!
Можете ли вы открыть новый вопрос с ошибкой и конфигурацией вашего сервиса / кеша? Я не могу понять, почему это могло произойти.
конечно, я сделаю это прямо сейчас
Для одного из моих проектов с 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
Большое спасибо, я попробую !!