AWS Elastic Beanstalk を使う その12
StandardSessionクラスがSerializableインタフェースを持っているので、Base64エンコードして直列化した文字列をSimpleDBに書き込むような流れになっています。
オブジェクトの文字列化に使ったのはこれ。
ちゃんとテストしていませんがw。
http://www.source-code.biz/base64coder/java/
道半ば。。
package jp.cm.aws.tomcat.session; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import org.apache.catalina.Session; import org.apache.catalina.Store; import org.apache.catalina.session.StandardSession; import org.apache.catalina.session.StoreBase; import biz.source_code.base64Coder.Base64Coder; import com.amazonaws.auth.PropertiesCredentials; import com.amazonaws.services.simpledb.AmazonSimpleDB; import com.amazonaws.services.simpledb.AmazonSimpleDBClient; import com.amazonaws.services.simpledb.model.Attribute; import com.amazonaws.services.simpledb.model.DeleteAttributesRequest; import com.amazonaws.services.simpledb.model.GetAttributesRequest; import com.amazonaws.services.simpledb.model.GetAttributesResult; import com.amazonaws.services.simpledb.model.Item; import com.amazonaws.services.simpledb.model.PutAttributesRequest; import com.amazonaws.services.simpledb.model.ReplaceableAttribute; import com.amazonaws.services.simpledb.model.SelectRequest; public class SimpleDBStore extends StoreBase implements Store { private AmazonSimpleDB sdb = null; private String myDomain = "SessionPersistence"; private String mySession = "Session"; public SimpleDBStore() throws IOException { sdb = new AmazonSimpleDBClient(new PropertiesCredentials( SimpleDBStore.class .getResourceAsStream("AwsCredentials.properties"))); } @Override public int getSize() throws IOException { String selectExpression = "select * from `" + myDomain + "`"; SelectRequest selectRequest = new SelectRequest(selectExpression); int count = 0; for (Item item : sdb.select(selectRequest).getItems()) { System.out.println(" Item"); System.out.println(" Name: " + item.getName()); for (Attribute attribute : item.getAttributes()) { System.out.println(" Attribute"); System.out.println(" Name: " + attribute.getName()); System.out.println(" Value: " + attribute.getValue()); } count++; } return count; } @Override public String[] keys() throws IOException { String selectExpression = "select * from `" + myDomain + "`"; SelectRequest selectRequest = new SelectRequest(selectExpression); List<Item> items = sdb.select(selectRequest).getItems(); List<String> keyNames = new ArrayList<String>(); for (Item item : items) { keyNames.add(item.getName()); } return (String[]) keyNames.toArray(); } @Override public Session load(String id) throws ClassNotFoundException, IOException { System.out.println("load : " + id); GetAttributesResult result = sdb .getAttributes(new GetAttributesRequest().withDomainName( myDomain).withItemName(id)); List<Attribute> list = result.getAttributes(); StandardSession session = null; for (int i = 0; i < list.size(); i++) { Attribute attribute = list.get(i); if (attribute.getName().equals(mySession)) { String value = attribute.getValue(); session = (StandardSession) fromString(value); } } System.out.println(session.toString()); return session; } @Override public void remove(String id) throws IOException { System.out.println("remove : " + id); sdb.deleteAttributes(new DeleteAttributesRequest().withDomainName( myDomain).withItemName(id)); } @Override public void clear() throws IOException { System.out.println("clear"); } @Override public void save(Session session) throws IOException { System.out.println(session.toString()); System.out.println("save"); String id = session.getId(); sdb.putAttributes(new PutAttributesRequest() .withDomainName(myDomain) .withItemName(id) .withAttributes( new ReplaceableAttribute(mySession, toString((StandardSession) session), true))); System.out.println(toString((StandardSession) session)); } private Object fromString(String s) throws IOException, ClassNotFoundException { byte[] data = Base64Coder.decode(s); ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream( data)); Object o = ois.readObject(); ois.close(); return o; } private String toString(Serializable o) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos); oos.writeObject(o); oos.close(); return new String(Base64Coder.encode(baos.toByteArray())); } }
AWS Elastic Beanstalk を使う その6
Beanstalkでインスタンス立ち上げると、次に思うのがTomcatのバージョン上げたり、server.xml編集したりいろいろやりたい!ってはず!?
ということで、方法が無いか調べたらあっさり分かりました。
まず、普通にBeanstalkでEnvironmentを作ります。
次にEC2タブのKey Pairsで事前に鍵を用意します。keysample
.pemとかね。
Environmentのコンフィグ画面から先ほど作ったKey Pairを指定します。
これで、普通のEC2インスタンスとしてSSHでログインできるようになります。
こんな感じで入れましたよー。
__| __|_ ) Amazon Linux AMI _| ( / Beta ___|\___|___|
ちなみにログインIDは、ec2-user です。rootじゃ入れません。
root系コマンドはsudoでどうぞー。
sudo su -
ログインすれば普通のLinuxですからserver.xmlを修正するとかして、DataSourceの設定とか、セキュリティロールの設定なんかをすればいい。
これで念願のSession Clusteringが実現できるのでは!?と。
基本的にはスティッキーセッションロードバランシングで処理先を固定にしておいて、万が一インスタンスが落ちた際には、他のインスタンスでセッション内容を引き継ぐと。
MySQLをHttpSessionの永続化先にしておけば、オートスケール、ロードバランサー、フェイルオーバーに対応したお気楽クラウド生活が!!
各種設定とか必要なアプリのインストールが終わったらログアウトして、
オリジナルのAMIを作成します。Custom AMI ですね。
最後にBeanstalkのEnvironmentコンフィグ画面で先ほど作成したCustom AMI IDを指定しましょう。
最初っからオリジナルのAMIを使いたいって人もいると思うんですが、AWSとしてはAmazon AMIにはTomcat の再起動や、WARファイルの配備、ログの取得など裏で色々やっているので、Beanstalkで使うにはAmazon AMIからコピーしてほしいってさ。
Editing server.xml, logging in as root
https://forums.aws.amazon.com/thread.jspa?threadID=58723&tstart=0
JVM/Tomcat config questions
https://forums.aws.amazon.com/thread.jspa?threadID=58744&tstart=0
AWS Elastic Beanstalk を使う その8
Beanstalkでどうやったらセッションレプリケーションしようかって悩んで調べていたんですがカンタンなやり方が分かりました。Tomcatの基本を知らないオイラが馬鹿だったw。
rootで入ってserver.xmlを設定する必要なかったんですw。
配備するアプリケーション(後でwar化するやつ)にMETA-INFフォルダを作って、
context.xmlを記述すれば反映されることが分かりました。
Beanstalkがどうのこうのではなく、ただのTomcatに配備するアプリ側の設定だけでいけるんですね。
ということは、Beanstalkに配備するアプリの設定だけで、ファイルオーバー対応するためのセッションレプリケーション指定(JDBCStore)できるわけですね。
もー、Beanstalk最強じゃんw。
Tomcat 6 Session Persistence through JDBCStore
http://www.intelligrape.com/blog/2010/07/21/tomcat-6-session-persistence-through-jdbcstore/
Tomcatでフェイルオーバー
http://syo.cocolog-nifty.com/freely/2007/05/tomcat.html
Tomcat 5.5 で session persistence (using JDBCStore)
http://d.hatena.ne.jp/stdcall/20070102/1167688088
ActionScript API for AWS (Amazon Web Services)
出す出すと言ってだいぶ時間が経ってしまいましたが、、、
GitHubにアップしました。
ActionScript からカンタンにAWSへアクセスするためのAPI群です。
とりあえずswcが必要な方はこちらへ
[cmawslib.swc](https://github.com/satoshi7/ActionScript-API-for-AWS-Amazon-Web-Services-/blob/master/bin/cmawslib.swc)
-
- 操作できるAPI
Amazon Web Services Query API が提供しているものはほぼ全ての操作に対応しています。
-
-
- EC2 - Amazon Elastic Compute Cloud
-
-
-
- RDS - Amazon Relational Database Service
-
-
-
- SDB - Amazon SimpleDB
-
-
-
- SQS - Amazon Simple Queue Service
-
-
- 使い方
本コードは Adobe Flex Library Project で作っています。
ご使用の際には Adobe Flash Builder などでプロジェクトのインポートを行い、
アプリケーション側の設定画面からライブラリ追加をしてご利用ください。
-
- 開発の仕方
以下のように短いコードを書いて頂ければカンタンにAWSを操作できます。
-
-
- Amazon Elastic Compute Cloud
-
var ec2:EC2 = new EC2(); ec2.setAWSCredentials(AWSKey.key,AWSKey.sec); ec2.addEventListener(AWSEvent.RESULT,awsHandler); ec2.executeRequest(EC2.DESCRIVE_REGIONS);
var emr:EMR = new EMR(); emr.setAWSCredentials(AWSKey.key,AWSKey.sec); emr.addEventListener(AWSEvent.RESULT,awsHandler); emr.executeRequest(EMR.DESCRIBE_JOB_FLOWS);
-
-
- Amazon Relational Database Service
-
var rds:RDS = new RDS(); rds.setAWSCredentials(AWSKey.key,AWSKey.sec); rds.addEventListener(AWSEvent.RESULT,awsHandler); rds.executeRequest(RDS.DESCRIBE_DB_INSTANCES);
-
-
- Amazon Simple Notification Service
-
var sns:SNS = new SNS(); sns.setAWSCredentials(AWSKey.key,AWSKey.sec); sns.addEventListener(AWSEvent.RESULT,awsHandler); sns.executeRequest(SNS.LIST_TOPICS);
-
-
- Amazon SimpleDB
-
var sdb:SDB = new SDB(); sdb.setAWSCredentials(AWSKey.key,AWSKey.sec); sdb.addEventListener(AWSEvent.RESULT,awsHandler); sdb.executeRequest(SDB.LIST_DOMAINS);
-
-
- Amazon Simple Queue Service
-
var sqs:SQS = new SQS(); sqs.setAWSCredentials(AWSKey.key,AWSKey.sec); sqs.addEventListener(AWSEvent.RESULT,awsHandler); sqs.executeRequest(SQS.LIST_QUEUES);
-
-
- Amazon CloudWatch
-
var acw:ACW = new ACW(); acw.setAWSCredentials(AWSKey.key,AWSKey.sec); acw.addEventListener(AWSEvent.RESULT,awsHandler); acw.executeRequest(ACW.LIST_METRICS);
var iam:IAM = new IAM(); iam.setAWSCredentials(AWSKey.key,AWSKey.sec); iam.addEventListener(AWSEvent.RESULT,awsHandler); iam.executeRequest(IAM.LIST_ACCESS_KEYS);
-
-
- AWS Elastic Beanstalk
-
var ebt:EBT = new EBT(); ebt.setAWSCredentials(AWSKey.key,AWSKey.sec); ebt.addEventListener(AWSEvent.RESULT,awsHandler); ebt.executeRequest(EBT.DESCRIBE_APPLICATIONS);
-
-
- イベントハンドラの記述の仕方
-
public function awsHandler(event:AWSEvent):void{ var data:Object = event.data; //XML形式のテキストが取得されます。 ta.text += data.toString(); }
-
- 注意
本ライブラリを使うには、AWSと契約を行って頂き、発行される Access Key ID と Secret Access Key を使用します。
事前にご準備ください。
-
- コントリビュータ
[@sato_shi](http://twitter.com/sato_shi/) - Classmethod,Inc. http://classmethod.jp/(http://classmethod.jp/)]
ActionScript API for AWS (Amazon Web Services)
https://github.com/satoshi7/ActionScript-API-for-AWS-Amazon-Web-Services-
AWS Elastic Beanstalk を使う その4
Beanstalk の System.getProperties()で取得できるキーと値一覧
KEY : java.runtime.name VALUE : OpenJDK Runtime Environment KEY : AWS_ACCESS_KEY_ID VALUE : KEY : sun.boot.library.path VALUE : /usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0/jre/lib/i386 KEY : java.vm.version VALUE : 19.0-b06 KEY : shared.loader VALUE : KEY : java.vm.vendor VALUE : Sun Microsystems Inc. KEY : java.vendor.url VALUE : http://java.sun.com/ KEY : AWS_SECRET_KEY VALUE : KEY : path.separator VALUE : : KEY : tomcat.util.buf.StringCache.byte.enabled VALUE : true KEY : java.util.logging.config.file VALUE : /usr/share/tomcat6/conf/logging.properties KEY : java.vm.name VALUE : OpenJDK Client VM KEY : file.encoding.pkg VALUE : sun.io KEY : sun.java.launcher VALUE : SUN_STANDARD KEY : user.country VALUE : US KEY : sun.os.patch.level VALUE : unknown KEY : java.vm.specification.name VALUE : Java Virtual Machine Specification KEY : user.dir VALUE : /usr/share/tomcat6 KEY : java.runtime.version VALUE : 1.6.0_20-b20 KEY : java.awt.graphicsenv VALUE : sun.awt.X11GraphicsEnvironment KEY : java.endorsed.dirs VALUE : KEY : os.arch VALUE : i386 KEY : java.io.tmpdir VALUE : /var/cache/tomcat6/temp KEY : line.separator VALUE : KEY : java.vm.specification.vendor VALUE : Sun Microsystems Inc. KEY : java.naming.factory.url.pkgs VALUE : org.apache.naming KEY : java.util.logging.manager VALUE : org.apache.juli.ClassLoaderLogManager KEY : os.name VALUE : Linux KEY : sun.jnu.encoding VALUE : UTF-8 KEY : java.library.path VALUE : /usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0/jre/lib/i386/client:/usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0/jre/lib/i386:/usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0/jre/../lib/i386:/usr/java/packages/lib/i386:/lib:/usr/lib KEY : java.specification.name VALUE : Java Platform API Specification KEY : java.class.version VALUE : 50.0 KEY : sun.management.compiler VALUE : HotSpot Client Compiler KEY : os.version VALUE : 2.6.34.7-56.40.amzn1.i686 KEY : user.home VALUE : /usr/share/tomcat6 KEY : catalina.useNaming VALUE : true KEY : user.timezone VALUE : Universal KEY : java.awt.printerjob VALUE : sun.print.PSPrinterJob KEY : file.encoding VALUE : UTF-8 KEY : java.specification.version VALUE : 1.6 KEY : catalina.home VALUE : /usr/share/tomcat6 KEY : JDBC_CONNECTION_STRING VALUE : KEY : java.class.path VALUE : :/usr/share/tomcat6/bin/bootstrap.jar:/usr/share/tomcat6/bin/tomcat-juli.jar:/usr/share/java/commons-daemon.jar KEY : user.name VALUE : tomcat KEY : java.naming.factory.initial VALUE : org.apache.naming.java.javaURLContextFactory KEY : package.definition VALUE : sun.,java.,org.apache.catalina.,org.apache.coyote.,org.apache.tomcat.,org.apache.jasper. KEY : java.vm.specification.version VALUE : 1.0 KEY : java.home VALUE : /usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0/jre KEY : sun.arch.data.model VALUE : 32 KEY : user.language VALUE : en KEY : java.specification.vendor VALUE : Sun Microsystems Inc. KEY : java.vm.info VALUE : mixed mode KEY : java.version VALUE : 1.6.0_20 KEY : java.ext.dirs VALUE : /usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0/jre/lib/ext:/usr/java/packages/lib/ext KEY : sun.boot.class.path VALUE : /usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0/jre/lib/resources.jar:/usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0/jre/lib/rt.jar:/usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0/jre/lib/sunrsasign.jar:/usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0/jre/lib/jsse.jar:/usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0/jre/lib/jce.jar:/usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0/jre/lib/charsets.jar:/usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0/jre/lib/netx.jar:/usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0/jre/lib/plugin.jar:/usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0/jre/lib/rhino.jar:/usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0/jre/lib/modules/jdk.boot.jar:/usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0/jre/classes KEY : server.loader VALUE : KEY : java.vendor VALUE : Sun Microsystems Inc. KEY : catalina.base VALUE : /usr/share/tomcat6 KEY : file.separator VALUE : / KEY : java.vendor.url.bug VALUE : http://java.sun.com/cgi-bin/bugreport.cgi KEY : common.loader VALUE : ${catalina.base}/lib,${catalina.base}/lib/*.jar,${catalina.home}/lib,${catalina.home}/lib/*.jar KEY : sun.io.unicode.encoding VALUE : UnicodeLittle KEY : sun.cpu.endian VALUE : little KEY : PARAM5 VALUE : KEY : package.access VALUE : sun.,org.apache.catalina.,org.apache.coyote.,org.apache.tomcat.,org.apache.jasper.,sun.beans. KEY : PARAM4 VALUE : KEY : PARAM3 VALUE : KEY : PARAM2 VALUE : KEY : PARAM1 VALUE : KEY : sun.cpu.isalist VALUE :
AWS Elastic Beanstalk を使う その5
Ruby on Rails を Beanstalk で動かしてみましょう。
まずはじめにgemで環境を整えます。
>gem update >gem update --system >gem install rails --version '<3' >gem install warbler >gem install jruby-openssl >gem install rake >gem install activerecord-jdbcmysql-adapter >gem install jruby >gem install jruby-rack
railsをローカルで動かしてみましょう。
>rails -v Rails 2.3.10 >ruby -v ruby 1.8.7 >rails railssample >cd railssample >ruby script/generate scaffold person name:string age:integer >rake db:migrate >ruby script/server
ブラウザでRailsのデフォ画面を表示します。
次にrailsからwarファイルを吐き出すwarblerの手続きです。これいいね。
さっそく
>warble config >warble war
で完成するはずですが、コケる。。。。只今調査中。。
gemsからのRailsインストール †
http://takeoba.com/index.php?gems%A4%AB%A4%E9%A4%CERails%A5%A4%A5%F3%A5%B9%A5%C8%A1%BC%A5%EB
Warblerでwarファイルを作る
http://rubyist.g.hatena.ne.jp/muscovyduck/20090205/p1
JRuby on Rails on Amazon Elastic Beanstalk
http://blog.headius.com/2011/01/jruby-on-rails-on-amazon-elastic.html