sashima

GREEのUserAgent比率を公開します(2014/09)

もうすぐ開催されるGREE Tech Talk #06が楽しみな佐島です。

今月もGREEを利用して頂いているクライアントのUA比率を公開します。

グラフは以下のデータを元に作成しています。

  • 本データはGREEのSNSサービスのブラウザに基くデータです。
  • 本データの内容の正確性・信頼性については保証いたしかねます。
  • データはスマートフォンに限ったブラウザ比率を元に集計しています。
kyo_ago

GREEのUserAgent比率を公開します(2014/08)

サンダルは鼻緒派のago(@kyo_ago)です。

今月もGREEを利用して頂いているクライアントのUA比率を公開します。

グラフは以下のデータを元に作成しています。

  • 本データはGREEのSNSサービスのブラウザに基くデータです。
  • 本データの内容の正確性・信頼性については保証いたしかねます。
  • データはスマートフォンに限ったブラウザ比率を元に集計しています。
ZhouWenting

BMPを検証してみました

初めまして、ネットワークエンジニア周ウェンティンと申します。
GREEのサービスネットワークの運用設計を担当しております。
普段ネットワーク業界でストイックの人たちを集まる飲み会で皆の思いを聞くことが好きです。

今回はビジネスやサービスを越えて、世界最大のネットワーク機器開発会社であるCisco Systemsさん、日本大手ISP(Internet Service Provider)であるBIGLOBEさんと一緒にBMPというまだ標準化前段階のプロトコルを共同検証し、その結果をJANOG34で発表してきました。
その内容をご報告できればと思います。

背景

世界中のインタネットはBGP(Border Gateway Protocol)という通信プロトコルで接続してます。
ユーザネットワークを提供するインターネット事業者や企業などの組織間がどのように通信行うか、どの径路を通しているかを全てBGPのアルゴリズムで決められます。径路が変化したり、通信障害が起きたりする時はネットワーク機器間でBGPのやり取りによって検知されます。しかし、BGPはとても複雑で、また、ネットワーク機器によってOSやCLIが異なるためオペレーションも様々です。そのため、エンジニアの経験やスキルによってBGPが取得してくれた情報を完全に理解するのがとても難しいです。
そこで、今回はBMPを注目しました。

BMPとは

BMP(BGP Monitoring Protocol)はBGPをモニタリングするプロトコルです。
本来BGPはネットワーク機器間でしかやり取りを行わないですが、BMPはそのやり取りをサーバでキャプチャし、その結果を表示します。キャップチャしたデータをどのように表示するのがサーバの実装にもよりますが、ネットワーク機器メーカを頼らず、BGPの可視化が期待できます。

プロトコルの標準化

インターネットは無数なネットワーク機器が物理的にケーブルで繋がり、論理的には様々な通信プロトコルを用いて通信し合い構成されます。その様々な通信プロトコルは世界レベルで統一しなければいけません。実は、プロトコル標準化を行う団体が多数います。
例えば、IETF(Internet Engineering Task Force)と呼ばれている団体は主にインターネットで使用される技術(TCP/IPなど)の標準化を行います。また、標準化された文章はRFC(Request for Comments)と呼ばれていて、固有の番号が付与されインターネットで公開されています。
BMPはまだIETFドラフトな段階で、RFCされていません。そのため、対応するネットワーク機器がまだ少なく、BMPを普及させるには、我々サービス側にいる企業たちが「BMPを使ってみたい」、「こう言う機能が欲しい」ともっと声をあげなければいけません。
ちなみに、現在最新のIETFのdraft07ではBMPがVersion3になっています。

BMPのIETFドラフト
http://tools.ietf.org/html/draft-ietf-grow-bmp-07

BMPの共同検証

今回Cisco Systemsさん、BIGLOBEさんと一緒に共同検証を行いました。
最初は社内のラボで軽く検証しました。社内の検証機材ですと、BMP Ver1しか対応しせず、Googleで一般公開されているBMPサーバbmpreceiverでデータをちゃんと取れたことが確認できました。BMPの最新バージョンでもっとがっつり検証やってみようということで、Cisco SystemsさんとBIGLOBEさんがそれぞれハイエンドのネットワーク機器製品を持ち合い、さらにBIGLOBEさんがFull routeも流して頂き、2週間Cisco Systemsさんのラボ環境で三社で共同検証することになりました。

network dgram


