在 platform.sh 上使用 SncRedisBundle

Posted

技术标签:

【中文标题】在 platform.sh 上使用 SncRedisBundle【英文标题】:using SncRedisBundle on platform.sh 【发布时间】:2017-05-26 09:18:19 【问题描述】:

我正在尝试让我的应用程序由 platform.sh 托管,我的问题是我使用 SncRedisBundle,配置如下:


#config.yml

imports:
    -  resource: platformSh/parameters_platform.php  #platform.sh cloud provider configuration's

snc_redis:
    clients:
        doctrine:
            type: predis
            alias: doctrine
            dsn: "%redis_url%&database=4"
    doctrine:
        metadata_cache:
            client: doctrine
            entity_manager: default          # the name of your entity_manager connection
            document_manager: default        # the name of your document_manager connection
        result_cache:
            client: doctrine
            entity_manager: [default]  # you may specify multiple entity_managers
        query_cache:
            client: doctrine
            entity_manager: default
        second_level_cache:
            client: doctrine
            entity_manager: default

#platformSh/parameters_platform.php
$relationships = getenv("PLATFORM_RELATIONSHIPS");

var_dump('$relationships : ', $relationships, @$_ENV['PLATFORM_RELATIONSHIPS']);

if (!$relationships) 
    return;


$relationships = json_decode(base64_decode($relationships), true);

foreach ($relationships['database'] as $endpoint) 
    if (empty($endpoint['query']['is_master'])) 
        continue;
    

    $container->setParameter('database_driver', 'pdo_' . $endpoint['scheme']);
    $container->setParameter('database_host', $endpoint['host']);
    $container->setParameter('database_port', $endpoint['port']);
    $container->setParameter('database_name', $endpoint['path']);
    $container->setParameter('database_user', $endpoint['username']);
    $container->setParameter('database_password', $endpoint['password']);
    $container->setParameter('database_path', '');


if (!empty($relationships['redis'])) 
    $redisConstructedDsn = 'redis://'.$relationships['redis'][0]['host'].$relationships['redis'][0]['port'].'?password=';
    $container->setParameter('redis_url', $redisConstructedDsn);

    var_dump('$redisConstructedDsn : ', $redisConstructedDsn);
 else 
    var_dump('$relationships :', $relationships);



# Store session into /tmp.
ini_set('session.save_path', '/tmp/sessions');

当我推送到 platform.sh 时,他们的构建过程包括对 composer update 的调用,其结束如下:

生成优化的自动加载文件 > Incenteev\ParameterHandler\ScriptHandler::buildParameters > Sensio\Bundle\DistributionBundle\Composer\ScriptHandler::buildBootstrap > Sensio\Bundle\DistributionBundle\Composer\ScriptHandler::clearCache 脚本 Sensio\Bundle\DistributionBundle\Composer\ScriptHandler::clearCache 处理以异常终止的 symfony-scripts 事件

[运行时异常] 执行“'cache:clear --no-warmup'”命令时出错: 字符串(17)“$关系:” 布尔(假) 空

[Predis\Connection\ConnectionException] php_network_getaddresses:getaddrinfo 失败:名称或服务未知 [tcp://localhost&database=4:6379]

        .

我联系了他们的支持团队,他们告诉我:

嗨,

我想知道您是否想在 PLATFORM_RELATIONSHIPS 构建阶段?

这不可用,因为构建与环境无关。

如果需要连接DB/Redis/其他服务,请在 部署阶段(即部署 Hook)。


编辑:支持人员回答我说问题出在 composer.json 部分:

"scripts":  
  "symfony-scripts": [ 
    "Incenteev\\ParameterHandler\\ScriptHandler::buildParameters", 
    "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::buildBootstrap", 
    "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::clearCache", 
    "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installAssets", 
    "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installRequirementsFile", 
    "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::prepareDeploymentTarget" 
], 
"post-install-cmd": [ 
  "@symfony-scripts" 
], 
"post-update-cmd": [ 
  "@symfony-scripts" 
], 
"compile": [ 
  "app/console assetic:dump" 
] 
,

例如,"Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::clearCache" 以及 "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installAssets" 导致 Symfony 清除缓存,这太快了(在构建阶段,platform.sh 不提供链接的 redis 所需的环境和mysql 来炒锅...)


我不知道如何纠正这个问题,platform.sh 想让我修改 composer.json 文件,但我觉得这很奇怪而且很危险。你会怎么做?

【问题讨论】:

【参考方案1】:

在你的platform.app.yaml中,设置

flavor: 'none'

然后用假值创建一个parameters.dist.yml(在这个文件中添加redis_url:xxx)。这些假值将在您的 parameters_platform.php 中被覆盖

这里是我的platform.app.yaml的钩子代码:

hooks:
# Build script; can modify the filesystem, but cannot access services
build: |
    set -x -e

    # remove the development front-controller if present
    (>&2 rm web/app_dev.php || true)

    SYMFONY_ENV=prod composer install --prefer-dist --optimize-autoloader --classmap-authoritative --no-progress --no-ansi --no-interaction --no-dev
    (>&2 SYMFONY_ENV=prod app/console cache:clear --no-warmup)
    (>&2 SYMFONY_ENV=prod app/console cache:warmup)
    # Keep the cache in a persistant directory
    # If your cache can be readonly, you can skip this step
    (>&2 mkdir -p tmp/cache && mv app/cache/prod tmp/cache/ && mv app/bootstrap.php.cache tmp/bootstrap.php.cache)
    yarn
    gulp

# Deploy script, can access services, but the filesystem is read-only
deploy: |
    set -x -e

    # "install" cache
    # If your cache can be readonly, you can skip these steps
    rm -rf app/cache/prod
    (>&2 SYMFONY_ENV=prod app/console --env=prod cache:clear)
    (>&2 SYMFONY_ENV=prod app/console --env=prod doctrine:schema:update --dump-sql --force)
    cp -Rp tmp/bootstrap.php.cache app/bootstrap.php.cache
    cp -Rp tmp/cache/prod app/cache/

我们项目的platform.php:

if (empty($relationships['redis'])) 
    return;


$redis = array_shift($relationships['redis']);

$container->setParameter('redis_host', $redis['host']);
$container->setParameter('redis_port', $redis['port']);

【讨论】:

在缓存:清除和资产:安装上,调用redis服务器(由predis调用,由sncredis调用,由...调用我不知道事件监听也许),但你的方式似乎不错。我将 anwser 标记为已接受,但由于我们从 platform.sh 移至 aws,因此无法对其进行测试。

以上是关于在 platform.sh 上使用 SncRedisBundle的主要内容,如果未能解决你的问题,请参考以下文章

php Platform.sh提供的Magento 2 Env.php配置文件

apache_conf Redis on platform.sh - config.yml

json redis on platform.sh - composer.json w / scripts已删除

如何指向手动安装 Microsoft ODBC Driver 13

Facebook 登录无法在移动设备上使用(但可以在桌面设备上使用)

在 Linux 上使用此 .htaccess 获取错误 500,在 Windows 上运行良好