Php 如何在多个Symfony实例(共享缓存池)之间共享应用程序缓存?
我的symfony应用程序有多个实例在单独的docker容器中运行 我已将我的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
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。但是,我不确定您是否可以使用名称中带有句点的池。