There is a not-so-obvious way to check whether or not a MemCache-Server is available.
Using ($memCache->connect() == false) will wait for a timeout if it can't connect. If you got a high-traffic site this may not be an option. So when the server is down, you may want to avoid waiting for this timeout on every request and instead try to reconnect only once every X seconds.
If so, this code may help:
<?php
$memCache = new Memcache();
$memCache->addServer($host, $port);
$stats = @$memCache->getExtendedStats();
$available = (bool) $stats["$host:$port"];
if ($available && @$memCache->connect($host, $port))
// MemCache is there
else
// go on without MemCache
?>
The result of getExtendedStats() is an array. The information is cached and maintained by MemCache itself. If the server is not available, the result will be FALSE.
Even if the result is not false, the server may still not be available. Thus you need to check for connect() != false too, but only if the first check returns TRUE, thus avoiding the 1 second timeout in most cases.
Both getExtendedStats() and connect() issue notices/warnings if the server is not there. Thus you have to mute both calls.
Do NOT use getServerStatus() for this purpose: the result is cached on server-start and will not recognize when the connection to the server is lost (or reestablished) in between.
Memcache::connect
(PECL memcache >= 0.2.0)
Memcache::connect — memcached サーバーへの接続をオープンする
説明
$host
[, int $port
[, int $timeout
]] )Memcache::connect() は、memcached サーバーへの接続を 確立します。 Memcache::connect() を使用してオープンされた接続は、 スクリプトの実行終了時に自動的に閉じられます。 Memcache::close() を使用して閉じることも可能です。 memcache_connect() 関数を使用することも可能です。
パラメータ
-
host -
memcached が接続を待ち受けるホストを指定します。 このパラメータには別のトランスポート層を指定することもできます。たとえば unix:///path/to/memcached.sock のようにすると Unix ドメインソケットを使用できます。この場合、
portは 0 を指定しなければなりません。 -
port -
memcached が接続を待ち受けるポートを指定します。 Unix ドメインソケットを使用する場合は、このパラメータを 0 とします。
portを指定しなかったときのデフォルトは memcache.default_port となります。そのため、このメソッドをコールするときにはポートを明示しておくことをおすすめします。 -
timeout -
デーモンへの接続の際に使用する値 (秒単位) です。 デフォルト値を 1 秒でも変更する前には十分注意してください。 接続が遅くなってしまうと、 キャッシュ処理のメリットが なくなってしまいます。
注意
port を省略した場合は、PHP の ini 設定
memcache.default_port
の値をデフォルトとして使います。
もしこの値がアプリケーションのどこかで変更されていれば、予期せぬ結果を引き起こすかもしれません。
このメソッドをコールするときには、常にポートを明示しておくことをおすすめします。
返り値
成功した場合に TRUE を、失敗した場合に FALSE を返します。
例
例1 Memcache::connect() の例
<?php
/* 手続き型の API */
$memcache_obj = memcache_connect('memcache_host', 11211);
/* オブジェクト指向の API */
$memcache = new Memcache;
$memcache->connect('memcache_host', 11211);
?>
To suppress (or handle) the warning and notice thrown by a failed attempt to connect, you can use a custom error handler function, like this:
<?php
function myErrorHandler($errno, $errstr, $errfile, $errline)
{
if (E_WARNING === $errno)
{
Log("PHP Warning: $errstr, $errfile, $errline", Logging::WARN);
return true;
}
if (E_NOTICE === $errno)
{
Log("PHP Notic: $errstr, $errfile, $errline", Logging::NOTICE);
return true;
}
return false;
}
set_error_handler('myErrorHandler');
?>
If memcached is working, calling memcache_connect( ) returns an Object instance, not a boolean. If memcached is not working, calling memcache_connect( ) throws a notice AND a warning (and returns false as expected).
<?php
/* memcache is running */
$test1 = memcache_connect('127.0.0.1',11211);
echo gettype($test1);
// object
echo get_class($test1);
// Memcache
/* memcached is stopped */
$test2 = memcache_connect('127.0.0.1',11211);
/*
Notice: memcache_connect(): Server 127.0.0.1 (tcp 11211) failed with: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.
(10060) in C:\Program Files\Support Tools\- on line 1
Warning: memcache_connect(): Can't connect to 127.0.0.1:11211, A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.
(10060) in C:\Program Files\Support Tools\- on line 1
*/
echo gettype($test2);
// boolean
echo $test2===false;
// 1
?>
There appears to be no way to check whether memcached is actually running without resorting to error suppression:
<?php
$test3 = @memcache_connect('127.0.0.1',11211);
if( $test3===false ){
// memcached is _probably_ not running
}
?>
The behavior of Memcache::connect() is to always reinitialize the pool from scratch regardless of any previous calls to addServer().
E.g.
<?php
$mmc = new Memcache()
$mmc->addServer('node1', 11211);
$mmc->addServer('node2', 11211);
$mmc->addServer('node3', 11211);
$mmc->connect('node1', 11211);
?>
The last connect() call clears out the pool and then add and connect node1:11211 making it the only server.
If you want a pool of memcache servers, do not use the connect() function.
If you only want a single memcache server then there is no need to use the addServer() function.
