tail my trail

作るのも使うのも、結局は、人なのだ

WebSocket対応した噂のALB (Application Load Balancer) を試してみた

TL;DR

  • 2016年8月にAWSのLoad Balancerが WebSocketに対応した
  • スムーズすぎて心配になるくらい簡単に導入できる
  • 「うまい、はやい、やすい」ので、導入しない理由はないと思う

ALB Release!

巷では長らく噂になっていた、新しいAWSのLoad Balancer。 先月2016年8月11日についにリリースされた。待望のL7対応だ。

個人的に魅力の一つだったのはWebSocket対応。

従来のELBではWebSocket通信を終端できなかったため、 WebSocket通信の負荷分散/バランシングを行ったりSSL/TLS化する場合、 自前でバランシングする仕組みを実装したり、Nginxを前段に配置するなどちょっとした工夫が必要だった。 AWSのLoad BalancerがWebSocketサポートしてくれるのであれば、この設計構築および運用をアウトソース出来ることになる。ハッピーな未来しか見えない。

ちょうど時間ができたので、遅ればせながら試してみた。

新しいLoad Balancer, ALBとは

至るところで紹介されているので、ここでは簡潔に。

Application Load Balancer、通称ALBは、Elastic Load Balancerのラインナップの一つという位置付けで発表された。 以前のELBは "Classic Load Balancer" という扱いになるらしい。 Management ConsoleのLoad Balancerを開くと、以下のように2つから選択できるようになっている。

f:id:uorat:20160924224519p:plain

主だったUpdateは以下。 魅力盛り沢山!

  • Content-Based Routing (Path Based Routing):
    • URLパスに基いて、リクエストを異なるバックエンドサーバに振り分けすることが出来る
  • Support for Container-Based Applications:
    • ECS (EC2 Container Service) - ELB 連携対応、ポートマッピングやヘルスチェック定義の運用性が大幅改善
  • Better Metrics:
    • ポートやURLパス (ターゲットグループ) 毎のメトリクス、トラフィック(GB)、アクティブコネクション数、コネクションレートなどメトリクスを拡充
  • Support for Additional Protocols & Workloads:
    • WebSocketとHTTP/2 をサポート

引用: Amazon Web Services ブログ (日本語)

引用: AWS Blog (English)

WebSocketとLoadBalancer

これまでのWebSocketアプリケーションの構成

おさらい。

詳しくは以前の記事に記載しているが、従来のELBではWebSocket通信をサポートしていなかったため、 WebSocket通信の負荷分散/バランシングを行うためには、自前でバランシングする仕組みを用意する必要があった。

SSL/TLS化する場合も同様。ELBで終端することが出来ないためアプリケーション側で実装したり、Nginxを前段に配置するなどちょっとした工夫が必要だった。

これからのWebSocketアプリケーションの構成

通常のWeb Applicationと同じ構成が取れる。つまりこういう事だ。

f:id:uorat:20160924224649p:plain

Try it!

百聞は一見にしかず。試してみる。

なお、ALBの登場に伴い、AWSのLoad Balancerの構成要素が変わったので注意。一瞬面食らうが、思想がわかれば大した差ではない。

Make Target Group

今までのバックエンドサーバの設定が Load Balancer から独立し Target Group という要素に分離された。 L7対応ということでContent-based Routingが可能になったので、Load Balancerそのものと、後段のバックエンドサーバの定義の関係性が疎になったイメージ。

ということで、まずバックエンドサーバとTarget Groupを用意する。 バックエンドサーバは、以前使ったNode.js / Socket.IOなサンプルアプリケーションを再利用し、EC2上で稼働させる。

server

package.json

How to run

$ vim app.js
$ vim package.json
$ vim /usr/share/nginx/html/sample.html
$ npm install
$ node app.js

それからTarget Groupを作成する。

基本的に今までのELBのバックエンドサーバの設定箇所と同じ。 ここで設定/作成するTarget Groupを、後ほどALBに振り分けルールとセットで登録することとなる。

  • バックエンドのNode.jsサーバは :3000 で listen しているので、ProtocolはHTTP、ポートは3000を選択する
  • Health Check Pathは 今回は /socket.io/socket.io.js を指定する

f:id:uorat:20160924231855p:plain

まず、これでTarget Groupを作成。

その後、Target GroupにInstanceを登録する。今回はテスト用に2台のEC2 instanceを用意したので、これをTarget Groupとして設定する。

