2014年5月22日

ElastiCache で tomcat の session を管理する

以前、DynamoDB で tomcat の session を管理するというメモを書きましたが、今回は ElastiCache で管理してみます。
使うのは memcached-session-manager です。

Setup はこちらの wiki に従います。

まず、$CATALINA_HOME/lib/ に以下のライブラリを格納します。
memcached-session-manager-${version}.jar
memcached-session-manager-tc7-${version}.jar
AmazonElastiCacheClusterClient-no-version.jar

次に WEB-INF/lib/ に kryo-serializer のライブラリを格納します。
こちらは maven で pom.xml に含めておくことで、war ファイル作成時に自動的に導入されます。
<dependency>
    <groupId>de.javakaffee.msm</groupId>
    <artifactId>msm-kryo-serializer</artifactId>
    <version>1.8.1</version>
    <scope>runtime</scope>
</dependency>


META-INF/context.xml を設定します。
ElastiCache の設定の仕方はこちらにあります。
memcachedNodes に ElastiCache の Configuration Endpoint を設定すればOKです。
今回はこのように sticky、copyCollectionsForSerialization を false にしてみました。
<Context>
  ...
  <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
    memcachedNodes="session.xxxx.cfg.use1.cache.amazonaws.com:11211"
    requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
    transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"
    sessionBackupAsync="false"
    sticky="false"
    copyCollectionsForSerialization="false"
  />
</Context>

"It should work with non sticky sessions as well but has not yet been tested" とありましたが ELB 配下に複数配置して、ELB の Sticky を無効にした場合でも、振り分けられたインスタンスに関係なく値を取ることができました。
試してはいませんが、Auto Scaling などでインスタンスが停止した場合でも、ほかのインスタンスでセッションを引き継げるかもしれないですね!

もう少しドキュメントやソースを確認して DynamoDB Session の場合と比較してみたいです。

2014年5月11日

user data でインストール

EC2 起動時に指定する user data では shell script を実行することが出来ます。
参考:ユーザーデータとシェルスクリプト http://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/user-data.html#d0e29929

起動してから ssh でつないで、sudo yum install ... ということをあらかじめ仕込んでおくことが出来ます。

chef をインストールするため、以下を user data に設定してみます。
#!/bin/bash
curl -L https://www.opscode.com/chef/install.sh | sudo bash

起動後、インストールを確認してみます。
$ chef-client -version
-bash: chef-client: command not found
無事にインストール・・・されていません。

/var/log/cloud-init.log を確認してみたところ、実行に失敗していました。
May 11 13:39:17 cloud-init[1178]: util.py[DEBUG]: Failed running /var/lib/cloud/instance/scripts/part-001 [1]
Traceback (most recent call last):
  File "/usr/lib/python2.6/site-packages/cloudinit/util.py", line 637, in runparts
    subp([exe_path], capture=False, shell=True)
  File "/usr/lib/python2.6/site-packages/cloudinit/util.py", line 1528, in subp
    cmd=args)
ProcessExecutionError: Unexpected error while running command.
Command: ['/var/lib/cloud/instance/scripts/part-001']
Exit code: 1
Reason: -
Stdout: ''
Stderr: ''
May 11 13:39:17 cloud-init[1178]: cc_scripts_user.py[WARNING]: Failed to run module scripts-user (scripts in /var/lib/cloud/instance/scripts)

ところが、このスクリプトをそのまま実行するとうまくいきます。
$ sudo cat /var/lib/cloud/instance/scripts/part-001
#!/bin/bash
curl -L https://www.opscode.com/chef/install.sh | sudo bash
$
$ sudo /var/lib/cloud/instance/scripts/part-001
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 15934  100 15934    0     0  15986      0 --:--:-- --:--:-- --:--:-- 15981
Downloading Chef  for el...
downloading https://www.opscode.com/chef/metadata?v=&prerelease=false&nightlies=false&p=el&pv=6&m=x86_64
  to file /tmp/install.sh.1367/metadata.txt
trying wget...
url     https://opscode-omnibus-packages.s3.amazonaws.com/el/6/x86_64/chef-11.12.4-1.el6.x86_64.rpm
md5     959acd5df77c25f4f69d1f786f3c7360
sha256  d4eacc6b16c448a628367e7201922a4c58997f68808c5f698676e8a5eaf169b5
downloaded metadata file looks valid...
downloading https://opscode-omnibus-packages.s3.amazonaws.com/el/6/x86_64/chef-11.12.4-1.el6.x86_64.rpm
  to file /tmp/install.sh.1367/chef-11.12.4-1.el6.x86_64.rpm
trying wget...
Comparing checksum with sha256sum...
Installing Chef
installing with rpm...
warning: /tmp/install.sh.1367/chef-11.12.4-1.el6.x86_64.rpm: Header V4 DSA/SHA1 Signature, key ID 83ef826a: NOKEY
Preparing...                          ################################# [100%]
Updating / installing...
   1:chef-11.12.4-1.el6               ################################# [100%]
Thank you for installing Chef!
$ chef-client -version
Chef: 11.12.4
$


原因は以下の設定によるものでした。デフォルトでは、ssh 経由でないと sudo を実行できないのですね。こんな設定があるとは知りませんでした。。。
# Disable "ssh hostname sudo <cmd>", because it will show the password in clear.
#         You have to run "ssh -t hostname sudo <cmd>".
#
Defaults    requiretty
こちらをコメントアウトすることで、元のスクリプトは実行できるのですが、user script を実行するのは root なので、sudo を外して解決しました。

#!/bin/bash
yum update -y
curl -L https://www.getchef.com/chef/install.sh | bash


user data の実行ユーザはこちらの shell script を user data から実行して確認しました。
#!/bin/bash
whoami > /tmp/who

root でした!
$ cat /tmp/who
root


作りこめば設定ファイルを書き換えたり、デプロイとかできそうですね!
もっともそれをやるための chef のインストールで躓いたわけですが!