2013年6月26日

下の人などいない

周回遅れエンジニアはダメダメダメ子さんなエンジニアですが、気を付けていることがあります。

それは「下を見ない」ということです。
下を見て、それよりマシだからといって安心してしまうことは、不満に思っている現状から抜け出せなくなります。

それでは下とはなんでしょう?

それを言っていた頃は、こんなことを「下」と思っていました。
・自分たちより多い残業時間
・自分たちより少ない給料
・自分たちよりキツイプレッシャー
・自分たちより作業効率が悪い
などなど。

挙げてみてもやっぱり、それより良いからと言って満足できるものではありません。

「上」を見てもがないように、「下」を見てもきりがない。
だから、もっと上を目指して行くことを考えています。

2013年6月20日

try-with-resources

Java SE 7 の新機能に「The try-with-resources Statement」というものがあります。

これまではリソースをオープンした場合、このように忘れずにclose()しないといけませんでした。
SomeIO io = null;
try {
    io = new SomeIO();
    io.somethingIO();
} finally {
    if (io != null) {
        io.close();
    }
}

毎回同じようなコードを書くのは面倒だ!
ということで作成された今回の新機能。tryを書くときに宣言すると、ブロックを抜ける場合にclose()を呼んでくれるステキな機能です。
try (SomeIO io = new SomeIO()) {
    io.somethingIO();
}
これだけでOKとは本当にステキです。

ここで指定できるクラスは java.lang.AutoCloseable を実装したクラスです。
ここではわざとIOExceptionを発生させるようにしています。
class SomeIO implements AutoCloseable {
    @Override
    public void close() throws IOException {
        System.out.println("忘れずにClose!");
    }

    public void somethingIO() throws IOException {
        System.out.println("IOが発生!");
        throw new IOException("IO Error!");
    }
}

実行結果をみると、例外が発生していますが、close()してくれています。
IOが発生!
忘れずにClose!
Exception in thread "main" java.io.IOException: IO Error!
 at TryWithResources$SomeIO.somethingIO(TryWithResources.java:24)
 at TryWithResources.main(TryWithResources.java:9)

しかし周回遅れエンジニアは性格が悪いので、SomeIOをこんな風にclose()時にもIOExceptionを発生させてしまいます。
class SomeIO implements AutoCloseable {
    @Override
    public void close() throws IOException {
        System.out.println("忘れずにClose!");
        throw new IOException("Close時にIO Error!");
    }

    public void somethingIO() throws IOException {
        System.out.println("IOが発生!");
        throw new IOException("IO Error!");
    }
}

最初の従来ソースでこれを実行すると、somethingIO()にて発生した例外が握りつぶされてしまいます。
Exception in thread "main" IOが発生!
忘れずにClose!
java.io.IOException: closeに失敗!
 at TraditionalIO$SomeIO.close(TraditionalIO.java:31)
 at TraditionalIO.main(TraditionalIO.java:18)