ここまで特にWebSocket特有の設定項目はない。

一点注意点として、Socket.IOベースのアプリケーションを使用している場合は、Target Groupの Attribute を編集してStickness を有効化すること。 つまり、Sticky Sessionを効かせる。

f:id:uorat:20160924225023p:plain

理由は後述する。

Launch ALB

次に、Load Balancerを作成する。

まず、Application Load Balancer を選択する。

f:id:uorat:20160924224519p:plain

ALBの設定画面はいつも通り

  • 名前とScheme (internet-facing か internal ) を決め、ALBのListenerとAZの設定を行う
  • Listner Protocol は Target Groupと同じくHTTP / HTTPS のいずれかを選択すれば良い

f:id:uorat:20160924231919p:plain

HTTPSを選んだ場合は証明書を選択し、続いてSecurityGroupを選択/作成する。

ここまでは従来のELBと同じ。

次にRouting先のTarget Groupを設定する。

先程作成したTarget Groupをルーティング先として指定する。 これがデフォルトのルーティング先となる。

f:id:uorat:20160924225429p:plain

前述したとおり、URLパスに基づいて複数のTarget Groupを登録することも出来る。 複数のサブシステムやマイクロサービスな作りをしているものを一つのLB、ドメインでまとめたり、アプリケーションコードを変えずにALBだけでパスルーティングを返ることが出来たり、 運用が幸せになる可能性を感じる。

設定内容が問題ないことを確認後、ALBを立ち上げる。

これだけ。 WebSocket特有の設定項目は必要ない。

Run!

このLoad Balancer経由でサンプルアプリケーションを稼働させる。

以下の sample.html を手元のPCで作成し、ブラウザで開くとサンプルアプリケーションが立ち上がる。

ブラウザのDeveloper ConsoleなどでHTTP Upgrade (101) やWebSocketの通信状況を確認して、無事接続確立していればOK。

f:id:uorat:20160924225800p:plain

心配になるくらい、驚くほどあっさり動いてしまう。

Socket,IO 利用時の注意点

前述したが、Socket.IOを利用しているWebSocketアプリケーションの場合、Sticknessを有効化しておく必要がある。 これはSocket.IOのハンドシェイク処理の仕様で、接続確立までに行われる幾つかのHTTPリクエストが同一サーバに固定される必要がある。 公式ドキュメントにも言及されている。

Socket.IO — Using multiple nodes

Sticknessが無効のままだと以下のように400エラーや502エラーが発生し、接続確立に失敗する。

f:id:uorat:20160924225829p:plain

この時のResponse Dataを見てみると、前リクエストでSession ID が見つからない旨出力される。

{"code":1,"message":"Session ID unknown"}

シンプルにWebSocketを話すアプリケーションは特にSticknessの有効化は不要だと思うが、 環境やブラウザによってはWebSocketを話せないケースもあるため、両方に対応可能なSocket.IOを利用するケースは多いと思うので、参考までに。

所感

何度も言うが、心配になるくらい、驚くほどあっさり動いてしまう。 簡単なチャットアプリケーションであれば、ALB前段にかませばそれで終了だ。

WebSocket接続用のEndpointの管理が不要となり、DNS Recordのメンテは初回以降不要。 SSL/TLS通信の終端先としても使えるのでReverseProxyを置く必要もなくなる。 Target GroupにAutoScaling Groupの登録もできるようなので、普通のWebアプリケーションサーバと同じ感覚でScalingできるようになる。

WebSocketアプリケーションの作りや規模によってはシャーディングっぽい作りが必要になることもあると思うが、 その際はTarget GroupとPath Rule追加して、同じALBにぶら下げれば良い。

ALBを活用すればランニングコスト、構築や運用にかかる労力ともに減るので、メリットしか感じられない。

がしがし活用していこう。

Nginxを用いたWebSocketサーバのReverseProxy構成及びSSL/TLS接続

TL;DR


今更ながら、随分前の作業メモが貯まっていたのと、もう一つの記事のつなぎとするために吐き出しておく。

WebSocket 通信のSSL/TLS通信をさせたりロードバランシングさせたい場合など、WebSocketサーバの前段にReverseProxyを置きたい時は Nginx (v1.3.13 以降) を使おうという話。

