昨日、一時的にサービスが落ちていました。

15時くらいにサーバの1つが突然繋がらなくなり、何かやっちまったのか(例えばデータベースへの過剰なアクセスとか)と思ってサーバを再起動してみたのだけど全然ダメでおろおろしていたら、しれっとこんな告知が出てました。

メンテナンス・障害情報・機能追加|さくらインターネット公式サポートサイト

平素よりさくらインターネットをご利用いただき、誠にありがとうござ います。 本日、ご提供サービスにおきまして、以下の通り障害が発生いたしました。 ご利用中のお客様には大変ご迷惑をおかけしておりますことを深くお詫び 申し上げます。



影響範囲 : さくらのVPS 1Gプランの一部
IPアドレスが下記の範囲のお客様
219.94.245.15 ~ 219.94.245.134

障害内容 : サーバに接続できなくなる障害が発生しました。
障害によりVPSの意図しない再起動が発生しました。


ああうん、ドンピシャだよさくらさん。

いままでここまでビシッとターゲットになったことが無かったのでちょっと驚きました。発生したのが15時20分で復旧したのが18時05分。何が原因か解らないけど(機材の故障かなぁ)さすがに3時間とめられるのはきついなー。まぁ、障害発生は仕方ないか。ただせめてメールでお知らせくらいして欲しいなーと思いました。障害情報をRSSで読むといっても、それを読むRSSリーダーが今障害が起きているサーバに載っていたので。

とりあえず、データに何の問題も無くて良かったです。やれやれ。




個人的な反省

止まったのはバックエンドに使用しているサーバで、データベース(MySQL)と管理ツールが動いてました。なのでサイトの表示は基本的に問題なかったんですけど、通信が発生するサービスで上手くサービスダウンを表現出来てなかったところがありました。例えばTumblr Thumbnailsとか。ページ読み込み中がずっと続いてしまうという。

コード見てみたら、データベース接続失敗で投げる例外を手前で拾った後何もせずfalseを返す仕様になってて、処理自体は続行されるみたいな感じになってました。だめじゃん。

データベース接続ライブラリ(抜粋/イメージ)

static public function connect()
{
try {
if(!self::$connection)
self::$connection = new PDO('mysql:host=' . self::HOST . ';', self::USER, self::PASSWORD);
return self::$connection;
} catch (PDOException $e) {
//logging
} catch (Exception $e) {
//logging
}
return false;
}

サービス側のコード(抜粋/イメージ)

public function __construct()
{
if(!$this->getPdo())
$this->setPdo(MyMysqlConnectionHandler::connect());
}


データベース接続ライブラリでは成功/失敗を返り値で判断するように設計されているのに対し、サービス側では例外を返すことを期待した設計がされているという。どっちでもいいけどどっちかにしないといけないわけで、影響範囲を考えると「サービスとしては例外投げて欲しいけどライブラリがこうなっちゃってるからしょうが無い返り値見るわ」ということにしないとダメですねぇ。失敗した。


というわけでとっとと改修しましょう。すみません。