IntelliJでリモートのPython SDKを読み込む

子が産まれるまで時間あるからフロント技術習得でもしようと思って脱線しまくってる私です。


今日はIntelliJでリモートのPython SDKを指定できたのが便利だったのでBlogged.
IntelliJというかPyCharm helperの機能だろうけど。
ちなみにVagrant configから読み込む、てのでやりました。

  1. File -> New Project...
  1. 左ペインからPython Moduleを選択 -> Next
  1. Configure...

4. 左上のプラスマーク -> Python SDK

5. Remote...

6. File from Vagrant config -> VagrantFileのあるディレクト

7. HostをリモートIPにする(Auth, keyなども自分のを設定) -> Test connection...

8. Python interpreter pathの選択ボタン -> 好きなPython Interpreterを選択


ローカルには入れてないんだけど、ちょっとVMに入れたPython3系で試してみたいなーって思ったので好都合でした。

Java開発は乗り換えられなかったけど、これを機にIDE替えに挑戦。
IntelliJ、高機能でいいんだけどMacEmacsモードのM-系使えないのだけどうにかなれば嬉しいんだけど…

Vagrant1.5でEC2インスタンスを立ち上げる設定

今度はVagrantからEC2インスタンスsshアクセスした後、プロビジョニングしたい。
ということでやってみる。

  • 参考

vagrant 1.2を使ってみる - Qiita
GitHub - mitchellh/vagrant-aws: Use Vagrant to manage your EC2 and VPC instances.
Vagrant 1.1 で EC2 を vagrant up - naoyaのはてなダイアリー

  • やったこと
$ vagrant plugin install vagrant-aws
    • box追加
$ vagrant box add aws https://github.com/mitchellh/vagrant-aws/raw/master/dummy.box
    • VagrantFile
VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.box = "aws"

  config.vm.provider :aws do |aws, override|
    aws.access_key_id     = "<ACCESS_KEY_ID>"
    aws.secret_access_key = "<SECRET_ACCESS_KEY>"
    aws.keypair_name = "kamiya"
    aws.instance_type = "t1.micro"
    aws.region = "ap-northeast-1"
    aws.ami = "ami-c9562fc8"
    aws.security_groups = [ '<SECURITY_GROUPS>' ] 

    override.ssh.username = "ec2-user"
    override.ssh.private_key_path = "~/.ssh/aws-kamiya.pem"

  end

end
$ VAGRANT_LOG=DEBUG vagrant up --provider=aws

これ、最初デバッグつけてなかったんだけど、まんまvagrant 1.2を使ってみる - Qiitaの”ハマったところ”の現象になって付けた。
らとっても便利だった。
なかなかこの記事に辿りつけなくて遠回りしちゃった。

そして念願の

