【问题标题】:Configuring a cache server on a Laravel application hosted on the cloud在云上托管的 Laravel 应用程序上配置缓存服务器
【发布时间】:2015-01-05 18:06:21
【问题描述】:

我正在使用 Laravel 框架,并在 Heroku 上托管我的暂存和生产环境。

我想使用缓存,例如 Memcached。在我的本地机器上,一切运行良好,我可以存储值并在我运行的缓存中检索它们。

但是一旦部署在 Heroku 上,设置和访问缓存中的键不会做任何事情,也不会导致错误。

经过一番调查,我认为问题在于与我使用的 Memcached 服务的连接(在我的例子中是 Memcached 云)。

如何为我的暂存和生产环境设置 Laravel 以连接到外部 Memcached 提供程序?

我尝试使用在我的应用程序上安装 Memcached 云后提供的用户名和密码,但 Laravel 不使用它们。

在cache.php中

$memcachedURL = parse_url(getenv("MEMCACHEDCLOUD_SERVERS"));

...

'memcached' => array(

    array(
                'host' => $memcachedURL["host"], 
                'port' => $memcachedURL["port"], 
                'weight' => 100,
                'username' => getenv("MEMCACHEDCLOUD_USERNAME"),
                'password' => getenv("MEMCACHEDCLOUD_PASSWORD")
                ),
)

我应该编写一个 Memcached 连接器来使用这样的用户名和密码吗?如果是,您能否提供一些关于如何开始做的参考资料?

【问题讨论】:

  • 不是 Laravel 专家,但请注意 Memcached Cloud 应使用 Heroku 的 SASL(二进制)Memcached 协议连接。

标签: php caching heroku laravel


【解决方案1】:

我只是在调查同样的事情。似乎有两种方法可以解决。

  1. 您可以创建自己的缓存扩展。 http://laravel.com/docs/4.2/extending#cache

  2. 您扩展 \Illuminate\Cache\MemcachedConnector 以包含 setSaslAuthData 调用并将其绑定到 IoC 容器中。

MemcachedConnector 类 (https://github.com/laravel/framework/blob/4.2/src/Illuminate/Cache/MemcachedConnector.php) 有一个 getMemcached() 方法,它返回一个 Memcached 的实例。根据http://php.net/manual/en/memcached.setsaslauthdata.php,您可以在 Memcached 实例上设置 SASL 身份验证凭据。

因此,您可以继承 \Illuminate\Cache\MemcachedConnector 并将其绑定到您自己的服务提供商中的 $app['memcached.connector']。然后,您的子类可以覆盖 getMemcached() 以包含凭据。更多关于 IoC 基础扩展的信息:http://laravel.com/docs/4.2/extending#ioc-based-extension

【讨论】:

  • 我遇到了一个为 Elasticache github.com/atyagi/elasticache-laravel 构建的类似扩展。它使用您提到的第二种解决方案。我为 Memcached Cloud 调整了它,并没有覆盖 getMemcached() 方法,而是覆盖了 connect() 方法。我将代码粘贴为答案
【解决方案2】:

感谢@tscheepers 和@atyagi,这是我用来使它与 Memcached 云和 Heroku 一起工作的代码。

我还在 Packagist 和 Github 上提供了一个包,https://github.com/kintso/memcachedcloud-laravel

创建 Memcached 云连接器

class MemcachedCloudConnector {

/**
 * Extend the Memcached connection to use MemcachedCloud via Heroku
 *
 * @param array $servers
 * @throws \RuntimeException
 * @return \Memcached
 */
public function connect(array $servers)
{
    $memcached = $this->getMemcached();

    // Set Elasticache options here
    if (defined('\Memcached::OPT_BINARY_PROTOCOL')) {
        $memcached->setOption(Memcached::OPT_BINARY_PROTOCOL, true);
    }

    $memcached->addServers(array_map(function($server) { return explode(':', $server, 2); }, explode(',', $_ENV['MEMCACHEDCLOUD_SERVERS'])));
    $memcached->setSaslAuthData($_ENV['MEMCACHEDCLOUD_USERNAME'], $_ENV['MEMCACHEDCLOUD_PASSWORD']);

    if ($memcached->getVersion() === false) {
        throw new \RuntimeException("Could not establish Memcached connection.");
    }

    return $memcached;
}

/**
 * Get a new Memcached instance.
 *
 * @return \Memcached
 */
protected function getMemcached()
{
    return new Memcached;
}

}

通过服务提供者将其绑定到 IoC

// Based on https://github.com/atyagi/elasticache-laravel

class MemcachedCloudServiceProvider extends ServiceProvider {

/**
 * Indicates if loading of the provider is deferred.
 *
 * @var bool
 */
protected $defer = false;

/**
 * Register the service provider.
 *
 * @return void
 */
public function register()
{
        $servers = $this->app['config']->get('cache.memcached');
        $memcachedCloud = new MemcachedCloudConnector();
        $memcached = $memcachedCloud->connect($servers);

        $this->app->getProviderRepository()->load($this->app, array('Illuminate\Cache\CacheServiceProvider'));

        $this->app->make('cache')->extend('memcached', function() use ($memcached) {
            /** @noinspection PhpUndefinedNamespaceInspection */
            /** @noinspection PhpUndefinedClassInspection */
            return new \Illuminate\Cache\Repository(
                new \Illuminate\Cache\MemcachedStore($memcached, $this->app['config']->get('cache.prefix')));
        });
}

/**
 * Get the services provided by the provider.
 *
 * @return array
 */
public function provides()
{
    return array();
}
}

不要忘记在你的 app.php 文件中引用新的服务提供者,并确保你的 Memcached id 在你的 Heroku 应用中注册为环境变量。

【讨论】:

    猜你喜欢
    • 2016-11-17
    • 1970-01-01
    • 1970-01-01
    • 2016-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-29
    相关资源
    最近更新 更多