Alexaアプリ開発:Lambdaからネットワークにアクセスできない!?

Amazon Echoを購入したので自分でちょっとしたAlexaアプリを作って遊び始めました。Alexaアプリではバックエンド側にAmazon Lambda上でNode.jsのコードを作成しています。
Lambda上からネットアクセス(http get)を使用としたのですが上手く動作しません。実行時のエラーなどは出ないのですが、ネットワークアクセス部分の出力がログに記録されません。

色々試しているうちに、ネットワークへのアクセス部分のコードの直後にthis.emit(’tell…’)を実施するのではなく、ある程度の時間を待ってからthis.emitを実施することによってログにネットワークアクセスの結果が書き込まれるようになりました。
個人的な理解ですが、AlexaからのTriggerで実行されるLambda関数自体がCallbackでその中にネットワークアクセスのコードがResponse処理のCallbackを設定しているため、this.emit()がAlexaから起動されたCallback自体を終了してしまい、ネットワークアクセス部分の終了前にLambda関数全体が終了してしまうだと思います。
ネットワークアクセスの結果をチェックするループにいれて結果をみてからthis.emit()の内容を変化させるのが好ましいロジックかなぁと思います。

 

コード例1:

 

コード例2:

 

S3のRegion指定

EC2のオレゴン移転に伴って、修正が必要な点が判明しました。
サーバとしてはまあ良好に動作しているのですがAWSのUsage情報を見ているとRegion間のデータ転送の値が大きくなっています。
思い出しました。
EC2のデイリーのバックアップをS3にアップロードしているのですが、このツール内でS3のRegionをTokyoに設定しています。したがって、Oregonのサーバのバックアップが毎日東京のS3バケットにアップロードされていたわけです。
グローバル企業であればサイトのバックアップを海外で保存するのは重要なコンセプトですが、個人の利用、しかもRegion間のデータ転送は有料ですのでできる限り避けるべきでしょう。

以前もどこかで記録したような気がしますが、ツールで修正が必要だったのは2箇所。s3のインスタンス作成時のEndpointの設定とBucket作成時のRegion設定となります。

s3のs3インスタンスの作成例:

Bucketの作成例:

 

カテゴリー: AWS

オレゴンサイトの弊害

基本的に特に問題もなく、オレゴンでのサーバが起動していますが、一点予想外の現象を発見。
Bingのオープニング画像を自動取得しているのですが、サイトがオレゴンに移ったため、オープンニング仕様がUS Versionになってしまいました。おそらく、基本的にアクセス元のIPアドレスを元に地域Versionを決定しているのでしょう。
サーバではcurlを使ってアクセスしているのですが、何かURLなどでサイト側に日本Versoinを戻すようにできないか考えています。
PCとかでアクセスしたソースをサイトに上げるような方法もあるかもしれません。自動化したいですが…

カテゴリー: AWS

オレゴンからこんにちは

AWSの無料利用期間があと一月、さらに現在のMicroインスタンスにWordpress、 Tomcat、MySQLを動かしている状況ではプロセスが落ちる落ちる。
もうこの状態での運用はきついのでMicro からSmallインスタンスへのアップグレードを行いました。
今後は有料になりますので、一番コストの安いオレゴンリージョンでのEC2になります。
以前も記事にしたように、AMIをオレゴンにコピーしてそちらでInstanceを実行になります。
最初にReserved Instanceの購入を実施します。この前払い料金は通常の月締めの請求ではなく、購入した瞬間に課金処理されました。
また、Reserved Instanceを購入しても、特にReserved Instanceを起動する手順はありません。説明を良く読むとインスタンスの起動自体はOnDemandやSpotと同じ手順でインスタンスを起動します。起動した後の課金に関して、自動的にReserved Instanceの条件が適応されるようです。
Reserved Instanceの購入時にはAvailability Zoneも決まるみたいですので、実際のInstanceを起動するときにはここにも気をつけないといけないかもしれません。

インスタンスを起動したあとはSecurity Groupの設定をこれまでと同様にすると同じ条件でのアクセスができます。IPアドレスでアクセスを確認してOKであればS3でURLとIPアドレスのマッピングを変更すれば新しいサーバにアクセスが開始されます。WebサイトやBlogなどの設定でIPアドレスを直接使っている場合などは変更する必要があります。(私の場合は気がつきませんでしたが一箇所ありました。)

smallインスタンスはmicroに比較してメモリが豊富なのでプロセスが落ちるようなことはありませんが、処理が速くなることはありませんでした。MySQLに重いsqlをかけるようなアクセスはmicro同様に遅いです。Wordpressで複数の画像ファイルをアップロードするような際には動作が止まってしまうようなこともありましたが、このような現象もなくなりました。速くはありませんが、安定した…というところでしょうか。

 

カテゴリー: AWS

クラウドドライブとファイルのバックアップ

