Symfony 4,Doctrine和AWS RDS读取副本使用情况

我将着手将RDS与主读/写和从属只读设置一起使用。

我已经阅读了有关Doctrine MasterSlaveConnection类型的信息。

但是,我创建了一些端点,希望使用只读副本(大多数GET端点),而有些端点需要写入数据(PUT,PATCH,DELETE端点)。

我也在使用API​​平台。

在Symfony 4和Doctrine 2中实现此目标的最佳方法是什么?

lzq0809 回答:Symfony 4,Doctrine和AWS RDS读取副本使用情况

我过去所做的只是使用不同的连接。

类似的东西:

doctrine:
  dbal:
    default_connection: default
    connections:
      default:
        # This is your Master
        url: '%env(DATABASE_URL)%'
        driver: 'pdo_mysql'
        server_version: '5.7'
        charset: utf8mb4
      slave:
        # This would be the slave
        url: '%env(DATABASE_SLAVE_URL)%'
        driver: 'pdo_mysql'
        server_version: '5.7'
        charset: utf8mb4

  orm:
    default_entity_manager: default
    entity_managers:
      default:
        connection: default
        mappings:
          Main:
            is_bundle: false
            type: annotation
            dir: '%kernel.project_dir%/src/Entity'
            prefix: 'App\Entity'
            alias: Main
      slave:
        connection: slave
        mappings:
          Main:
            is_bundle: false
            type: annotation
            dir: '%kernel.project_dir%/src/Entity'
            prefix: 'App\Entity'
            alias: Main

https://symfony.com/doc/current/doctrine/multiple_entity_managers.html

然后,在您的控制器或业务逻辑中,您可以选择使用默认的实体管理器:

// Controller
$this->getDoctrine()->getEntityManager();

或者您可以获取从属连接:

// Controller
$this->getDoctrine()->getEntityManager('slave');

如果您只需要处理所有请求,而不必为所有请求创建特殊操作,那么最好的选择就是装饰Collection和Item DataProviders来实现学说。

https://symfony.com/doc/current/service_container/service_decoration.html

https://github.com/api-platform/core/blob/master/src/Bridge/Doctrine/Orm/CollectionDataProvider.php

https://github.com/api-platform/core/blob/master/src/Bridge/Doctrine/Orm/ItemDataProvider.php

因此,基本上,您需要根据$opperationName更改选择的经理,例如:

if($opperationName === 'GET'){
    $manager = $this->managerRegistry->getManager('slave');
} else {
    $manager = $this->managerRegistry->getManager();
}
,

您实际上不需要设置多个实体管理器,这也不是可取的,因为处理具有多个实体管理器的一个实体很困难。

使用 Doctrine 2.2,您可以直接从配置中设置从属/副本,而无需额外的实体管理器:

在此处查看配置参考: https://www.doctrine-project.org/projects/doctrine-bundle/en/2.2/configuration.html#configuration-overview

示例:

doctrine:
    dbal:
        default_connection: default
        connections:
            default:
                dbname: '%env(DATABASE_DBNAME)%'
                user: '%env(DATABASE_USER)%'
                password: '%env(DATABASE_PASSWORD)%'
                host: '%env(DATABASE_HOST)%'
                driver: 'pdo_mysql'
                server_version: '5.7'
                charset: utf8mb4
                default_table_options:
                    charset: utf8mb4
                    collate: utf8mb4_unicode_ci
                slaves:
                    ro_replica:
                        dbname: '%env(REPLICA_DBNAME)%'
                        user: '%env(REPLICA_USER)%'
                        password: '%env(REPLICA_PASSWORD)%'
                        host: '%env(REPLICA_HOST)%'
                        charset: utf8mb4
,

感谢@Chase提供解决方案。你让我开心。尽管它在“开发”环境中对我有效,但切换到“生产”时还是有问题。我收到一个找不到实体的错误。解决方案来自this帖子-感谢@xabbuh。基本上,我必须在doctrine.yml中添加default_entity_manager: name_of_default_em。这是代码的副本:

# config/packages/prod/doctrine.yaml
doctrine:
    orm:
        default_entity_manager: BOE <- add this line to let know prod about default em
        auto_generate_proxy_classes: false
        metadata_cache_driver:
            type: service
            id: doctrine.system_cache_provider
        query_cache_driver:
            type: service
            id: doctrine.system_cache_provider
        result_cache_driver:
            type: service
            id: doctrine.result_cache_provider

# ...
本文链接:https://www.f2er.com/3108948.html

大家都在问