なお、AWSのELB (ALB: Application Load Balancer) を使っても実現できるようになったので、AWSで運用しているサービスの場合はALB使ったほうがお手軽省コストメリット大きいと思う。

はじめに


以前Node.js 自身でSSL/TLS通信する方法を記したが、 シングルコアで動作するNode.jsプロセスに、暗号化のオーバーヘッドまで食わせるのは非常にもったいない。 pm2などのNode.js製のクラスタリングツールでマルチプロセス化はできるとはいえ、Node.jsサーバのコンピューティングリソースは本来の責務であるアプリケーションロジックに集中させたい。

Nginx v1.3.13以降 のWebSocket Support

WebSocket接続のハンドシェイク時、HTTP/1.1 101 (Switching Procotols) というステータスコードとHop-by-Hopヘッダを使用してWebSocket通信への切り替えを行う。

2013年02月にリリースされたNginx v1.3.13 で、これらの仕様に対応された。

WebSocket proxying - http://nginx.org/

Since version 1.3.13, nginx implements special mode of operation that allows setting up a tunnel between a client and proxied server if the proxied server returned a response with the code 101 (Switching Protocols), and the client asked for a protocol switch via the "Upgrade" header in a request.

これをReverseProxyとして挟む。

Try it!


ということで試してみる。

Install Nginx

まずはインストール。

NginxのRepositoryを登録し、Nginxをインストールする。 Nginx 1.3.13以降であれば良いので、Latest versionをインストールする。

Ansible Playbookのサンプルを載せておく。

Nginx Configuration

設定方法は公式ドキュメントにあるとおり。

WebSocketのハンドシェイク時に使われる Upgrade ヘッダと Connection ヘッダ は Hop-by-Hop ヘッダ である。 通常のEnd-to-End headerと異なり基本的に一度の転送に対して有効なヘッダなため、ReverseProxyを間に挟んでいる場合これらのheaderはバックエンドサーバまで届かない。

以下、Hop-by-Hop ヘッダに関するRFCのリンク。

RFC 2616 - Hypertext Transfer Protocol -- HTTP/1.1

以下、Nginxのリンク。

WebSocket proxying - http://nginx.org/

As noted above, hop-by-hop headers including "Upgrade" and "Connection" are not passed from a client to proxied server, therefore in order for the proxied server to know about the client's intention to switch a protocol to WebSocket, these headers have to be passed explicitly:

Nginxも例外ではないため、WebSocket通信をプロキシする場合は明示的にこれらのヘッダをバックエンドに渡すようにする必要がある。

この設定を入れて、Nginxを起動する。

$ sudo systemctl start nginx.service

なお、後段のNode.jsサーバは、以前使ったサンプルアプリケーションを再利用する。

server

package.json

client

How to run

$ vim app.js
$ vim package.json
$ vim /usr/share/nginx/html/sample.html
$ npm install
$ node app.js

動作確認

ブラウザで動作確認してみる。複数のタブで sample.html を開いてそれぞれで投稿したコメントが同期できればOK。

f:id:uorat:20160919201007p:plain

画像左部のDeveloper Toolsでも分かる通り、101 (Switching Protocols) が通り、WebSocket接続が確立できていることが分かる。

Request / Response Headerは以下。Hop-by-Hopヘッダも期待通りセットされている。

Request URL

ws://your.domain.or.ip/socket.io/?EIO=3&transport=websocket&sid=3_K8sGX3W6bYyXAAAAAe

Request Headers

Accept-Encoding           : gzip, deflate, sdch
Accept-Language           : ja,en-US;q=0.8,en;q=0.6
Connection                : Upgrade
Cookie                    : io=lsIxmwKy6QY8s9ocAAAQ
Host                      : (your domain or IP)
Origin                    : http://your.domain.or.ip
Sec-WebSocket-Extensions  : permessage-deflate; client_max_window_bits
Sec-WebSocket-Key         : aZWrWEnJQsBvp38sAtBP1A==
Sec-WebSocket-Version     : 13
Upgrade                   : websocket

Response Headers

Connection                : upgrade
Date                      : Mon, 19 Sep 2016 07:30:43 GMT
Sec-WebSocket-Accept      : 9wz2i4UrQXQqilnyAtByxzwbwb8=
Sec-WebSocket-Extensions  : permessage-deflate
Server                    : nginx/1.10.1
Upgrade                   : websocket

WebSocket通信を暗号化する


SSL/TLS Termination

