Php 如何在多个Symfony实例(共享缓存池)之间共享应用程序缓存?

Php 如何在多个Symfony实例(共享缓存池)之间共享应用程序缓存?,php,symfony,symfony4,symfony-messenger,symfony-cache,Php,Symfony,Symfony4,Symfony Messenger,Symfony Cache,我的symfony应用程序有多个实例在单独的docker容器中运行 我已将我的app.cache配置为使用redis: framework: cache: app: cache.adapter.redis 我有相同的前缀\u seed: framework: cache: prefix_seed: 'dev' 因此,我在redis中遇到了如下情况: 1605259288.470950 [0 172.18.0.28:55044] "MG

我的symfony应用程序有多个实例在单独的docker容器中运行

我已将我的
app.cache
配置为使用redis:

framework:
    cache:
        app: cache.adapter.redis

我有相同的
前缀\u seed

framework:
    cache:
        prefix_seed: 'dev'
因此,我在redis中遇到了如下情况:

1605259288.470950 [0 172.18.0.28:55044] "MGET" "HnMEIyUlZ+:workers.restart_requested_timestamp"
1605259288.471680 [0 172.18.0.28:55044] "SET" "HnMEIyUlZ+:workers.restart_requested_timestamp" "d:1605259288.471522;"
1605259314.483389 [0 172.18.0.29:42884] "MGET" "8TMgMtnOAG:workers.restart_requested_timestamp"
从上面两个不同的实例可以看出,它们正试图用同一个键
workers从redis获取值。重新启动请求的\u timestamp
,但前缀不同,即使使用相同的
前缀\u seed

在本例中,我使用的是messenger组件,我希望通过
stop workers
命令(通过共享redis)停止在任何地方运行的工作程序。但一般来说,这与缓存配置有关


如何克服这个问题,并告诉两个应用程序使用相同的池?此配置是什么?

在symfony framework捆绑包的配置定义中,您可以找到:

    private function addCacheSection(ArrayNodeDefinition $rootNode)
    {
        $rootNode
            ->children()
                ->arrayNode('cache')
                    ->info('Cache configuration')
                    ->addDefaultsIfNotSet()
                    ->fixXmlConfig('pool')
                    ->children()
                        ->scalarNode('prefix_seed')
                            ->info('Used to namespace cache keys when using several apps with the same shared backend')
                            ->example('my-application-name')
                        ->end()
                        ...
前缀_seed正是您要寻找的。
查看此处的文档:

最后,我找到了解决方案。有一个选项可以创建自己的缓存池,并将适配器映射到缓存池。这里的主要技巧是将带有
名称空间的标记传递给适配器(名称也应该是
cache.pool
):

框架:
隐藏物:
游泳池:
cache.redis_共享_池:
适配器:app.cache\u共享\u redis\u适配器
服务:
app.cache\u共享\u redis\u适配器:
父项:“cache.adapter.redis”
标签:
-{name:'cache.pool',命名空间:'shared'}
就这样!您在redis中的所有密钥都将以
shared:
作为前缀。现在,您应该将您的
@cache.redis\u shared\u池
传递给您想要的任何服务

至于messenger组件,我们应该覆盖服务(但我不确定这是最好的方式):

console.command.messenger\u停止\u工作人员:
类别:Symfony\Component\Messenger\Command\StopWorkersCommand
论据:
$restartSignalCachePool:“@cache.redis\u共享\u池”
messenger.listener.stop\u worker\u on\u restart\u signal\u listener:
类:Symfony\Component\Messenger\EventListener\StopWorkerRestartSignalListener
论据:
$cachePool:“@cache.redis\u共享\u池”

我到处都有相同的
前缀\u seed
在我的情况下,这取决于环境和构建id:
前缀\u seed:“%env(APP\u env)%\uu%env(build\u id)%“
但是如果您尝试在两个独立的容器中运行同一个symfony应用程序,您会发现前缀将不同。@yivi我发现它无法按预期工作签出。这可能对你有帮助。这能回答你的问题吗?如果使用自动连接,则可以使用
CacheInterface$cacheSharedPool
,其中变量是CamelCase中池的名称。Symfony会根据您的池名自动创建这些自动连接服务ID。但是,我不确定您是否可以使用名称中带有句点的池。