Amazon ElasticBeanstalkインスタンスをNewRelicでモニタリングする
NewRelicのServersデータ収集用のデーモンをインストールします。
プログラミング言語とか関係なく「.ebextensions」に設定ファイルを置くだけ。
Node.jsでもJavaでも同じ設定ファイルが使えます。
configファイルを作成
設定ファイルの書き方とか置き方とかは前回と同様です。
「.ebextensions」配下にインストール用の「newrelic.config」を配置します。
Install and start newrelic daemon on Amazon ElasticBeanstalk
あとはデータが収集されるので管理画面から確認します。
参考:Installation: RedHat and CentOS - New Relic Documentation
Node.js on ElasticBeanstalkインスタンス上にキャッシュ用のRedisを設置する
前回に続きBeanstalkネタですがBeanstalkでは構成管理ツールのような起動時に環境の初期化を行う機能が備わっています。
EC2 インスタンス上のソフトウェアのカスタマイズ - AWS Elastic Beanstalk
Node.jsのアプリケーションをホスティングするだけでなくRedisをインストールしてみました。
サンプルアプリケーションの入手
こちらからダウンロードします。展開すると以下の様な構成になっているので、
nodejs-sample/
├─ app.js
├─ index.html
├─ package.json
└─ .ebextensions/
└─ logging.config
configファイルを作成
「.ebextensions」配下にRedisインストール用の「redis.config」を配置します。
Install Redis on Elastic Beanstalk
設定はインスタンスタイプなど合わせて変更します。
アプリケーションの配備
コマンドラインツールもありますがそのままzip圧縮して配備することも出来ます。
Windowsの場合はフォルダを選択して圧縮するとapp.jsが見つからずに起動に失敗が
してしまうのでapp.jsと同じ階層のファイルを全選択して圧縮します。
失敗した場合は「Logs」から「Snapshot Logs」を確認します。
Tomcat on ElasticBeanstalkへCloudWatchカスタムメトリクスを簡単に追加する
今までEC2でゴリゴリ作っていたのですが最近ElasticBeanstalkの便利さに気付き始めました。
初期の頃に少しだけ触って初心者向けの機能だと今まで侮っていたのですがEclipseのプラグインも発達してサクサク開発できるので楽しいです。
ElasticBeanstalkでJava Webアプリケーションを構築する場合はTomcatを使用する事になりますが、デフォルトではCloudWatchに正常/異常のチェックしかできません。 EC2のメトリクスではメモリ使用量が見れないしカスタムメトリクスって面倒くさいという方に以下の設定がオススメです。
ManagementConsoleからアプリケーションの設定で"JVM command line options"が設定できるので以下の文字列を設定します。
-Dcom.amazonaws.sdk.enableDefaultMetrics =metricNameSpace=MyBeanstalkApp, includePerHostMetrics, cloudwatchRegion=ap-northeast-1
metricNameSpaceとcloudwatchRegionは必要に応じて変更してください。
しばらく待つとCloudWatchの"Custom Metrics"にデータが収集されファイルディスクリプタ/メモリ使用量/スレッド数などが観測できるようになります。
細かい設定などは以下の記事などを参考にしてください。
Metric Configuration in AWS SDK for Java - AWS Developer Blog - Java
ImportError: No module named _ssl
GoogleAppEngineのローカルデバッグ環境でDropboxのSDKを使用した際に以下のエラーが発生した
ERROR 2013-11-02 07:21:59,539 cgi.py:121] Traceback (most recent call last): (中略) File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ssl.py", line 60, in <module> import _ssl # if we can't import it, let the error propagate File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/tools/devappserver2/python/sandbox.py", line 867, in load_module raise ImportError('No module named %s' % fullname) ImportError: No module named _ssl
「_ssl」というモジュールがないのが原因のようだがデフォルトではモジュール一覧に含まれていないようなので、 エラーメッセージに書かれている「sandbox.py」を修正する
$ sudo vi /Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/tools/devappserver2/python/sandbox.py
「_WHITE_LIST_C_MODULES」に「_ssl」を追加するだけで大丈夫でした。
変更前(754行目辺り)
_WHITE_LIST_C_MODULES = [ 'array', '_ast', 'binascii', (省略)
変更後
_WHITE_LIST_C_MODULES = [ '_ssl', 'array', '_ast', 'binascii', (省略)
AppEngineのランチャーから再起動すると問題なくDropboxのSDKが使えるようになりました。
Windowsの開発環境でも同様の現象が確認できましたが同じ手順で解決。
デプロイするときは「app.yml」に「ssl」を追加します。
libraries: - name: ssl version: "latest"
Chromeの「Secure Shell」を使用してAmazonEC2に接続する
Secure ShellはChromeからSSHするアプリ。
Windowsの開発環境では普段TeraTermを使用しているのですが、
接続先も保存できて便利そうなので試しに使ってみました。
公開鍵を作成
EC2に接続する際に使用する秘密鍵から公開鍵を生成します。
>ssh-keygen -y -f keyname.pem > keyname.pub
秘密鍵の名前を変更
Secure Shellに鍵を登録する際は「xxxxx」「xxxxx.pub」という名前で
セットにしないと正しく登録されないので名前を変更します。
>cp keyname.pem keyname
Secure Shellで接続
「Import...」から上で作成した「keyname」「keyname.pub」を選択し
「Identity」に「keyname」が表示されればOK。SSH接続します。
DynamoDB Localをaws-java-sdkから操作
ダウンロードと起動
Additional Tools and Libraries For Amazon DynamoDB - Amazon DynamoDB
ここまでは公式ドキュメントに載ってる通り。
$ java –Djava.library.path=. -jar DynamoDBLocal.jar
aws-java-sdkから呼び出す
基本的にエンドポイントを"http://localhost:8000"にするだけ。
アクセスキーとリージョンはDBファイル名に使われるので好きな名前で。
以下で動かすと"AccessKey_us-east-1.db"という名前のファイルが作成された
public static void main(String[] args) { String accessKey = "AccessKey"; String secretAccessKey = "SecretKey"; AWSCredentials cre = new BasicAWSCredentials(accessKey, secretAccessKey); AmazonDynamoDBClient client = new AmazonDynamoDBClient(cre); client.setEndpoint("http://localhost:8000"); }
動作確認
String tableName = "DynamoTest"; // テーブル一覧 System.out.println(client.listTables()); // テーブル作成 List<KeySchemaElement> keySchema = new ArrayList<KeySchemaElement>(); keySchema.add(new KeySchemaElement().withAttributeName("HogeId").withKeyType(KeyType.HASH)); AttributeDefinition attrDef = new AttributeDefinition().withAttributeName("HogeId").withAttributeType(ScalarAttributeType.S); ProvisionedThroughput pt = new ProvisionedThroughput().withReadCapacityUnits(10L).withWriteCapacityUnits(5L); System.out.println(client.createTable(new CreateTableRequest(tableName, keySchema).withAttributeDefinitions(attrDef).withProvisionedThroughput(pt))); // アイテム追加 Map<String, AttributeValue> item = new HashMap<String, AttributeValue>(); item.put("HogeId", new AttributeValue("AAAA")); item.put("foo", new AttributeValue("valueA")); item.put("bar", new AttributeValue().withSS(Arrays.asList("valueB", "valueC"))); System.out.println(client.putItem(new PutItemRequest(tableName, item))); // アイテム取得 Map<String, AttributeValue> key = new HashMap<String, AttributeValue>(); key.put("HogeId", new AttributeValue("AAAA")); System.out.println(client.getItem(new GetItemRequest(tableName, key))); // アイテム更新 Map<String, AttributeValueUpdate> attributes = new HashMap<String, AttributeValueUpdate>(); attributes.put("bar", new AttributeValueUpdate(new AttributeValue().withS("valueD"), AttributeAction.PUT)); System.out.println(client.updateItem(new UpdateItemRequest(tableName, key, attributes))); // スキャン System.out.println(client.scan(new ScanRequest(tableName))); // アイテム削除 System.out.println(client.deleteItem(new DeleteItemRequest(tableName, key))); // テーブル削除 System.out.println(client.deleteTable(new DeleteTableRequest(tableName)));
実行結果
{TableNames: [],} {TableDescription: {AttributeDefinitions: [{AttributeName: HogeId,AttributeType: S}],TableName: DynamoTest,KeySchema: [{AttributeName: HogeId,KeyType: HASH}],TableStatus: ACTIVE,CreationDateTime: Fri Sep 13 14:12:03 JST 2013,ProvisionedThroughput: {NumberOfDecreasesToday: 0,ReadCapacityUnits: 10,WriteCapacityUnits: 5},TableSizeBytes: 0,ItemCount: 0,}} {} {Item: {HogeId={S: AAAA,}, foo={S: valueA,}, bar={SS: [valueB, valueC],}},} {} {Items: [{HogeId={S: AAAA,}, foo={S: valueA,}, bar={S: valueD,}}],Count: 1,ScannedCount: 1,} {} {TableDescription: {AttributeDefinitions: [{AttributeName: HogeId,AttributeType: S}],TableName: DynamoTest,KeySchema: [{AttributeName: HogeId,KeyType: HASH}],TableStatus: ACTIVE,CreationDateTime: Fri Sep 13 14:12:03 JST 2013,ProvisionedThroughput: {NumberOfDecreasesToday: 0,ReadCapacityUnits: 10,WriteCapacityUnits: 5},TableSizeBytes: 0,ItemCount: 0,}}
Amazon Elastic Transcorderメモ
今のところ使う予定は無いのですが試しに使って見ました。
思ったより変換速度が早くかなり良いサービスだと思います。
ジョブの設定が少しわかりづらかったので使い方をメモ。
パイプライン作成
S3にテスト用のバケットを1つ作成してInput及びOutputに同じバケットを設定しました。
ここは特に難しくないため割愛します。
ジョブ作成
出力の設定が複数あって分かりづらかったのでいろいろ試行錯誤しました。
以下に設定項目と設定例を示します。
設定名 | 設定例 | 説明 |
---|---|---|
Pipeline | pipeline-test | 作成したパイプライン名 |
Input Key | input/test.m4v | 変換対象のファイル。バケット名を除くパスを設定 |
Output Key Prefix | output/test- | すべての出力ファイルの接頭辞。"/"が必須 |
存在しないファイルを指定するなど設定を誤ると実行時にエラーとなります。
ジョブがエラーで終了するのですが原因を確認する方法がないようなので注意です。
設定名 | 設定例 | 説明 |
---|---|---|
Preset | System preset : Web | 変換後の出力形式を選択。Presetから選択。 |
Output Key | video/test.mp4 | 変換後の出力ファイルのキー。"/"も使用可 |
Create Thumbnails | Yes | サムネイルを出力するか(Yes or No) |
Thumbnail Filename Pattern | thumb/web-{count} | サムネイル出力ファイルのキー。"/"も使用可 |
出力先のフォルダ構成
上の設定例でジョブを実行した場合には以下の出力となります。
bucket/input
test.mp4
bucket/output/test-video
test.mp4
bucket/output/test-thumb
web-00001.png
bucket/output/test-thumb
web-00002.png
bucket/output/test-thumb
web-00003.png
bucket/output/test-thumb
web-00004.png
Watermark機能
動画にJPEGまたはPNG画像を被せる機能があるので試してみました。
使い方は簡単で上記の設定のあとWatermarkを有効にして同じバケット内にある
Watermark用の画像を選択するだけです。(バケット名は含めない)
設定名 | 設定例 |
---|---|
Input Key for Preset Watermark Id BottomRight | watermark/test.png |
大きめの画像を指定してみたのですがかなり小さめに出ました。
サイズの指定は出来ないみたいです。