通常の導入検証と違って、BMPはまだ標準化されてないし、サービスへ導入事例もないので、細かい機能が実装されなかったり、メーカや製品によって実装状況が異なったり、上手く動かないのは当たり前、さらに、一般公開なサーバがBMPの最新バージョンを対応しておらず、開発な方に新バージョンの実装をお願いしながら、そのコードを修正する度に検証し、当たり前のように失敗し、まだ開発者に修正を依頼し、また検証の繰り返し、本当に挫折ばっかりでした。
幸いCisco Systemsさんの社内検証用の内製ツールがBMPの最新バージョンを対応しているため、今回BMPの動作確認だけに使ってもいいということで、お借りして最終的に色々確認できました。

検証結果

BMPに期待するものが主に2つ

  • CLIで確認できなかったものをBMPで確認できる。
  • CLIで確認できたものの、BMPがよりシンプルに分かりやすく表示する。

また、BMPの評価ポイントが主に以下2点

  1. BMPでしっかりデータを取れるか

    • CLIで確認できないのは主に消えた経路情報(withdraw routes)になりますが、しっかり取れたことを確認できた。
    • CLIでも確認できるものはFilterする前後の経路情報を保持するデーターベース(Adj-RIB-In、Loc-RIB-In)、BGPのCapability、Notificationなど、そちらのデータも取れたことを確認できた。

    その中で、グリーが一番期待しているのはBGP Notificationでした。BGP Notificationに含まれたerror code(cease code)をきちんと表示できればトラブルシューティングがとても楽になります。検証を通じで分かったことは、BMPはあくまでもBGPのキャプチャなので、BGP Notificationの該当機能が実装されないと当然BMPが表示できません。
    また、トラブルシュートには時系列(timestamp)がとても重要ですが、ネットワーク機器側も、サーバ側もBMPのtimestampを実装しなければいけません。しかし、timestampはIETFドラフト上は必須機能ではないため、実装しない場合はトラブルシュートには使えなくなります。実際導入する際はネットワーク製品におけるBGPの実装、timestampの実装はキーになってくると思います。

  2. 取ったデータを上手く表示できたか

    見やすさという観点では、BMPサーバの実装によるものになります。検証の段階では一般公開されているBMPサーバはVer3を対応しているものがありませんでした。

検証結果についてBIGLOBEさんがまとめて頂きました。
http://www.janog.gr.jp/meeting/janog34/doc/janog34-rtabl-taiji-2.pdf

JANOGでの発表

日本でネットワーク運用者を中心に集まるJANOG(JApan Network Operators’ Group)というイベントがあります。
BMPがまだ知らない方がたくさんいらっしゃいますし、日本でBMPが検証されたのも今回初めてです。たくさんの方に知って頂いて、運用者たちのフィードバックを頂くため、JANOGの場をお借りしてBMPの検証を紹介させて頂きました。

JANOG34_0167


当日の同セッションでMultifeedさんがBMP以外の技術で経路情報を保持するための工夫を紹介して頂きました。とても面白かったです。セッションの発表については下記リンクをご確認ください。

JANOG34 Meeting ルーティングテーブルを覗きたい┃_・)ジー
http://www.janog.gr.jp/meeting/janog34/program/rtabl.html

JANOGで発表後、BMPサーバを作ってくださった救世主もいらっしゃいました。BIGLOBEさんのエンジニアブログにて詳細を記載しました。
BIGLOBEさんのエンジニアブログ
http://engineer.biglobe.ne.jp/201408/article_1.html

感想

一般の企業において、何かをサービスに導入する際、実績のあるもの、枯れた技術を使う傾向がありますが、サービスプロバイダーを除く、ユーザ企業ではネットワークの新しい技術を検証する機会がとても少ないのではないかと思います。
グリーを入社以来、異なる立場の会社を混ざって一緒に新機能の検証をするのも、またJANOGの発表も初めてでした。同じ技術を検証しても、会社のサービスによって期待する機能や活用する場所が全く異なりますし、サービス側かメーカ側かは立場によって視野も違うとしみじみ感じました。また、JANOGで発表を通して、すぐにサーバを実装して頂ける方も現れました。改めてJANOGというコミュニケーションの場の大切さも実感しました。
今後ともこのような機会がありましたら、ぜひまた参加したいと思います。

kyo_ago

Server Sent Events(SSE)の使いどころと使い方

Flameの箱を捨ててしまったためどうやって送り返すか困っています。@kyo_agoです。

今日は2014年6月にβ公開したGREEチャットで通信に使用しているSSEを紹介したいと思います。

SSEとは

SSEとはServer-Sent Eventsの略でW3Cで提案されているhtml5関連APIの一種です。

これはサーバとの通信やJavaScript APIを中心としたもので、サーバからPush通信を行うための仕様です。

サーバからPush通信に関してはこれまでもCometやWebSocketが存在しましたが、SSEは互換性や効率などの点でそれ以外の技術に対する特徴があります。

