予備知識
- DASとノードのOSの設定は極力合わせませしょう
- JDKのバージョンも合わせましょう
- OpenJDKは1.7系を使いましょう。8系だとGlassFish上でJSPが動作しないようです
ノードとなるGlassFishが載るOSを用意する
Amazon Linuxが既に起動している前提で手順を進めます。
ここでのポイントは、__GlassFishをインストールしない__ことです。
ポート
- 4848
- 28080
- 28181
OSの最新化
sudo yum -y update
OpenJDKのインストール
sudo yum -y install java-1.7.0-openjdk-devel
SSHの設定変更(rootログイン可、かつパスワード認証可に)
※この手順は、あまり望ましくないです。出来れば証明書によるSSHでクラスタ構築可能にしたい。
が、現時点ではこの方法でしか動作確認が取れていないので、この手順をメモしておきます。
sudo vi /etc/ssh/sshd_config
viで開いたsshd_config
の以下の設定を書き換えます。
PermitRootLogin yes
PasswordAuthentication yes
sshdを再起動。
sudo /etc/rc.d/init.d/sshd restart
rootユーザのパスワードを設定
rootユーザのパスワードが空ではSSHでログイン出来ないため、パスワードを設定。
(もしかするとSSHの設定を変更すれば空パスワードでもログイン出来るようになるかもしれないが、未検証)
sudo su -
passwd
任意のパスワードを設定して下さい。
動作確認
下記コマンドでrootユーザのパスワードを入力してログイン出来ればOK。
ssh root@<ホスト>
DAS(GlassFishのドメイン管理サーバ)を立てる
ここからはDASが載るサーバで作業します。ノードとなるサーバでは作業不要です。便利。
Amazon LinuxにGlassFishをインストールする
# ライブラリを最新に
sudo yum -y update
# JDKのインストール
sudo yum -y install java-1.7.0-openjdk-devel
# GlassFish-v4.1のインストール
sudo yum -y install wget
cd /tmp
wget -P /tmp http://dlc.sun.com.edgesuite.net/glassfish/4.1/release/glassfish-4.1-web.zip
unzip /tmp/glassfish-4.1-web.zip
sudo mv glassfish4/ /opt/
cd /opt
sudo mv glassfish4/ glassfish-4.1-web
- 現状ではopenjdk-1.7を利用します。1.8ではJSPが動きませんので(javacのパスが変わったため?)。
GlassFishの自動起動設定を追加
sudo touch /etc/init.d/glassfish
sudo chmod +x /etc/init.d/glassfish
sudo vi /etc/init.d/glassfish
開いたファイルの中を以下のように編集。
# !/bin/bash
#
# glassfish Startup script for the Apache HTTP Server
#
# chkconfig: - 85 15
# description: Startup script of Glassfish Application Server.
# processname: glassfish
#
export LANG=ja_JP.utf8
GLASSFISH_HOME=/opt/glassfish-4.1-web
case $1 in
start)
sh ${GLASSFISH_HOME}/bin/asadmin start-domain $2
;;
stop)
sh ${GLASSFISH_HOME}/bin/asadmin stop-domain $2
;;
restart)
sh ${GLASSFISH_HOME}/bin/asadmin restart-domain $2
;;
esac
exit 0
自動起動を登録。
sudo chkconfig --add glassfish
sudo chkconfig glassfish on
sudo service glassfish restart
GlassFishの管理コンソール設定を変更
リモートで操作可能になるように設定を変更します。
cd glassfish-4.1-web/bin/
./asadmin start-domain
./asadmin change-admin-password
ここで任意のパスワードを入力。
入力したパスワードは、後のコマンド発行を楽にするためにファイルに出力しておきます。
echo AS_ADMIN_PASSWORD=xxx >> pass.txt
リモート接続可能にするための最後のコマンド。
./asadmin -W pass.txt enable-secure-admin
クラスタを作成
./asadmin -W pass.txt create-cluster <クラスタ名>
ノードを作成
SSH接続する際のパスワードをパスワードファイルに設定しておきます。
echo AS_ADMIN_SSHPASSWORD=yyy >> pass.txt
ノードを作成
./asadmin -W pass.txt create-node-ssh --nodehost <nodehost> --install=true --sshuser root <ノード名>
クラスタにインスタンスを追加
./asadmin -W pass.txt create-instance --node <ノード名> --cluster <クラスタ名> <インスタンス名>
このコマンドはかなり時間がかかります。DASからノードにGlassFishのモジュールをコピーしてインストールするためです。
タイムアウトがしばしば発生し、下記のようなメッセージが表示されます。コマンドが失敗しているように見えます。
No response from Domain Admin Server after 600 seconds.
The command is either taking too long to complete or the server has failed.
Please see the server log files for command status.
Command create-instance failed.
本当に失敗しているかどうかは分かりません。
経験的には、次のクラスタの起動がうまく行けば「実はうまくいっていたんだな」と判断しています。
クラスタの起動
./asadmin -W pass.txt start-cluster cluster01
ELBの設定
ポートのマッピング
80を28080にマッピングします。
ヘルスチェック設定
セキュリティグループ設定
通常はHTTP(80)とHTTPS(443)で充分でしょう。
Add EC2 Instances & Add Tags
Add EC2 InstancesではGlassFishクラスタのノードとなるEC2インスタンスを追加しましょう。
Add Tagsは運用時に役に立つタグを設定しておくといいでしょう。
スティッキーセッションの設定
ELBを作成したら、もう1つやることが残っています。
同一セッション内のリクエストを常に同じノードに振るようにするために、スティッキーセッションの設定を行います。
Enable Application Generated Cookie Stickiness
にチェックを入れます。
更にCookie Name
にJSESSIONID
と入力します。
以上で設定完了です。
他にも作業は残っていて、例えば独自ドメインをELBのDNSに向ける設定を行う必要がありますが、この記事ではここまでにします。
余談・本来はGlassFishがセッション管理をしてくれるはず
ここでELBに施したスティッキーセッションの設定は、あまり良い手法ではありません。
JSESSIONID
などという、アプリケーションサーバの実装詳細に依存したパラメータ設定は柔軟性を落とします。
また同一セッションのリクエストが常に同一ノードに振られるため、セッションの寿命によって各ノードの負荷に差が出ることが予想されます。
各ノードの負荷が出来るだけ平準になるようにリクエストを振ってくれた方が、高負荷時の対策がしやすそうです。
実は本来、セッションの共有はGlassFishのクラスタ機能がまかなってくれるようで、それを使いたかったのですが、動作させることが出来なかった、という背景があります。
かなり古い記述ですが、以下のページにインメモリセッションレプリケーションの仕組みについて記述がありました。
http://otn.oracle.co.jp/technology/global/jp/sdn/java/series/glassfish/200807.html
上記のページを見ると、LBがどのノードにリクエストを振っても、GlassFishのクラスタの中で適切にセッションを維持してくれる仕組みが働くようです。
GlassFish 4でもこの仕組みを踏襲してくれていることを期待しますし、実際、それらしき設定項目があるのですが、何故か設定変更することが出来ません。
しかしこの機能が有効になれば、LB側の設定が最小限で済む上、GlassFishの各ノードの負荷がうまいこと分散されることが期待出来ます。
また耐障害性も上がります(今回の構成だと、あるノードが落ちたら、そこに置かれているセッション情報は失われる)。
引き続き検証していきます。
その他のメモ
ノードに先にGlassFishをインストールしておいたら、時間短縮になるのでは?
結果としてこれは、うまくいきませんでした。原因は調査していません。
ノードを作成してクラスにインスタンスを追加するまでは出来たが、インスタンス起動が出来ませんでした。
また、期待したほど時間短縮にもなりませんでした。
GlassFishクラスタを利用することの考察
利点と欠点
利点
- ノードの管理が楽
- ノードを簡単に増やす事が出来ます。これはこの上なく楽です。
- ノードの環境変数やアプリは、DASで設定するだけで全ノードに自動で反映されます。これもものすごく楽です。
欠点
- DASが単一故障点になり得る?
ノードとなるEC2インスタンスにElastic IPを振るべきか
結論は「振る必要なし」です。
ノードとなるEC2インスタンスが落ちたら、そのインスタンスは破棄し、新しいノードを作成して追加する運用が楽だと思います。
この運用だと、Elastic IPは不要です。