プレビュー版のようですが、
MySQLと互換性をもつRDSが発表されましたね。
詳しくは、こちら。
ちょっと気になるのは、
AmazonのEC2で選択できるAmazonLinuxって、centos6系をベースにカスタマイズされたものだったような。
centosは7から、標準レポジトリにMySQLが外れて、mariadbになってたから、
当面はAmazonLinuxはcentos7には上げないのかね?
EC2とRDSで違うから、問題ないのかもしれないけど、
mariadbもaws(特にRDS)で使えるようになると、今後もっと流行りそうな気がします。
投稿日時:2014年11月26日 13:16
カテゴリー:
aws,
mariadb,
mysql
今のところ、3回にわたりwebsocketの比較を書いてきましたが、
これからは、
となります。
とその前に、一服。
個人的な見解としては、
node.jsよりjavaの方がwebsocketは組みやすいかなと思っています。
理由は、
- 過去資産が豊富なので、選択肢が多い
- 型制約があるので、全体的に堅牢になる
- eclipseなどのIDEが優秀
といったところでしょうか。
node.jsはjavascriptなので、
なんでもできてしまう分(たとえば、ユーザ定義オブジェクトになんでも突っ込めるとか)、
コードがわかりにくくなりがちです。(※規約で気を付けないとね)
また、IOが基本的に非同期で実行されるとかが、
やっぱりやりにくいなと感じてます。
ただ、java側はAPサーバを動かすコスト(メモリ消費)がやや高いので、
省エネなのはnode.jsかなとも思います。
ちなみに、javaでwebsocketをやる場合、
jetty8とかは独自実装になっており、
jetty9でJSR356に対応してます。
※jetty9の場合、jettyの独自パッケージの中で、JSR356に読み替えているようです。mavenのpomファイルも後で作成します。
JSR356に対応しておけば、tomcatに移植しても動くので、独自実装はもう使わないほうがよかです。
なお、あのplayframework2.3のwebsocketはjetty8でした。(playは機能面はすごいけど、ちょっと重いよね。。)
最終的には、どちらもクセはあります。
取り巻く環境、開発者の経験等を考慮して、
選択するとよいと思います。
(go言語なんかでもやっている人はいるのかな?goはこれから勉強します。)
投稿日時:2014年11月26日 13:04
カテゴリー:
java,
node.js,
websocket
前回の続き。
前回の大切な前提として、
pub/subはなし(つまり、メモリ内で処理を完結可能)
というのがありました。
実際に対戦ゲームの作成を通して、処理フローを整理しましょう。
別に面白いものを作る必要はないので、
簡単なゲームとして、以下のような仕様とします。
- 2人対戦の神経衰弱
- ゲームの種別として、4×4、4×8、4×12の3種類(使用枚数が16枚、32名、48枚)
- ユーザはマッチング時に、ゲーム種別を選択可能
- マッチングが成立したらゲーム開始
- ゲーム中に離脱した場合、その時点で残っている人の勝利
- 離脱者なしにゲームが終わった場合、自分の取得枚数が多ければ勝利で、少なければ敗北
pub/subはないので、
スケールアウトの手段が現状皆無です。
そこで、URLを絡めて、効果的にスケールアウトができるようにしておきましょう。
URLはこんな感じです。
【マッチング】 /ws/matching/${type}
${type}とは、上記の4×4などをコード化したもの
【対戦】 /ws/round/${pairId}
${pairId}とは対戦者同士を結びつける一意のキーで、形式は0-9a-zの繰り返し
こんな感じでURLを設計しておくことで、
websocketのリバースプロキシ可能なサーバ(nginxやapache2.4など)で、
URLに応じた振り分けが可能となります。
この設計方式だと、マッチングが成立したら、
一旦マッチングサーバとの接続を閉じて、
新たに対戦サーバと接続する必要があります。
※nginxの設定例
vim /etc/nginx/websocket_params
proxy_read_timeout 300;
proxy_connect_timeout 300;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Document-URI $document_uri;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
vim /etc/nginx/conf.d/game.conf
# マッチング4x4
upstream ws_matching_4x4 {
server localhost:8081;
server localhost:8082 backup;
}
# マッチング4x8
upstream ws_matching_4x8 {
server localhost:8083;
server localhost:8084 backup;
}
# マッチング4x12
upstream ws_matching_4x12 {
server localhost:8085;
server localhost:8086 backup;
}
# 対戦(ペアIDの先頭がcからnまでの12個)
upstream ws_round_0b {
server localhost:8181;
server localhost:8182 backup;
}
# 対戦(ペアIDの先頭がcからnまでの12個)
upstream ws_round_cn {
server localhost:8183;
server localhost:8184 backup;
}
# 対戦(ペアIDの先頭がoからzまでの12個)
upstream ws_round_oz {
server localhost:8185;
server localhost:8186 backup;
}
server {
listen 80;
server_name game.example.com;
charset utf-8;
root /var/www/game/public;
# エラーページ
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
# websocket_paramsのインクルード
include /etc/nginx/websocket_params;
# マッチング4x4
location ~ ^/ws/matching/4/$ {
proxy_pass http://ws_matching_4x4;
}
# マッチング4x8
location ~ ^/ws/matching/8/$ {
proxy_pass http://ws_matching_4x8;
}
# マッチング4x12
location ~ ^/ws/matching/12/$ {
proxy_pass http://ws_matching_4x12;
}
# 対戦(ペアIDの先頭がcからnまでの12個)
location ~ ^/ws/round/[0-9a-b][0-9a-z]+?/$ {
proxy_pass http://ws_round_0b;
}
# 対戦(ペアIDの先頭がcからnまでの12個)
location ~ ^/ws/round/[c-n][0-9a-z]+?/$ {
proxy_pass http://ws_round_cn;
}
# 対戦(ペアIDの先頭がoからzまでの12個)
location ~ ^/ws/round/[o-z][0-9a-z]+?/$ {
proxy_pass http://ws_round_oz;
}
}
※全部localhostにしてポートを変更していますが、細分化すれば、上記設定で12台に切り分けられます。
※もちろん、もっと細かく分けることも可能です。
という具合で考えると、
ちょっと大げさに以下のようなイメージでインフラが考えられます。