AWSのS3はEC2の日々のデータのバックアップとStaticなWebサーバとして使用しています。一方でAmazonやGoogleのCloud DriveはPCのファイルの共有性を高めると同時にファイルのバックアップもかねて使用しています。
しかし、最近気がついたのですが、Cloud Driveの利便性はまったくその通りですし、PCのクラッシュなどを考えればCloud Driveはバックアップ用の機能があるのはその通りです。
しかし、Cloud Driveのファイルは色々な方法でアクセスしますので誤って削除してしまったり、Cloud Driveの同期機能のバグなどでファイルが消えてしまうリスクはなくなりません。
結局のところ、安全を期すのであればファイルのバックアップはCloud Driveとは別のロケーションに実施する必要があると思います。
その意味でCloud Driveではなく、S3そのものは基本的なバックアップの方法かなとは思います。とはいえ、たとえば、写真のオリジナルのように日々変更されないデータの保存であれば、DVDなどでも結局問題ないかなと思っています。S3の使用領域もコストがかかりますからね。

メールサーバ始動 (復刻ページ)

以前のSerendipityブログの記事で比較的アクセスの多いものをWordpressに移行しています。

最近ちょっとご無沙汰でしたが、メールサーバでメールの送受信可能になりました。

AWSの起動時からsendmailが動作していて、メールの送信はできましたが
受信はできませんでした。
もちろんメールサーバへのルーティングができないので当然ですが、Route53で
メールのドメインも設定できるようになったので挑戦してみました。

まずはメールのルーティングのためにRoute53にMXレコードの追加

nantoka7.com MX 10 54.248.89.83

といった感じでMXレコードとしてドメインとアドレスのマッピングを設定。
ちなみにnslookupでMXレコードの検索も可能。

[root@ip-10-162-38-78 ~]# nslookup -type=mx nantoka7.com
Server: 172.16.0.23
Address: 172.16.0.23#53

Non-authoritative answer:
nantoka7.com mail exchanger = 10 54.248.89.83.

Authoritative answers can be found from:

他のサイトでチェックするとMXレコードはIPアドレスを設定しているのではなく、mail.xxxx.com
のようなドメイン名で設定している例が多いのでそのうち直しましょう。

さらにEC2のSecurity Groupでポート25を開けます。
ちょっと怖いですが、httpと同様に全てのIPアドレスに対してオープンしました。

さらに、sendmailの設定ですが、まず以下のファイルを編集します。

/etc/mail/local-host-name
にメールのドメインを設定します。
nantoka7.com
これでxxxx@nantoka7.comのメールアドレスを受け付けるようになります。

最後に以下のファイルを編集します。
/etc/mail/sendmail.cf

以下の行をコメントに変更します。
O DaemonPortOptions=Port=smtp,Addr=127.0.0.1, Name=MTA

そしてsendmailの再起動
/etc/init.d/sendmail restart

netstatで再起動前後のポート25の状態を確認すると、変更前はlocalhostに対してのみ
ポート25(smtp)がオープンしていますが、変更後には全てのIPアドレスに対してポートが
開かれます。

以上でEC2上のsendmailでメールの送受信が可能になりました。

いつものことですが、動いてしまえば簡単ですね。

AWS APIによるS3オブジェクトのパーミッション変更(復刻ページ)

以前のSerendipityの記事で比較的アクセスの多いものをWordpressに移行しています。

毎日気象庁のサイトから前日の気温を収集するプログラムをcurlで作成し、サーバの
cronで毎朝自動起動してMysqlに格納するプログラムもとりあえず安定動作の模様。

そこでこのデータの取得も確認も兼ねて毎日自動でデータの羅列をhtmlで作成することにした。
本当はこのあたりはツールを使って美しくフォーマットすべきなのだが、とりあえず、シンプルなhtmlの雛形にsqlの出力を改行だけを入れて表示する方法。
サーバローカル内ではつくったファイルを単に毎日上書きするだけなので特に問題はない。
さらにこのhtmlファイルをS3にもアップロードしてアクセス可能にしようと考えた。

今までの転送ツールを使って事前にWeb Accessを許容したBucketにファイルを転送。
1回アクセス設定をしたファイルに上書きするので特に問題はないだろうと思っていたら、ファイルが上書きされると、PermissionはOwnerのみのデフォルトに戻ってしまうことが判明。
ファイルをアップロードするたびに明示的にパーミッションを設定しなければならない…

これもあれこれ調べているうちにAPIを使用して以下のようなコードで変更できることを
確認。

AccessControlList acl = s3.getObjectAcl(bucketName, key);
acl.grantPermission(GroupGrantee.AllUsers, Permission.Read);
s3.setObjectAcl(bucketName, key, acl);

keyはBucket上に存在するファイルの名前と同義です。
定期的にデータは更新されるけれども、特にユーザとインタラクティブに通信する必要のないサイトはS3で構築するのがgoodかも…

 

カテゴリー: AWS

複数EBSを含むAMIとAMIのリージョン間コピー