そのため、finally区内でもtry-catchを書く必要がありました。リソースが増えるとその分、try-catchが増えるといったイヤラシイ定型句になっていました。
SomeIO io = null;
try {
    io = new SomeIO();
    io.somethingIO();

} finally {
    if (io != null) {
        try {
            io.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

こんどはスタックトレースがしっかり出力されています。
IOが発生!
忘れずにClose!
java.io.IOException: closeに失敗!
 at TraditionalIO$SomeIO.close(TraditionalIO.java:31)
 at TraditionalIO.main(TraditionalIO.java:18)
Exception in thread "main" java.io.IOException: IOに失敗!
 at TraditionalIO$SomeIO.somethingIO(TraditionalIO.java:36)
 at TraditionalIO.main(TraditionalIO.java:11)


では、try-with-resources句を使うとどういった実行結果となるでしょうか?
IOが発生!
忘れずにClose!
Exception in thread "main" java.io.IOException: IO Error!
 at TryWithResources$SomeIO.somethingIO(TryWithResources.java:24)
 at TryWithResources.main(TryWithResources.java:9)
 Suppressed: java.io.IOException: Close時にIO Error!
  at TryWithResources$SomeIO.close(TryWithResources.java:19)
  at TryWithResources.main(TryWithResources.java:10)
なんということでしょう。
周回遅れエンジニアのように性格の悪い人がいたのか、しっかり「Suppressed」としてスタックトレースから確認することができました。
こちらは java.lang.Throwable の拡張のようで、Throwable.addSuppressed()や、Throwable.getSuppressed()にて追加・取得ができるようです。



この機能によってclose()のし忘れを防止でき、コードもシンプルになりました。
これは使うしかないですね。

2013年6月19日

AWS ConsoleでService Healthを見る

AndroidアプリにAWS Consoleというものがあります。

名前の通り、AWSのConsoleがAndroid端末から使えます。

このアプリはEC2インスタンスの起動・停止やCloudWatchのグラフを見る事ができるのですが、それ以外にもService Healthを確認できるステキな機能があります。
通常はこちらのRSSをチェックするといった方法がありますが、AndroidのAWS Consoleは何かある場合に見やすいです。



このように、普段は何も表示されないのですが、何か問題がある場合は・・・って何か起こっていますね・・・


ELBとEC2に接続性の問題が発生しているようです。


今はもう解決しているようですね。


このように、現在のAWSのServiceHealthの状態が出先でも簡単に確認する事が出来ます。
でも、確認するようなシチュエーションは避けたいですね。。。

2013年6月18日

OpsWorksのセットアップの仕組み

OpsWorksがどうやってセットアップしているのかというと、Chefを使っているのですが、ではChefはどうやってセットアップしているのでしょう?

試しに起動してみたところ、OpsWorksで使用しているAMIは
amzn-ami-pv-2013.03.0.x86_64-ebs (ami-173fbf16)
でした。

先ほど起動したAmazon Linuxが
amzn-ami-pv-2013.03.1.x86_64-ebs (ami-39b23d38)
だったので、巣のAmazon Linuxを使っているようです。

では、どうやってChefをインストールしているのか、ということに戻ります。

インスタンスのUserDataを調べてみると・・・当たりっぽいです。


ここではBeansTalkのようにスクリプトをダウンロードするわけではなく、ベタでスクリプトが書かれていますね。
この中でOpsWorksのツール群をダウンロードしているようです。

UserDataのScriptで処理を行うのは、AMIが変わっても使えるので柔軟性が高いのかもしれませんね。


なお、OpsWorksではAMIを使えません。
Q: 独自の AMI を使用することはできますか?
いいえ。ただし、Chef のスクリプトを使用して OpsWorks がサポートする AMI をカスタマイズし、必要なエージェントやその他のソフトウェアをインストールすることができます。

きっと使えるようにしたら、CentOSとか、Windowsでも動かそうとしているからですかね?

現時点ではOpsWorksではオートスケーリングが使えませんが、独自のスケール機能を持っています。
Chefでセットアップする分、起動に時間がかかる気がしますが、そのあたりは検証してみる必要がありそうですね。

2013年6月14日

Beanstalkのセットアップの仕組み

Elastic Beanstalk を試しに使ってみたのですが、カスタムAMIを作ろうとしたとき、その元となるAMIにはTomcatなどが入っていませんでした。
(カスタムAMIの使用方法はこちら

じゃあ、どうやってインスートールしているんだーーーと思っていたのですが、その謎が解けました。

Beanstalkから起動した場合、/var/log/yum.logを見ると、tomcat等をインストールしているのがわかります。
でも、普通に起動した場合はインストールされません。

この謎は、User Data にありました。

Beanstalkから起動したインスタンスのUserDataを確認してみると、スクリプトが埋め込まれており、
そのスクリプト内でS3からスクリプトをダウンロードして、それを実行しています。

User Dataのスクリプトはcloud-initにて実行されます。
実際は /etc/init.d/cloud-init-user-scripts から /var/lib/cloud/data/scripts のスクリプトを実行しているみたいですね。

EC2のCloud Initについてはこちらから確認できます。
いろいろ奥が深そうですね。

ドキュメントにはこのように書かれています。
Amazon Linux AMI では、次の Cloud-init アクションを使用します(/etc/sysconfig/cloudinit で設定可能)。

action: INIT(常に実行)
  • デフォルトのロケールを設定します。
  • ホスト名を設定します。
  • ユーザーデータを解析および処理します。
action: CONFIG_SSH
  • ホストプライベート SSHkeys を生成します。
  • 容易にログインおよび管理できるようユーザーのパブリック SSHkeys を .ssh/authorized_keys に追加します。
  • action: PACKAGE_SETUP
  • yum repo を準備します。
  • ユーザーデータで定義されたパッケージアクションを処理します。
action: RUNCMD
  • シェルコマンドを実行します。
action: RUN_USER_SCRIPTS
  • ユーザーデータにあるユーザースクリプトを実行します。
action: CONFIG_MOUNTS
  • エフェメラルドライブをマウントします。

ちなみにManagement Consoleから確認できるのですが、Beanstalkを使うと内部的にはCloudFormationを使っているみたいです。

CloudFormationもBeanstalkは難しいですね。。。

2013年6月11日

言語を学ぶ

今年はRubyを覚えてみたいなー

とどこかのアンケートに入力したところ、以下のURLが送られてきました。
http://www.codecademy.com/

どうやらいろんな言語の学習サイトのようです。
日本語のコンテンツもある・・・のかな?
面白いですね、こういう学習サイトがあるなんて。

Scalaのサイトも以前見つけました。
http://www.simplyscala.com/

あとは腰を据えてやってみる事が必要ですね。。。

2013年6月7日

Scrum Boot Camp

Scrum Boot Campが開催されるみたいですね。
http://taoofscrum.doorkeeper.jp/events/4229

周回遅れエンジニアは以前参加しようとおもったのですが既に満席だったため、Premiumを受講しました。
何人かに「早く申し込んで!」とメールしましたが、無反応です。

悲しい。。。
Scrumに興味無いんですかねえ?

2013年6月5日

IMEの単語登録のショートカット

日本語入力がONの時に「CTRL+F10」を押すとIMEのメニューが出ます。

ここから単語の登録が簡単にできます。

周回遅れエンジニアはこれでよく使う言葉を登録しています。

おつ:おつかれさまです。周回遅れエンジニアです。
よろ:宜しくお願い致します。

心がこもっていないですね。。。

タブ移動の戻り方

作業をしているときタブで入力項目を移動したりしますが、
行き過ぎたりしませんか?

そんなときはshiftキーを押しながらタブを押すと前に戻れます!

便利です。

AWS Java SDKのアクセスキー・シークレットキーの指定

AWS SupportAPI のサンプルコードを見ていたら、APIのアクセスキー・シークレットキーの指定が以下のようになっていました。
AWSSupportClient support = new AWSSupportClient(new DefaultAWSCredentialsProviderChain());

JavaでAPIのテストするときはプロパティファイルを読み込んでいたので、「これは何ぞや?」ということで、ソースコードを見てみました。

AWSCredentialsProviderChainのサブクラスで、EnvironmentVariableCredentialsProvider、SystemPropertiesCredentialsProvider、InstanceProfileCredentialsProviderを渡しています。
JavaDocにあるように、以下の順でCredentialを探します。
環境変数 - AWS_ACCESS_KEY_ID and AWS_SECRET_KEY
Javaのシステムプロパティ - aws.accessKeyId and aws.secretKey
EC2のインスタンスのプロファイル - インスタンスのIAM Role

こんな便利なクラスがあったのですね。

AWSCredentialsProviderのJavaDocを見るといろいろ他にも種類があります。

いままでわざわざ実装していたプロパティファイルから取得するAPI(ClasspathPropertiesFileCredentialsProvider)も実はありました。

他人のソースを見るのは勉強になりますね。