ここからは具体的な仕様や、実際に使用した場合の感想などを紹介したいと思います。

通信方式

SSEはHTTP/1.1を使用し、Content-Type: text/event-streamで通信を行います。

基本的な通信内容は以下のとおりです。

特徴はContent-Lengthが指定されていないことと、サーバから通信が切断されないことです。

この特徴によりクライアントはサーバから断続的に送信されてくるデータを随時受け取ることができます。

JavaScript API

SSEはJavaScriptから通信内容を取得するAPIとしてEventSource objectを提供しています。

基本的な実装は以下のとおりです。

new EventSourceの第一引数はSSE形式でデータを返すURL文字列です。

new EventSourceで生成したインスタンスはaddEventListenerでイベントを設定でき、’open’, ‘message’, ‘error’やその他サーバが指定したイベントを捕捉できます。

addEventListenerで捕捉したイベントはcallback関数の引数のdataプロパティで受信したデータを取得できます。

Cometとの違い

SSEはCometと同じような問題を解決するために策定され、技術的にも近いものになっています。

しかし、SSEは後発なこととW3C上で議論されていることなどから、Cometに存在した問題点がいくつか改善されています。

具体的には以下の様な違いがあります。

  • Cometはサーバから最初にデータを受信できた時点で切断し、次のデータは再接続して取得するため、SSEとくらべて再接続のコストがかかる。
  • SSEは専用のJavaScript APIが存在し、切断時の再接続、取得できたデータの履歴管理、カスタムイベントの提供が標準で行われる。
  • SSEは通信方式が仕様化されているため、サーバ側の各言語やフレームワークでライブラリ等が提供されていることが多い。
  • Cometは通常のHTTP通信に近い動作を行うため、ブラウザの互換性が高い(SSEはAndroid標準ブラウザ等で動かすために特殊な対応が必要な場合がある)

WebSocketとの違い

WebSocketはSSEとくらべて広い利用方法を想定して定義された仕様ですが、利用方法として「サーバからのPush通信を行う」ことも含まれているためSSEとかぶるところがあります。

本来、SSEが既存の技術の組み合わせで作られていることに対して、WebSocketは既存の技術のしがらみ無しに作られていることから単純な比較が難しい部分もありますが、合わせて語られることが多いためここで比較したいと思います。

WebSocketとSSEは以下の様な違いがあります。

  • WebSocketはHTTPではなく専用のプロトコルを使うため、パフォーマンスが高い
  • SSEはHTTPを使うため、通信の互換性が高い。
  • SSEはHTTPのため、既存のセキュリティモデルを流用できる(既存のセキュリティモデルに引っ張られる)
  • SSEはHTTPなので、同じOriginの別URLでコンテンツを提供できる(htmlやjs, css、画像、他のSSE API等を同じドメインとポートで提供できる)

ブラウザ互換性

SSEは仕様上JavaScript APIが定義されているため、ブラウザがサポートしていない場合JavaScriptからAPIを呼び出すことができません。

ただ、これに関してはXHRを使ったPolyfillが公開されているため、IE等のSSE未サポートブラウザでも大半の動作は同じように動かすことが可能です。

(ちなみに、このPolyfillはSSEをネイティブでサポートしているブラウザのバグを潰す目的でも開発されているため仕様との互換性はネイティブのEventSourceより高い場合もあります。ただし、内部でXHRを使っているためAndroid標準ブラウザや古いIEなどのXHR自体に問題のあるブラウザでは動作がおかしい場合もあるため注意してください)

各通信方法との比較

それぞれを簡単に比較すると以下のとおりです。

SSE WebSocket Comet
通信コスト
JavaScriptAPI
サーバサイドサポート
通信互換性
仕様安定性
ブラウザ互換性

通信コストはWebSocketが効率的です。SSEは接続を維持するためCometよりは効率的に通信が可能です。

JavaScriptAPIはSSE、WebSocketは仕様化されているものが存在しますが、Cometの場合独自に定義する必要があります。

サーバサイドサポートに関してはSSE、WebSocketは仕様化されているため各種言語でのライブラリが提供されていますが、Cometは仕様化されていないこともあり存在しない場合もあります。

通信互換性に関して、WebSocketは独自プロトコルのため接続できない場合もあります。SSE、CometはどちらもHTTPを使用しますが、Cometの方が通常のHTTP接続の形式に近く接続性は高いと思っています。

仕様安定性に関して、SSEはプロトコル自体が簡単な事もあり仕様バージョンで混乱することはないと思います。WebSocketは過去に若干通信バージョンが混乱しましたが、現在では比較的安定しています。Cometはそもそも決められた仕様が存在しないため細かい部分で調整が必要になる可能性があります。