あとは、このNginx Reverse Proxy - cient間の通信を暗号化すれば良い。 普通に、サーバ証明書 + 中間CA証明書 と 秘密鍵を配置して ssl on; すれば良いだけ。

Nginx を再起動して、https で sample.html を開き直せばws通信もSSL/TLS化される。

Request URL

wss://your.domain.or.ip/socket.io/?EIO=3&transport=websocket&sid=uLFmikk0IVrjBy8bAAAb

非常に簡単。

HTTP/HTTPSとWebSocket (ws/wss) の両接続を単一のNginxで終端する

上述の Nginx の設定ファイルを見て分かる通り、locationを分けることで単一のNginx かつ同じ 443 portで、通常のHTTP/HTTPSとWebSocket (ws/wss) の両通信を扱うことが出来る。 今回のように両要件を共存で動かす場合や、一つのNginx Reverse Proxy クラスタ、同一ドメインでサービス提供する時などに活用できると思う。

※ステートレスな通信であるHTTP/HTTPSと違い、WebSocketは接続を持続するステートフルな通信となるので、リソースには要注意。

まとめ

Reverse Proxyを挟んでおくと色々と小回りが効き運用上も楽になることが多いので、前記事のように対応するよりもこちらの方がベターだと思う。 餅は餅屋。

ちなみに、2016年8月にAWSのElastic Load Balancerが WebSocketに対応した。ALB (Application Load Balancer) というらしい。 ELBのラインナップに含まれる形で、以前のELBは "Classic" という扱いとなるらしい。

また別に書くが、スムーズすぎて心配になるくらい簡単に導入できるので、AWSで運用している方はALBを使ったほうがメリット大きいと思う。 お手軽で省コスト。

nginx実践入門 (WEB+DB PRESS plus)

nginx実践入門 (WEB+DB PRESS plus)

Socket.io with Websocket の SSL/TLS 対応

※ (2016/9/19 追記) Nginx 使った対応方法も記載しているので、あわせて参考にして下さい。


昨今のサービスにおいて、暗号化はもはや必須の流れである。 GoogleFacebookなど主要なサービスはずいぶん前からHTTPS通信を標準としているし、HTTPS化対応しているサイトはSEO的にも優遇されるようになる という方針が出ていたりする。

前記事でSocket.IO + Redis PubSubを用いたリアルタイムメッセージ配信の仕組みをまとめたが、このままWebSocketを利用すると当然インターネット上を平文のテキストが流れてしまう。 また、チャット機能を呼び出す親元のWebページがHTTPSで提供されているものであれば、Mixed Content でブラウザによっては暗号化されていないWebSocket通信をブロックされることもあるだろう。 後からSSL/TLS対応を入れると往々にしてハマるので、ハナから対応しておくに越したことはない。

ということで、Socket.IOを用いたWebSocket通信をSSL/TLS対応させる。 以下、プログラム側での対応方法を記したが、NginxをWebSocket Proxyとして利用 できるので、NginxでSSL Terminationさせる手もある。

ポイント

f:id:uorat:20150830185442p:plain

  • ブラウザによってはWebSocket通信が利用できないことがあるため、Socket.IOでは、クライアントに適した通信プロトコルを自動選択する仕組みが実装されている。
  • セッションを張り続けて通信を行うWebSocketを使う以上、ボトルネックになりがちなロードバランサーを介することは推奨できない。
    • ロードバランサは最初の接続確立のみ利用し、WebSocket通信はクライアントからサーバに対して直刺しさせる

例えばAWSで運用している場合、SSL TerminationをELBに任せることが多いと思うが、WebSocket通信をELBを介さず行うため、サーバサイド (Socket.js on Node.js) で暗号化させる必要がある。

実装

サーバサイド

サーバに事前に配置したサーバ証明書、中間CA証明書、秘密鍵のセットをロードさせて起動することで、SSL対応が可能。 この対応で、Listenしたポートでhttps, wss通信が可能となる。

var fs = reqquire('fs');
var io = require('socket.io').listen(3000, {
    key : fs.readFileSync('/etc/pki/tls/private/your.domain.com.key').toString(),
    cert: fs.readFileSync('/etc/pki/tls/certs/your.domain.com.crt').toString(),
    ca: fs.readFileSync('/etc/pki/tls/certs/your.domain.com.cer').toString(),
    'log level':1
});