このようにフロントのサーバの機能を利用することで、
pub/subを使わずにwebsocketを通じたメッセージのやり取りができます。
狙いとしては
「同一属性者を同じブロセスに閉じ込めることで、メモリ内の操作で処理を完結させる」
ということになります。
投稿日時:2014年11月25日 18:17
カテゴリー:
java,
node.js,
websocket
airアプリをStalingFrameworkで作っていた時、
StalingFrameworkに制御が移る瞬間(stage3Dに制御が移る瞬間でよいのかな?)に、
描画イベントが効かなくなるという問題があった。
簡単なコードは以下。
public class Main extends Sprite
{
/**
* starlingのエンジン
*/
private var _starling:starling.core.Starling;
/**
* コンストラクタ
*/
public function Main():void
{
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
// 基本画面領域の定義
var width:int = 640;
var height:int = 960;
// 基本領域
var base:Rectangle = new Rectangle(0, 0, width, height);
// フル領域
var full:Rectangle = new Rectangle(0, 0, stage.fullScreenWidth, stage.fullScreenHeight);
// 表示領域
var viewPort:Rectangle = starling.utils.RectangleUtil.fit(base, full);
// ※ここ以降に制御が移ったら、それ以前に定義しておいた描画イベントは効かなくなる
// starlingのエンジンを生成
_starling = new starling.core.Starling(Game, stage, viewPort);
_starling.stage.stageWidth = width;
_starling.stage.stageHeight = height;
_starling.simulateMultitouch = false;
_starling.addEventListener(starling.events.Event.ROOT_CREATED, function(e:*, game:Game):void
{
// ゲーム開始
_starling.start();
});
}
}
自分の場合、iosでスプラッシュ画面がすぐに終了してしまい、
Starlingの初期化と同時に音声やら画像を一気にロードしていた時間がごまかせなくなった結果、
「now loading」的な描画処理をEnterFrameで入れていたら、
それが動かなくなったというものでした。
投稿日時:2014年11月25日 17:08
カテゴリー:
air,
as3
airアプリをAppleStoreにサブミットしたところ、
AIRSDK15でビルドしたバイナリが、
アップローダでアップできなかった。
原因としては、AIRSDK15では、32bitバイナリしか作成できないためだそうだ。
AIRSDK16(βだけど)でビルドしたら、
ワーニングが出来たけど、アップできた。
ただし、ワーニング(注意書き?)の内容としては「2015年2月以降は64bitじゃないとダメよ」
みたいなものであった。
AIRSDK16では64bitバイナリが作成できたってことでよいのかな?
いまいちよくわからないが、AIRSDK16のリリースノートに書いてあるような。。
とりあえず、AIRSDK16の正式版が出てからでないと、
アップしても危険かも。
投稿日時:2014年11月25日 16:27
カテゴリー:
air,
as3
さて、本腰入れて。
今回の比較に当たり、大きな前提として、
pub/subはなし(つまり、メモリ内で処理を完結可能)
というのをあげておきます。
というのも、pub/subがあるときと、ないときでは、
結構実装が異なってしまうためです。
(※うまく抽象化できればいいのですが、node.js側は上手に継承を使うのが難しいので)
この前提のもと、
javaとnode.jsの大きな違いは、
java:マルチスレッド
node.js:シングルスレッド
ということであります。
この違いは、プログラムを書く上で、
「排他制御」が必要か、不要かということにつながります。
たとえば、対戦ゲームを作るとした場合、
ゲームには「マッチング」と「対戦中」で処理が大きく2つに分かれます。
マッチングは諸条件あるものの、基本的には来た順番にさばく手法がとられると思います。
このとき、javaでは必ず排他制御をかける必要があります。
それに対し、node.jsでは、シングルスレッドなので、排他制御をかける必要はありません。
ここが両者の最大の違いとなります。
※あくまでメモリ内で完結する場合です。(つまり1プロセス)
複数台を使う場合は、node.jsでも排他制御が必要となる場合があります。
投稿日時:2014年11月25日 14:23
カテゴリー:
java,
node.js,
websocket
websocketというと、チマタではnode.jsが流行っていますね。
しかし、javaもJSR356という規約の下、
各サーブレットコンテナで対応が完了しており、
個人的にはnode.jsと対をなす位までの能力があるかと思います。
javaでもnode.jsでもwebsocketを構築した筆者が、
数回にわたりお互いの特徴と実装の注意点などを書いていきます。
なお、バージョンは
【java】
jetty9.X(JSR356に対応した形)
【node.js】
v10.3X
となります。
投稿日時:2014年11月25日 13:37
カテゴリー:
java,
node.js,
websocket
さくらのVPSでwordpress入れて、今日からブログを作成していきます。
基本的には、IT系のネタをメモ代わりに残し、
閲覧してくれた人の助けになれば幸いです。
ネタ的には、
- php
- java
- mysql(mariadb)
- as3(air)
- c/c++
- python
あたりを書き留めておきたいかなと。
投稿日時:2014年11月25日 13:29
カテゴリー:
other