ブラウザ互換性に関して、Cometだと古いIEやAndroidでも比較的容易に接続できますが、SSEだとPolyfillを使っても素直に接続できない場合があります。WebSocketはFlashなどを使ってPolyfillを作成することも可能ですが、Androidの標準ブラウザはFlashが動作せず、WebSocket自体もサポートされていないため対応が困難です。

SSEの問題点

ここからはSSEを実際に使ってわかった問題点を紹介したいと思います。

  1. ブラウザの実装にバグが多い(Polyfillがブラウザ実装無視してオブジェクト乗っ取るレベル)
  2. デバッグ辛い(Polyfillのコードがかなり複雑なのと、そもそもStream通信のデバッグは辛い)
  3. Polyfillのパフォーマンスは高くない(初期化コストはネイティブオブジェクトとくらべてiPhoneだと体感できるレベル)
  4. Android 2系の対応は辛い(特にCORSと絡めるとほんとうに辛い)

(1)に関しては基本的にPolyfillを使うことで回避できますが、最新のブラウザだと改善されている項目も多いため、UA判断でネイティブオブジェクトを使用しても問題ないと思います。

ちなみに、ブラウザ上のバグはPolyfillでテストケース化されています

(2)はおそらく仕様上解析が大変な部分があることと、パフォーマンス的な意味でPolyfillのコードが複雑なため、通信中のデバッグはかなり困難でした。

ただ、そもそもネイティブオブジェクトでデバッグを行う場合内部状態が外から参照できないため、コードが複雑であってもPolyfillを使用して開発したほうが楽な部分はあります(SSEのイベント発火前にbreak pointを入れたりできるので)

(3)は、実際SSEを使用する場合Polyfillは必須に近い存在ですが、やはりネイティブオブジェクトと比較するとパフォーマンス的に若干ペナルティがあります。

そのため、できるだけ速度を稼ぎたい場合はUA等で切り出してネイティブオブジェクトを使ったり、そもそもSSEではなく素のXHRで対応するほうが良いと思います。

(4)のAndroid 2系に関しては、今回htmlとSSE APIのドメインが違ったことで特に対応が困難でした。

Android 2系は元々一回のデータ受信が4KBを超えないとXHRからデータを取得できないというバグがあり、PolyfillもXHRを使用しているためこの影響を受けます。

更にAndroid 2系はXHR Level2をサポートしておらずCORSが使えないため、対応するためにiframe経由のpostMessageでデータのやり取りを行いました。

これ自体SSEの問題というわけではありませんが、実際対応をする場合には注意してください。

本当のSSE

ここからは一般的に言われるSSEの評価と使ってみての実感を紹介します。

SSEは一般的にEventSource, frankly, sucksと言われますが、Polyfillを使用すればEventSource自体はそこまで大きな問題と感じませんでした。

ただ、Polyfillは実装が複雑でデバッグが難しく、Android等の問題があるブラウザ上での開発は難しいと感じました。

速度的にはPolyfillを使用しても十分な速度ではありますが、高速なデータのやり取りをする場合ネイティブオブジェクトを直接使用するほうが高速に動作します。

また、Polyfillはブラウザがネイティブ実装を持っている場合でもPolyfill objectでの動作を優先しますが、最近のブラウザではネイティブオブジェクトの動作も改善しているため場合によってはPolyfillなしでも実装は可能だと感じました。

(それでもPolyfillの方が仕様への準拠度が高いことと、各ブラウザの動作を統一したかったためPolyfillを使用しました)

SSE自体に関してはプロトコル、APIともに比較的単純なため、簡単なサンプル実装や、本格的に実装する上で困難になる部分はありませんでした。

SSEの今後

ここまでSSEの過去、現在を紹介してきましたが、最後にSSEの今後に関して紹介したいと思います。

SSEは仕様的に現在「勧告候補(Candidate Recommendation)」ですが、各言語のバインディングやブラウザ上の実装も進んでいることから、今後仕様レベルで大きな変更が行われる可能性は低いのではないかと思っています。

では、今後SSEが大きく使われていくかというと個人的には疑問があります。理由として、SSEはあくまでもCometの発展形であり、既存のHTTP上でこれまであったXMLHTTPRequestでPolyfillが書ける範囲の機能しか提供しないためです。

もちろんサーバから簡単にPush通信を送る場合には便利な方法ではありますが、もしWebSocketが使えるのであればWebSocketを使う方が良いと思います。

このため、ネットワーク上の互換性が進み、WebSocketがHTTP並に接続できるようになればあえてSSEを使う理由は小さくなっていくと思います。