当然、証明書のドメインとWebSocket接続時にクライアントから指定するドメインは揃える必要がある。 ワイルドカードで証明書を作成していれば、例えば hostname.domain.com で接続させれば良い。

DNSにホスト名で名前解決できるようにA recordを登録しておく必要あり

クライアントサイド

以下のとおり、https で指定する。 "wss"ではない。 前に述べたとおり、handshake時にどのプロトコル (WebSocket / xhr-polling) で対話するかを採択するが、その通信は httpないしはhttpsで行われる。 handshakeが成功すると、wss または xhr-poolling over TLS で接続確立される。

<script src="https://hostname.domain.com:3000/socket.io/socket.io.js"></script>
<script>
    var socket = io.connect('https://hostname.domain.com:3000');

    ... your logic ...
</script>

ソース (※ 2016/5/15 追)

※ローカルのメモを転記しておく。

Socket.IOのdocumentaionにはSSL/TLS対応に関する記載が見当たらなかったが、ソース読んでみると明解。

Socket.IO

Socket.IO のコードを読んでみると、 `require('socket.io').listen した時に options.key があれば https#CreateServer 呼びだすロジックになっている。 ちょっと古いが、socket.io (v0.9.13) /lib/socket.io.js l63 - l66 抜粋

if (options && options.key)
  server = require('https').createServer(options);
else
  server = require('http').createServer();

Node.js - https.createServer

Official Documentationにあるとおり、 https.createServer の options は tls.createServer と同様で、以下のフィールドでSSL/TLS通信に必要なフィールドを指定できる。

https://nodejs.org/api/https.html#https_https_createserver_options_requestlistener https://nodejs.org/api/tls.html#tls_tls_createserver_options_secureconnectionlistener

終わりに

以上、Socket.IOでのWebSocket通信のSSL対応の一例としてプログラム側での対応方法を記したが、NginxをWebSocket Proxyとして利用 できるので、NginxでSSL Terminationさせるという方法もある。 手っ取り早く試すなら上記でも良いが、既にNginxを投入済みのサイトであればNginx WebSocket Proxyを用いても良いかも。

※ (2016/9/19 追記) Nginx 使った対応方法も記載しているので、あわせて参考にして下さい。

実践Node.js プログラミング (Programmer's SELECTION)

実践Node.js プログラミング (Programmer's SELECTION)

Socket.io + Redis PubSubでリアルタイムメッセージ配信

とあるサービスに「チャット機能」を追加しようという話になり、急ピッチで仕組みを用意することになった。 仕様/要件はふわっとしているものの、 2週間後にはリリースというケツは決まっている。 はてさてどうしたものかとその瞬間は思ったものだが、無事仕組みとして載せられたので、備忘記しておく。

リアルタイムチャット機能

要件は以下。

  • クライアントはWebブラウザとネイティブアプリ (iOS, Android)
  • 視聴者に軽量なテキストメッセージをbroadcastする
  • メッセージの永続化必須
  • 可用性/負荷分散も考慮する

例えば、動画を視聴しているとして、その動画の横に、自分含む視聴者のコメントが流れてくる、 ようなものを想像してもらえれば良い。

Socket.IO

「クライアント - サーバ間のリアルタイムなメッセージのやり取り」ということで、

という方針は早々に決まった。自動的にサーバは Node.js に決定。 ブラウザからのアクセスがあるため、xhr-polling / WebSocket をSocket.IO が両方サポートしていることは有難かったし、WebSocket通信を数行で始められる手軽さも魅力的だった。 ケツが2週間後なので実装コストがなるべく少なく済み、ビジネスロジックに集中できる方法を採択する必要があったため。

Socket.IOのポイントをまとめると、

  • WebSocket, xhr-polling をサポート、クライアントの動作環境に応じていずれかを自動採択する
  • "1 : 1" や "1 : N" のようなBasicな特定双方向通信、一斉配信 (broadcast)、接続単位を論理的に分離する 名前空間/namespace や 部屋/room 機能 など様々な配信方法をサポート

インストールは npm で一発 。 実装イメージは以下。

server side

var io = require('socket.io').listen(3000);
io.sockets.on('connection', function (socket) {
  
  ... your logic ...
  
});

client side

<script src="http://your.domain.com:3000/socket.io/socket.io.js"></script>
<script>
  var socket = io('http://your.domain.com:3000');
  socket.on('connect', function() {

    ... your logic ...

  });

  ... and so on...
</script>

ネイティブアプリ用のクライアントライブラリもある。 Socket.IOのGithub を見たところ、 C++ の実装もあるようだ。

Redis PubSub

Socket.IO on Node.js なWeb/Appサーバに対して、各クライアントはWebSocket通信で接続する。 接続数増と耐障害性を担保するためWeb/Appサーバの冗長化を考えた時に、一斉配信するメッセージを複数台のサーバにどのように伝達させるかで一瞬悩んだ。 所謂Publish / Subscribe ... ということで思い出したのがRedis。 "危険なほどのスピード" で有名なオンメモリKey-Value データストアで、扱えるデータ構造がMemcached と比べて豊富、ディスクへの永続化もあり人気のKVSだが、このRedis、PubSub も提供している。

1. 購読者 (subscriber) 、任意のkeyをsubscribeする

$ redis-cli
127.0.0.1:6379> SUBSCRIBE hoge
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "hoge"
3) (integer) 1

2. (別のターミナルで) 出版者 (publisher) 、1で指定したkeyでメッセージをpublishする

$ redis-cli
127.0.0.1:6379> PUBLISH hoge "hello pubsub"
(integer) 1

3. 購読者 (subscriber) の端末に、2で配信されたメッセージが表示される

$ redis-cli
127.0.0.1:6379> SUBSCRIBE hoge
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "hoge"
3) (integer) 1
1) "message"       ←追加
2) "hoge"          ←追加
3) "hello pubsub"  ←追加

Socket.IO - Redis の連携は容易。Socket.IOのバージョンによりインストール方法が若干変わる点に注意。

  • Socket.IO v0.9 系まで
    • Socket.IO 内に同梱されているため、特に追加インストールは必要なし。
    • 呼出は require('redis')
  • Socket.IO v1.0 以降
    • 外部ライブラリとして切り離された socket.io-redis をインストール
    • 呼出は require('socket.io-redis')

ちなみに、AWSのElasticCacheはRedisをサポートしており、Read Replica & Multi-AZも対応している。

PubSubはReplica Nodeに対しても有効で、PubSub sessionに関しても負荷対策が可能。

  1. Node.jsからReplica Nodeに対してSubscribe sessionを張っておく
  2. コメント投稿はMaster Nodeに対してPublish
  3. Read Replicaに対してSubscribeしている全購読者に配信される

WebSocketとELB

Socket.IO on Node.js サーバを冗長化させた場合の振り分け方も一工夫必要だった。 通常のHTTP通信と異なるため。注意点は以下の2点。

  • Cient - Server間の通信は通常のHTTP通信と異なりWebSocketで接続持続される
  • Socket.ioによるhandshake処理は必ず同一サーバに接続させなければならない

例えば、ロードバランサーを上段に挟む場合、全てのセッションがロードバランサーに対して張られることとなる。 通常のHTTPと異なりWebSocketのセッションを張り続けるという特性上、接続を集約させるロードバランサーボトルネックになる危険がある。 また、ロードバランサーによっては、Socket.IO/WebSocketの間に立てない場合がある。例えば、AWSのELB。

AWSのSolution Architectも、ELBは最初のセッション確立時にのみ利用してdispatchしてWebSocketさせるのが良いと言及している。

教えに従い、接続情報を返すAPIをクライアント側で呼出してから、サーバに対して直接WebSocket通信させる方式とした。

システム構成

行き着いたシステム構成は以下。

主機能がApache / PHPで動くWebアプリケーションのため、APIは既存資産を流用して実装。 Apahce/PHP を Node.js/Socket.IOと同梱させAPIを提供するようにした。 同梱させた理由は、接続情報管理の実装を省き自分のホスト名を返すようにしたかったため。 本来は、APIサーバは切り離して、ステータス含めて接続情報を管理するようにしたほうが望ましいと思う。

f:id:uorat:20150830185442p:plain

次回は、WebSocket接続のSSL/TLS対応をまとめようと思う。

Redis入門 インメモリKVSによる高速データ管理

Redis入門 インメモリKVSによる高速データ管理

Amazon Web Services クラウドデザインパターン設計ガイド 改訂版

Amazon Web Services クラウドデザインパターン設計ガイド 改訂版

Amazon Web Services パターン別構築・運用ガイド

Amazon Web Services パターン別構築・運用ガイド