PHPアプリケーション開発を支えたAzure

satoryuさん:少し長いんですが、このようなタイトルでお話しさせていただきます。よろしくお願いします。

自己紹介なんですけれども、私さとうと言います。よくTwitterとかGitHubだとアンダースコアを抜いたり入れたりするといろいろなところで見つかると思うので、探してみてください。satoryuとかよく呼ばれています。

だいたいRubyメインでやっていたんですけれども、最近のPHPとかNode.jsとか、Azureを触るようになって、少しC#を触ってみたりとかしています。

まず始めに8周年おめでとうございます!

ということですばらしいですね、という裏で、実は私が担当している「Rakuten Super English」というサービスが、この9月で1周年を迎えました。

(会場拍手)

すみません、ありがとうございます。

この「Rakuten Super English」というのは、英語学習のアプリケーションでC向けに提供しているものと、もう1つ企業さま向けに英語学習のサポート、弊社が英語公用語化をやったように、同じようにもっと進めていきたい会社さんがあるので、そこに行ってサービスとかコンサルティングでサポートするということをやっております。

そのなかのシステムとして、今我々が提供している「Learning Record」というのがございまして、これは従業員の人たちがどういった英語学習をしたのかをシステムにどんどん報告していく。

その学習時間を管理職やHRの人たちが分析して、どのような英語研修や施策を提供したらいいかを考えて、フィードバックループを回していって、英語学習をどんどん促進しましょうというような、弊社でけっこう困っていたようなところをシステム化したというのが、この「Learning Record」です。

現状、BtoBのサービスはけっこう展開しているんですが、そのなかで実際「Learning Record」を契約しているのが2社で、けっこう規模の違うものが2つあります。

この開発を昨年の5月ぐらいから始めて、立ち上げの時期から3名のエンジニアで、弊社には一応オンプレのデータセンターがあるんですけれども、それをまったく使わずに、完全に僕たち3人の趣味なんですが、今回は全部Azure縛りでぶっこもうというので勝手にやりました。

今日話すことなんですが、最初のPoCの段階から現在までの、我々のサービスのなかで使ってきたアーキテクチャやAzureサービスの構成の変遷についてお話しさせていただきたいと思います。

PoCから現在までの変遷

今日は、その上でPHPのアプリケーションと言っているんですけれども、これをどうやってPHPで書くかとか、サービスについての詳細は今回はまったく触れませんので、ご了承ください。

最初にPoCをしていた時なんですけれども、この時点ではさっきみたいなフィードバックループを提供したらいいよねというぐらいで、実際にどんな画面にするかとか、どういうデータをとるかということについてはなにも固まった要件がない状態でした。

この状態から開始して、とにかく週1でお客さんのところに行って、「こんな感じなんですけれども」というのをデモをしながら進めていきました。突然の訪問でいきなり決まることもあって、お客さんから呼ばれたりすることもありました。

こういう状況でやろうとすると、すぐに変更をリリースできるような状態で、そのままPCを持っていく、ブラウザを開いて見せられるような状況というのが求められていた状態です。

この時は、とにかくPHPのアプリが動けばいいやというぐらいで、当然選択肢としてはWebAppsでしょうと。VMなんで構築している暇はないと。

この時にCosmosDB、まだドキュメントDBと呼ばれていた頃にこれを採用しました。これ何でやったかというと、要件が固まっていないので、とにかくドキュメントDBのほうがいいだろうと思っていました。

MySQLも使いたかったんですけれども、この時はまだプレビューで怪しいなと思いながら見ていたので、避けてCosmosDBにしました。

サービスイン後の課題

そんなこんなで、サービスインを迎えることも、なんとか昨年9月に決まりまして、ここから本番稼働ですと。

お客さまの要望としては、初期の利用者、会社のなかで先行して利用する1,000人ぐらいにメールを送りたいとか、利用状況、どれぐらいちゃんと使っているかとかを把握したいとHRの人に言われていたので、こうやって本番稼働するには、一応うちの会社のレギュレーションどおり、ちゃんとうちの会社のドメインを載せなければいけないと。

AzureWebSites.netなんていうのはダメだというのが当然ですよね(笑)。そして一気に1,000通ほど送らなければいけないというのは、バックエンドのシステムにほしいなと。そして効果測定もどうしようということで、いろいろ追加しました。

Traffic ManagerとAzure FunctionsとApplication Insightsをこの時点で突っ込んでいます。

一応ストレージの旧サービスも新しく入っているんですが、これはAzure Functionsのためです。

Traffic Managerはたぶんご存知だと思うんですけれども、DNSレベルで負荷分散をしてくれるサービスです。弊社のDNSからいったんこのTraffic Managerに飛ばして、Traffic ManagerがCNAMEを持っているので、そいつからWebAppsに対して誘導してくれるというやつです。

そして今のでドメインは解決して、Azure Functionsでバックエンドの負荷の多いところをやらせました。

というのは、SendGridを使ってたくさんメールを送るというのを実装していただいて、フロントからやるとこの規模だとタイムアウトしてしまうので全然できないと。

トリガーも別にフロントに持たせる必要はないので、ここでやっています。

