LoginSignup
3
2

More than 5 years have passed since last update.

GlassFishのクラスター+ELBで高可用性Webサービスを構築する

Last updated at Posted at 2014-12-20

予備知識

  • 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にマッピングします。

ELB_01.png

ヘルスチェック設定

URLはお使いのアプリに合わせて適切に設定して下さい。
ELB_02.png

セキュリティグループ設定

通常はHTTP(80)とHTTPS(443)で充分でしょう。
ELB_03.png

Add EC2 Instances & Add Tags

Add EC2 InstancesではGlassFishクラスタのノードとなるEC2インスタンスを追加しましょう。

Add Tagsは運用時に役に立つタグを設定しておくといいでしょう。

スティッキーセッションの設定

ELBを作成したら、もう1つやることが残っています。
同一セッション内のリクエストを常に同じノードに振るようにするために、スティッキーセッションの設定を行います。

ELBのStickinessのeditをクリックします。
ELB_04.png

Enable Application Generated Cookie Stickinessにチェックを入れます。
更にCookie NameJSESSIONIDと入力します。
ELB_05.png

以上で設定完了です。

他にも作業は残っていて、例えば独自ドメインをELBのDNSに向ける設定を行う必要がありますが、この記事ではここまでにします。

余談・本来はGlassFishがセッション管理をしてくれるはず

ここでELBに施したスティッキーセッションの設定は、あまり良い手法ではありません。
JSESSIONIDなどという、アプリケーションサーバの実装詳細に依存したパラメータ設定は柔軟性を落とします。
また同一セッションのリクエストが常に同一ノードに振られるため、セッションの寿命によって各ノードの負荷に差が出ることが予想されます。
各ノードの負荷が出来るだけ平準になるようにリクエストを振ってくれた方が、高負荷時の対策がしやすそうです。

実は本来、セッションの共有はGlassFishのクラスタ機能がまかなってくれるようで、それを使いたかったのですが、動作させることが出来なかった、という背景があります。

かなり古い記述ですが、以下のページにインメモリセッションレプリケーションの仕組みについて記述がありました。
http://otn.oracle.co.jp/technology/global/jp/sdn/java/series/glassfish/200807.html

上記のページを見ると、LBがどのノードにリクエストを振っても、GlassFishのクラスタの中で適切にセッションを維持してくれる仕組みが働くようです。
GlassFish 4でもこの仕組みを踏襲してくれていることを期待しますし、実際、それらしき設定項目があるのですが、何故か設定変更することが出来ません。

Web_Container_Availability.png

しかしこの機能が有効になれば、LB側の設定が最小限で済む上、GlassFishの各ノードの負荷がうまいこと分散されることが期待出来ます。
また耐障害性も上がります(今回の構成だと、あるノードが落ちたら、そこに置かれているセッション情報は失われる)。
引き続き検証していきます。

その他のメモ

ノードに先にGlassFishをインストールしておいたら、時間短縮になるのでは?

結果としてこれは、うまくいきませんでした。原因は調査していません。
ノードを作成してクラスにインスタンスを追加するまでは出来たが、インスタンス起動が出来ませんでした。
また、期待したほど時間短縮にもなりませんでした。

GlassFishクラスタを利用することの考察

利点と欠点

利点

  • ノードの管理が楽
    • ノードを簡単に増やす事が出来ます。これはこの上なく楽です。
    • ノードの環境変数やアプリは、DASで設定するだけで全ノードに自動で反映されます。これもものすごく楽です。

欠点

  • DASが単一故障点になり得る?

ノードとなるEC2インスタンスにElastic IPを振るべきか

結論は「振る必要なし」です。
ノードとなるEC2インスタンスが落ちたら、そのインスタンスは破棄し、新しいノードを作成して追加する運用が楽だと思います。
この運用だと、Elastic IPは不要です。

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2