$ vagrant ssh

       __|  __|_  )
       _|  (     /   Amazon Linux AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-ami/2014.03-release-notes/
1 package(s) needed for security, out of 18 available
Run "sudo yum update" to apply all updates.

キターやったーー。

    • プロビジョニング

立ちあげた後なんだけど、プロビジョニングも普通に追記すればおk。

    config.vm.provision :fabric do |fabric|
      fabric.fabfile_path = "./provision.py"
      fabric.tasks = ["execute"]
    end

これは前回のFabricの設定

で、

$ vagrant provision
      • こんなエラーが出たら
Fatal error: sudo() received nonzero return code 2 while executing!

/etc/sudoersの下記をコメントアウト

Defaults    requiretty
  • Secret Access Keyについて

あとSecret Access Keyの取得方法がよりセキュアになったみたいで、IAMマネジメントのコンソールから取得するようだ。
これの通り。
Where’s My Secret Access Key? | AWS Security Blog
Getting Started with Amazon SQS - Amazon Simple Queue Service
Secret Access Keyは取得直後の一度しか表示されない。

Vagrant+Fabric試してみる

乗り遅れてる感満載なんだけど、必要に迫られてやっと触ってみた。
迫られてるというか産休中でドットインストールやってみてたら脱線しただけなんだけども。

Vagrantで実行するのにAnsibleがいいのかFabricがいいのか、よくわからなかったので調べた。
この2択にしたのはお手軽そうだったから。
ちなみに個人でテスト開発するようなちっぽけな環境構築なのでChefは最初から省いた。

まずはより手軽そうなFabric。

  • 参考

Vagrant Fabricで簡単プロビジョニング | Ryuzee.com
http://docs.fabfile.org/en/latest/api/contrib/files.html
http://nullege.com/codes/search/fabric.contrib.files.sed
http://nullege.com/codes/search/fabric.contrib.files.append

  • 前提

VMはCentOS6.4をVagrantで構築済み。
HostはOSX

  • やりたいこと

https://gist.github.com/fuzzy31u/117a6e00f93423aeca10

これはshellスクリプトのprovision。
# TODO manually!
とか書いてあるのを自動化したかったです。

全体的にはhttpサーバ起動したりMySQL, Pythonの最新バージョンをrpmインストールしたりソースインストールしたりするような手続き。

  • やったこと
    • Fabricインストール@ホストOS
$ sudo pip install fabric
    • Fabric provisionerインストール@ホストOS
$ vagrant plugin install vagrant-fabric

https://gist.github.com/fuzzy31u/a8e4e63df010f2fb7023

ファイル書き換えはputで置き換えなくてもsedとかappendが使えるよう

    • VagrantFile編集

https://gist.github.com/fuzzy31u/4912a6c0e9710c491944

    • プロビジョニングを適用しつつup
vagrant up --provision
  • Fabric触ってみて

簡単、学習コスト低い。
この程度であればファイル書き換えとか普通にできそうなのでもはやこれで充分。
困ったことと言えば、
複数行の記述を追記する時とかに改行コードで区切ってだらだら文字書くのが見にくい。
あと対話モードの実行がわかんなかった。(ちゃんと調べればできるのかも?

JVMの情報を確認する

$ jps | grep -v Jps
19111 Sample

$ jinfo 19111


Java SE 6 じゃじゃ馬ならし 管理用ツール


またJVMヒープサイズのデフォ値は

J2SE 5.0以降
初期値:物理メモリの 1/64
最大値:物理メモリの 1/4(上限1GB)
(物理メモリが1GBより小さい場合、最大値は物理メモリの1/2)

だそう

8Gの場合、
Xms: 126m
Xmx: 1024m

http://tech.ewdev.info/2012/01/298/

javaメモリ周り解析方法メモ

  • JVMメモリ/GC状況確認
$ jps | grep -v Jps
12942 
12965 Bootstrap
12812 

$ jstat -gcutil -t <pid> <time>
Timestamp         S0     S1     E      O      P     YGC     YGCT    FGC    FGCT     GCT   
          489.1   0.00   0.00  79.23  60.00  89.99     62    0.235     3    0.159    0.394
          492.1   0.00   0.00  79.23  60.00  89.99     62    0.235     3    0.159    0.394

=12965

    • 解析
  • gcutil オプション

ガベージコレクション統計データの概要
列 説明
S0 Survivor 領域 0 の使用率 (現在の容量に対するパーセンテージ)
S1 Survivor 領域 1 の使用率 (現在の容量に対するパーセンテージ)
E Eden 領域の使用率 (現在の容量に対するパーセンテージ)
O Old 領域の使用率 (現在の容量に対するパーセンテージ)
P Permanent 領域の使用率 (現在の容量に対するパーセンテージ)
YGC 若い世代の GC イベント数
YGCT 若い世代のガベージコレクション時間
FGC フル GC イベント数
FGCT フルガベージコレクション時間
GCT ガベージコレクション総時間

http://docs.oracle.com/javase/jp/6/technotes/tools/share/jstat.html

または実行時にオプションを付与

$ java -XX:+PrintGCDetails Sample

jstatの使い方 | dTblog | デザインとプログラムの境界をさまようブログ


  • ヒープダンプ
    • 取得
$ jps | grep -v Jps
12942 
12965 Bootstrap
12812 

$ jmap -F -dump:format=b,file=<filename> <pid>

=dump.hprof
=12965

    • 解析

Eclipse MAT(Memory Analyzer Tool)

Eclipseで、File > Open File...

JavaVMのメモリ管理に関するまとめ(Javaヒープ、GC、ダンプ等) - ぺーぺーSEのブログ


  • ヒープ統計情報
    • 取得
$ jps | grep -v Jps
19246 Sample

$ jmap -histo 19246

で標準出力に出力される

num #instances #bytes class name

                                                                                          • -

1: 4195417 134237248 [C
2: 4194433 134221856 java.util.HashMap$Entry
3: 4195397 100689528 java.lang.String
4: 4194436 67110976 java.lang.Integer
5: 34 50334752 [Ljava.util.HashMap$Entry;
 ・・・

    • 解析

見たまんまなので解析ツールはいらないかな。
メジャーなツールは特にないっぽい?

PrintClassHistogramツール関係を作成してみた - kotetsu0921のノート
使うとしたらこれかな。


Javaメモリ、GCチューニングとそれにまつわるトラブル対応手順まとめ - 日記のような何か


  • GCログ
    • 取得

起動オプションに下記を設定

- "-verbose:gc"
- "-Xloggc:$CATALINA_HOME/logs/gc.log.${DATE}"
- "-XX:+PrintGCDetails"
- "-XX:+PrintGCTimeStamps"
- "-XX:+PrintGCDateStamps"

で指定した場所にログが吐かれる

    • 解析

GC Viewer
見るべきは右カラムのSummary > Throughput
これはGCによる停止時間を除いたJVM稼働時間の割合。
85%を下回るとヒープサイズをチューニングする必要がある。

Webアプリの問題点を「見える化」する7つ道具 (2/3):現場から学ぶWebアプリ開発のトラブルハック(1) - @IT

目視なら
http://www.whitemark.co.jp/tec/java/javagc.html

  • スレッドダンプ
    • 取得
$ cp ${TOMCAT_HOME}/logs/catalina.out catalina.out_bk

$ kill -3 `pgrep -f "Bootstrap"`

$ diff catalina.out_bk ${TOMCAT_HOME}/logs/catalina.out >> threaddump.${DATE}.${TIME}
    • 解析

ツールは侍を使用

ここでチェックするポイントは以下の点である。

デッドロックが発生していない
・多くのスレッドが同じメソッドで停止している
・多くのスレッドが同じオブジェクトを待っている
・時系列で分析を行い、スレッドの状態が前回のスレッドダンプと同じ状況である

上記のような現象が発生している場合、オブジェクトロック長の問題や、オブジェクトの開放漏れなどによりマルチスレッドの実行が効率的に行えていない。

Webアプリの問題点を「見える化」する7つ道具 (2/3):現場から学ぶWebアプリ開発のトラブルハック(1) - @IT



GC発生状況の目標は下記を参考

マイナーGC、Full GCそれぞれが頻発することなく、かつそれぞれの実行時間を1秒未満に抑えること。

マイナーGCは1秒未満どころではなく、もっと短くなるべき。どれくらいが理想かは?(0.1秒未満ぐらいを目指したい?)

連続した負荷状態(想定されるピークアクセス)でもOutOfMemoryErrorが発生しないこと。

理想的な状態は、上記に加えて、Full GCの発生が低頻度であること。

具体的には、できるだけマイナーGCで短命オブジェクト(1回使ったらもう使わないようなオブジェクト。逆にセッションオブジェクト等は長命オブジェクトとなる)を破棄させて、短命オブジェクトが、TenuringThresholdを超えるマイナーGCを経てNew領域からOld領域へ移動することをできるだけ抑えることがチューニング目標となる。(Old領域に行ってしまうとFull GCでしか掃除されないため、できるだけOld領域に移る前にNew領域で掃除させるということ)(実際のTenuringThresholdが、-XX:MaxTenuringThresholdで指定した値にできるだけ近い状態を維持するということ)

http://d.hatena.ne.jp/learn/20090218/p1

MyBatisのスコープとライフサイクル

備忘録。

スコープとライフサイクル
これまでに説明した様々なクラスに適したスコープや、そのライフサイクルについて理解しておくことは大変重要です。 誤って使用すると、深刻な整合性の問題の原因となります。

SqlSessionFactoryBuilder

このクラスは、インスタンス化し、使用し、破棄することができます。 一旦 SqlSessionFactory を生成してしまえば、このクラスを残しておく理由はありません。 したがって、このクラスのスコープとして最適なのはメソッドスコープ(つまり、ローカルメソッド変数)です。 SqlSessionFactoryBuilder を再利用して複数の SqlSessionFactory を生成することも可能ですが、XML をパースするためのリソースが他の重要なものを圧迫しないように、このクラスを保持して使いまわさない方が得策です。

SqlSessionFactory

生成した SqlSessionFactory は、あなたのアプリケーション実行中はそのまま残しておくべきです。 生成した SqlSessionFactory を破棄したり、再度生成する理由はないはずです。 SqlSessionFactory を再生成しない、というのは所謂ベストプラクティスで、これを行なっていたら「何かおかしいぞ」と考えるべきです。 したがって、SqlSessionFactory に最適なのはアプリケーションスコープ、ということになります。 これを実現する方法はいくつもあります。 最も簡単なのはシングルトンパターンまたはスタティックシングルトンパターンを使う方法です。

SqlSession

各スレッドは、独立した SqlSession のインスタンスを使うべきです。 SqlSession のインスタンスは共有されることを前提としていないため、スレッドセーフではありません。 当然、最適なスコープはメソッドスコープになります。 SqlSession のインスタンスへの参照を static なフィールドや、インスタンスフィールドにも格納してはいけません。 Servlet フレームワークの HttpSession のようなマネージドスコープに SqlSession への参照を保持するのもダメです。 もし何らかの Web フレームワークを使っているのであれば、SqlSession のスコープが HTTP リクエストと同調するようにしておくべきです。 つまり、HTTP リクエストを受け取ったら SqlSession をオープンし、レスポンスを返すときにクローズすれば良いのです。 セッションをクローズすることはとても重要です。 間違いがないよう、常に finally ブロックの中でセッションをクローズするようにした方が良いでしょう。 SqlSession を確実にクローズするための一般的なパターンは下記のようなものです。

SqlSession session = sqlSessionFactory.openSession();
try {
  // do work
} finally {
  session.close();
}

常にこのパターンに従っておけば、すべてのデータベースリソースを確実にクローズすることができます。

Mapper インスタンス

Mapper は、Mapped Statement をバインドするためのインターフェイスです。 Mapper インターフェイスインスタンスは SqlSession から取得されます。 したがって、Mapper インスタンスの理論上の最長のスコープは、インスタンス取得元の SqlSession と同じということになります。 ですが、Mapper インスタンスに最適なスコープはメソッドスコープです。 つまり、Mapper インスタンスを利用するメソッドの中で取得・破棄するということです。 Mapper インスタンスを明示的にクローズする必要はありません。 リクエスト処理が完了するまで残しておいても問題ありませんが、SqlSession 同様、このレベルで余分なリソースを大量に扱うと、すぐに手に負えない状況になってしまうでしょう。 単純化のため、Mapper はメソッドスコープの中で使うようにしてください。 このプラクティスを実践したのが次のサンプルになります。

SqlSession session = sqlSessionFactory.openSession();
try {
  BlogMapper mapper = session.getMapper(BlogMapper.class);
  // do work
} finally {
  session.close();
}
http://mybatis.github.io/mybatis-3/ja/getting-started.html

結論、SpringまたはGuiceでDIフレームワーク連携しましょう。
ただ怖いのでスコープは一応覚えとく。

コマンドラインツールstreeを使う

MacにしてSourceTreeのGUIから新規リポジトリを読み込もうと思ったら反映されなかった。
SourceTreeにはstreeというコマンドラインツールがあるらしいことを知ってこちらを使うことに。

メニューの
SourceTree > コマンドラインツールをインストール
でインストール。

で、反映させたいディレクトリに移動して

$ stree .

してみたらちゃんとSourceTreeの新規読み込みダイアログが開いて反映されました。
以上。