EC2の無料期間も残り数ヶ月、EC2サーバを価格の安いOregon Regionに移行するテストを実施してみました。
現在ブートディスク以外に3つのデータディスクを使用しているのですが、AMIの作成でEBSをそのままRemoveしないで実行すると一つのAMIで表示されますが、データ用のEBSを含んで一つのAMIとして保存、登録されることを理解しました。ですからこのAMIからインスタンスをLaunchするとこれらのデータディスクも合わせて作成されることになります。
Tokyoで作成したAMIをOregonに移動するにはオリジナル側のRegionでAMIを選択してActionでCopyを実行するとコピー先のRegionを洗濯することができます。今回はここでOregonを選択しました。
バックグラウンドではそこそこ大きなデータの転送になるのでしょう。コピーが終了して使用可能になるのに数時間かかりました。
コピー終了後は問題なくインスタンスの起動ができましたし、少し試験した限りではアクセスも良好でした。コストを考えるとやはりOregonへの移行がリーゾナブルそうです。

カテゴリー: AWS

mobiファイル自動転送プロジェクト

先日のmobiファイルをKindle端末へ直接メールする方法ですが、うまく動作するようになりました。入力画面もRadioボタンを使って、新規に作品が追加された場合も一行追加するだけで対応できるようにしました。
今回、Crayon Syntax HighlighterというWordpressのプラグインをインストールしたので、これを使って、コードも綺麗に表示したいと思います。(今まではCodeの表示に苦労していました….)
全体の流れは
htmlのformでGETの実行
JSPでGETの引数解析とJava Toolの起動
Java ToolによってNative Scriptの起動
Native Scriptによってmailxを起動してメール転送 となります。

htmlのフォームはこんな感じです。

ここではKindle上のアカウント名とKindleアカウントに登録しているメールアドレスを入力してもらいます。mobiファイルはRadioボタンによる選択、サブディレクトリはhiddenで指定します。

JSPでは引数のチェックを行って、正しく引数が設定されている場合のみサーブレットを起動します。

 

Javaのツールのコードです。単純にNativeコマンドの実行を行っています。Windowsで動作しているTomcatでは使えませんが、Linux(Unix)上で動作している場合、Unixのツールを簡単に使えるので個人的には重宝しています。
Linuxを単にTomcatを動作させるプラットフォームと考えるよりも、Unixの遺産を使いこなす環境と考えることも個人的には意味があるのではと思います。

Javaのツールのコード

使うスクリプトが増えてきて、引数の多いものを逐次追加しているのはご愛嬌というところで…..

最後にKshで作ったスクリプトになります。

jspのレベルではURLを直接タイプすれば誰でもメールできますが、結局はkindle.comにしかメールできませんし、添付ファイルも指定ディレクトリのものしか添付できませんので、不正に使用されることは無いと考えています。

試験した感想としては自分の通常使うメールクライアントに添付してkindle.comにメールするほうが端末にファイルが転送される時間が短いです。
おそらく、AWSで絞っているのか、sendmailの設定なのかはわかりませんが、私のサーバからAWS内のメールサーバへのメール転送に時間がかかり、さらにその先の転送スピードも遅いように見えます。AWS内でのデータ転送がトラフィックの関係で遅いのか、あるいは、契約上スループットが抑えられているのかは興味深いところです。添付ファイルのサイズが小さいと転送も速いように感じられます。

Kindleドキュメントをサーバから直接Kindle端末にメールする方法

最近、私生活ネタばかりになってしまいましたが、私のサイトの新しいアイディアをひとつ。
青空文庫の吉川英治の作品をmobiファイル化してサイトにアップしていますが、このmobiファイルはユーザの方がPCなりにダウンロードして、その後、メールやUSB接続でさ最終的にKindleに転送しなければいけません。(注:タブレッドなどでダウンロードした端末でmobiファイルをそのまま読んでいるのであればこの必要はありませんね。)
そこで、サーバからKindle端末にmobiファイルの添付されたメールを直接送れば手間が省けます。
最初はBase64のuuencode…..などを考えたのですが、実は私のAmazon Linuxにはmailxというアプリケーションが動作していました。(mailとタイプすると実はこのアプリが動作している。)このmailxには”-a”オプションでファイルを自動的に添付してくれますので、自分でuuencodeなどを使用する必要はありませんでした。
自分のKindle端末にメールを送る場合には実は事前に登録したメールアドレスから到着したメールのみが自分のアカウントに受信され、その後、Kindle端末に転送されます。ですから、自分のアカウントにmobi添付メールを送る場合には自分の登録アドレスがわかりますが、任意の人に使用してもらうには、そのあたりを考慮しなくてはいけません。ちなみにmailxでは”-r”オプションで送信元(返信先)アドレスが指定できます。
おそらく、このようなサービスを行う場合のスクリプトはこんな感じになると思います。

#!/bin/ksh
rm test$$
touch test$$
mail -a musahi01.mobi -s “Musahi01″ -r $2 $1@kindle.com <test$$
rm test$$

引数1としてKindleユーザのアカウント名、引数2としてKindleユーザの登録メールアドレス。Web画面からこのスクリプトを実行するにはjspなりサーブレットを使うのかなと考えています。