そしてApplication Insightsというのもありまして、僕はこれが個人的に大好きなんですけれども、アプリケーション自体のメトリクスから、Azure Functionsのサーバーとか、どういったログが出ているかというのを、全部一元に収集してビジュアライズとかしてくれるサービスです。

Javaスクリプトをフロントエンドに組み込むと、ユーザーがブラウザ上でどういう行動をしたかとかというイベントをとったりとかもできて、アクティブユーザーとかリテンションとかをとったりするのがすごく便利です。

あとで死活監視までやってくれるというのが、なかなかすてきなサービスになっています。

新たな要望に対して取り組んだこと

実際サービスインしてくると、当然当初の要望とは違うことをコロッと言ってくるのがお客さんなので、新しい要望が出てきて当然なんですけれども、最初は「学習の記録ができて、従業員の学習の習慣化ができればいい」と言っていたのが、今度は「どれぐらいちゃんと勉強しているかを見たいし、それを上に報告したい」ということを言いだすわけです。

要は従業員の人を詰めたいと。

(会場笑)

そしてHRとして週にどれぐらいというのをやりたくて、ダッシュボードをつくろうと。CosmosDBにやらせようとすると、ジョインができないし、リレーションなんてちゃんと貼れないしということで、僕がゴリゴリアプリケーションからやったら3分かかってしまうという具合で、当然タイムアウトで死んでしまいます。

そしてMongoDBのアプリケーションに任せようと思ってやったんですけれども、CosmosDBは当然対応してません。

やっぱりSQLが欲しくなるということが起きてくるので、ここでやったのがこんな感じで、CosmosDBからData Factoryを使って、SQLにただデータを流しました。

ダッシュボードの画面だけはAzure SQL Databaseに繋いで表示するということで、これでいったんハッピーになるということをやりました。

データベースを移行する

でも、次に僕たちが今度は勝手にデータベース(DB)移行したいよねと思い始めるわけです。

なんで不服か。CosmosDBはけっこうつらいんですよ(笑)。あのぐらいの規模で別に日本の会社さんに提供しているので、グローバルな分散とかいらないんですね。いらないですよね(笑)。

僕たちが欲しかったのはドキュメントデータベースだけだったので、もういらんと。そしてだいたいスキームも決まってきたので、もういらんと(笑)。

なので、SQL Databaseと組み合わせて、CQRSっぽくもできそうだよねみたいな話もしていたんですけれども、そんな要件必要でしたっけみたいなのであったり、コレクションを1個持っているだけでけっこうなお金をとられてしまうので、やはりSQLだ! ということでデータベース移行をしました。

なかなかAzure産物的な感じがして、Data Factoryとスロットを使って、スロットでずっとSQL Database版をリリースしまくって、本番のデータをコピーして、本番のデータを実際に試しながら検証するというのが進められました。

実際にデータベース切替をどうするかというのはとても簡単で、スロットをスワップして完了ですというぐらいのことをしました。

普通、データベース移行はけっこうやりたくないんですけれども、すごく気持ちよくすっきり終わらせられたので、これは最高だったなと思っています。

Azure SQL Databaseはメインのデータベースとして、今度はちゃんと書き込みもするし、さっきのダッシュボードの画面でも使えます。

CosmosDBはCosmosDBで、セッションとかキャッシュとかで、割とこれは優秀だったので、今は残しています。でも最近これもつらいなというのがあって、Redisにしたいなという話もしたりしています。

とにかくCosmosDBはつらいです。

現在の課題と運用

現在は最初のA社さんからもう1社のB社さん、小さい規模で契約をゲットして、サービスレベルはかなり異なっているので、同じWebAppsとかデータベースで回すのは少しきついねということで、分けました。

本当はこういうことをやりたかったんです。

サブドメインをとって、それぞれのTraffic Managerに流して、よし、違うWebAppsだというふうにやりたかったんですけれども、社内の事情で難しく。でも、お客さんがすぐ使いたいと言い始めているので、ここから紹介する方法は推奨される使い方ではないです。もう無理矢理こねくり出した方法で、URLパスで解決しようと。笑えますよね(笑)。

Application Gatewayを使って、パスがAときたらA社さん、BときたらB社さんに流そうと。

そうしたらドメインは変えなくていいというすばらしいアイディアが思い浮かんだんですけれども、当然まずいですよね。

Traffic ManagerからしたらApplication Gatewayからうしろなんて見えないので、アプリケーションは1つに見えてしまうし、つまりどっちかが死んだら引きずられてもう1つも死ぬという状態ですし、これを冗長化しようと思ったら、別に大した規模ではないB社さんの分母を冗長化させなければいけないという、なかなかスケールが難しい問題なんです。

ですが、今のところこれで満足できている……? なんで俺は自信を持って言えないんだ(笑)。

(会場笑)

という感じで、今はこのかたちでなんとか動いています。

弊社のなかではAzureをフルでやるのはけっこう珍しい感じがして、よくIDとかポイントとか、そういったものと結び付けてやるのが多いんですけれども、今回はそんなの関係なしに、初のBtoB向けということでやりました。

状況に応じて柔軟に、即時にアーキテクチャの変更をサポートしてくれるのは、Azureはすばらしいなという話です。

ありがとうございました。

(会場拍手)