Runtime.addShutdownHook()

Javaでアプリケーションの実行後に任意の処理をしたい時のやり方

例えば、↓のような場合である。

  • jvmの終了時(正常/異常)
  • System.exit()
  • Ctr+cなどでアプリケーションを終了させる
Runtime.getRuntime().addShutdownHook(new Thread() {
   @Override
   public void run() {
    // ここに終了処理を記述する
   }
  });

LINE Developer Conferenceに行ってきた

 

というわけで、LINE Developer Conferenceに行ってきました。

司会の田中さんが、Blogに書くまでが勉強会と言っていたので、記憶の新しいうちに、レポートを残しておきます。

LINE Developer Conference 開催のお知らせ : LINE HR Blog

リンク先にもある通り、アジェンダは以下の通りでした。

 

・講演1 All about LINE Platform
 LINE Platformとして何をどう扱い、どうEco-systemを作っているか、その全体像を紹介します。

・講演2 Esper CEP on LINEGame
 LINEゲームにおける同時接続者数のリアルタイム指標収集についてお話する予定です

 

まずは、LINEの今後のビジョンについて説明がありました。
話の印象としては、LINEは今後、Global進出を進めていこうとしていました。

と、LINEのビジョンの説明から始まり、話は本題のプラットフォームに関する話に。
まずは、

All About LINE Platform

と題し、LINE GAMEのプラットフォームについてでした。
LINE GAMEの開発とは、主に、GAMEアプリ用のSDKAPIの開発を行っているようです。最初は全体で一つのプラットフォームを持つようにしていましたが、今後1GAMEに1プラットフォームを持つようにしていくそうです。(すでにそうしている?)

そして、Esperについて。

このEsperというものは全く知らなかったのですが、CEP(Complex Event Processing)を実現するもので、リアルタイムデータをSQLライクに処理できるものらしいです。
LINE GAMEでは、Webサーバーからログ情報を送り、Esperを用い定期的にMySQLにデータを格納するような使い方をしているらしいです。
大雑把ですが、Esperでは、Update ListenerとSubscriberというものがあり、Update Listenerがイベントを検知し、Subscriberがデータ処理を行うような動きをするようです。

普段、データ処理を扱っていてEsperというものは初めて知ったので、どんなものなのかを一度ちゃんと調べてみようと思いました。

 

続いて、LINEのことについて話してくれました。

 

というか、ここ(LINEのClient⇔Server通信部分)が僕の一番知りたかったことでした!!

 

前に、LINEは通信プロトコルとして、SPDYを使っている事を、ブログを見て知ってはいたのですが、もうちょっと詳細に知りたかったのです。

Adopting SPDY in Line – Part 1: An Overview « LINE Engineers' Blog

今回はその部分をもうちょっと詳細に話してくださったのですが、LINEでの通信処理は、SPDYの規格の必要な部分だけを使い、残りは自分たちで実装したそうです!しかもErlangでwこの仕組をLEGY(Line Event Gateway)と呼んでいるそうです。
全部ではなく必要な所だけ?と思うかもしれませんが、既存のSPDYでは、UAなどの情報に関するものなども含まれているのですが、LINEで行われる通信のクライアントは、LINEアプリだけ、というかLINEアプリのクライアント以外から通信がくるということは、アプリがクラッキングされている状態ですwと話していました。このような事情により、LINEでは、LEGYという、SPDYの規格を元にした、独自プロトコルの実装を行ったそうです。(詳細な情報は今後LINE Tech Blogにのる予定だそうです。)

通信処理の後の流れですが、Cache的なDBとして、データはRedis→HBase→HBaseHA→Storm→MySQLという構成をとっているそうです。(多分部署によっては、色々違う形になっていると思います。)
(最終的な構成になるまで、いろいろな事件が起きたそうでした・・・)

 

LINEの裏っかわの仕組みの話が終わったら、最後に開発者の方々による質問タイムみたいな時間になりました。(ファイヤーなんとかって呼んでましたが忘れましたw)ここでは、開発の苦労話などがはなされてました。

印象に残ったのが、「当初のユーザー数の目標は100万ユーザーだったけど、その年は結局目標の10倍の数のユーザー数になった」という話でした。想像を超えるアクセスがあり、データストアもスケールさせなければいけなかったので、この3年間は相当大変だったようです。。。

感想

今回の勉強会は懇親会もあり、中の人からいろいろな話が聞けて大変楽しい時間でした!!(しかもLINEの方がご飯を用意してくださいました!!)
おみやげも8GのUSBメモリーやLINEグッズなどがいっぱいあって豪華絢爛!!LINEすごいす!LINEの方々、お疲れ様でした!次回も期待しています!w

このエントリーをはてなブックマークに追加

f:id:m19cmjigen:20140417221801j:plain

f:id:m19cmjigen:20140417221739j:plain

f:id:m19cmjigen:20140417202509j:plain

レゴスクラム

レゴスクラムを社内の方に実施していただいたので、体験レポートを書き留めておきます。

レゴスクラムとは

スクラム開発の一連の作業をレゴを用いた町づくりと似せて擬似体験を行うワークショップです。

 

詳しくはこちらの記事を参照

理屈より実践で学ぶアジャイルの方法論:「LEGOブロックで街づくり」 実体験型スクラム入門をのぞいてみた - @IT

全体の流れ

  • チームを組む(各チーム4人くらい)
  • チームの中での役割を決める(例:父、母、姉、弟、犬など。。。)
  • テンプレートにしたがって役割としてほしいものを決める(例:弟として、コンビニが欲しい。なぜなら毎週ジャンプを買いたいから
  • テンプレート

    ◯◯として

    △△が欲しい

    なぜなら□□がしたいから

  • 欲しいものをストーリとして、チームで共有し、町のコンセプトを考え、何が町に必要かの優先度を決める(上、中、下)
  • ストーリをもとに、パッケージデザインを作る(大きい模造紙に町を描く)
  • チームの席を交換し、他チームのパッケージデザイン、ストーリを見て、ストーリーにストーリーポイントをつける
  • 自分のチームに戻り、出されたストーリーポイントと優先度を元に、すべてのプロダクトバックログを実現させて欲しい順番に並べ替える。
  • パッケージデザインを元に、町のコンセプトとストーリーを説明してもらう
  • また、他チームの席に移動し、優先度によって、並び替えられたPBを元に、計画MTGを始める
  • 実際に作業を行う
  • 振り返りを行う

 

感想

この研修を通して僕は以下のことを再確認しました。

  • スプリント計画の際に綿密に話すことは、不確実な開発要件に対し、実際の開発をどのように行えばよいか?という不安を取り払ってくれる。または、分からない部分がより明確に分かるので、安心する
  • スプリント計画の際に、実際のタスク内容について不確実な確認しか行っていないと、実際の開発着手時になにを行えばよいかわからない
  • プロダクトオーナーの要求をコミュニケーションを通し、より理解する必要がある
  • スプリントを回す事によって、開発力、そしてチームとしての習熟度も上達する。(経験の共有など)

 

スクラムの擬似体験ワークショップとして

約4時間で、3スプリントを回しまた。実際は4スプリント回したかったようだが、初心者にとっては、スクラム開発ってどうやって回すのだろうというのがなんとなくつかめると思います。ただ、このワークショップを行っても、実務では実際にはすぐに回せないと思う。ワークショップ自体は楽しいのだが、実際の開発と照らし合わせて考えることはなかなか難しいのではないかと思います。

 

このエントリーをはてなブックマークに追加

滞在時間を測りたいページに下みたいなjavascriptを仕込んで、アクセス先のphpで、ログファイルに落とす感じでいけそう。

仕込むJS
(function() {
        var second = 0 ; 
        function countUp() {
                second++ ;
        }   
        function b() {
                var img = new Image() ;
                img.src = 'http://example.com/access.php?url=' + document.location + '&sec=' + second ;
        }   
        if( window.addEventListener) {
                window.addEventListener('load', function() {
                        setInterval(countUp, 1000) ;
                }, false) ;
                window.addEventListener('unload', b, false) ;
        } else if(window.attachEvent) {
                window.attachEvent('onload', function() {
                        setInterval(countUp, 1000) ;
                }) ;
                window.attachEvent('onunload', b) ;
        } else {
                window.onload     = setInterval(countUp, 1000) ;
                window.onunload = b() ;
        }   
 })() ;
アクセス先のPHP
<?php
define('LOG_PATH', '/tmp/') ;
{
	$url         = $_GET['url'] ;
	$sec         = $_GET['sec'] ;
	$filename = 'track-' . date('Y-m-d') . '.log' ;
	$log = <<<EOF
[url]:${url}
[second]:${sec}

EOF;
	error_log(
		$log ,
		3,
		LOG_PATH . $filename
		) ;
        exit(1) ;
}
?>
落ちるログ
/tmp/track-2011-04-07.log
[url]:http://example.com/test.html [second]:21
[url]:http://example.com/test.html [second]:0

実際は、jsだと自由に書き換えられてしまうので、アクセス先のphpにてエラーチェックは必須。
実際はgoogle analystic仕込めばいいんだけどね!!

sshによるnon path設定メモ

たくさんのサーバーを管理していると、多くのサーバーに同一の事をしなくてはいけない用件が多々あると思います。

用件によっては、以下のようして、公開鍵と秘密鍵を作成して、ログイン先に公開鍵を置き、ログイン元のサーバーに秘密鍵を置き、ノンパスでログインするようにする事があると思います。(同じネットワーク内のサーバー同士の時などで)

# SSH2の鍵の作成
$ssh-keygen -t rsa -N ""
Generating public/private rsa key pair.
Enter file in which to save the key (/home/username/.ssh/id_rsa): 
Your identification has been saved in /home/username/.ssh/id_rsa.
Your public key has been saved in /home/username/.ssh/id_rsa.pub.
The key fingerprint is:
・・・
# 公開鍵をauthorized_keysに追加
$cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
# パーミッションを自分だけが読めるようにする。
$chmod 600 ~/.ssh/authorized_keys

上記の事を行い、作成した秘密鍵(id_rsa)をログイン元サーバーに置き、そのファイルを指定すれば(~/.ssh/以下に置けば指定しなくても自動でファイルが適用される)sshの際に秘密鍵と公開鍵の認証が行われるようになります。
ただ、この際実際にノンパスでログインしようとすると、最初に以下のような事が聞かれます。

$ssh  ~/.ssh/id_rsa @servername
・・・
Are you sure you want to continue connecting (yes/no)? 

ここで、yesをすると、/home/username/.ssh/known_hostsファイルにフィンガープリントが挿入され、晴れてノンパスでログインできるようになります。


ただ、運用を行っていて、サーバーが一気に増えたときにknown_hostsへの追加をいちいち1台ずつ行っていては面倒です。100台のサーバーにいちいちsshを行い、yesを行っていては時間の無駄です。

で、今回は一度に多くのサーバーを追加する方法があったので、どのように行ったかを忘れないように書きます。(公開鍵が全てのログイン先サーバーに置かれている事が前提です。)

作業は、簡単で、サーバーのリストを作成して、各サーバーに対するフィンガープリントをssh-keygenというコマンドを用いて出力し、それをknown_hostsファイルに上書いていきます。

# ログイン用サーバーのリストの作成
$vim server.txt
server1
server2
server3
・・・
#フィンガープリントの作成とknown_hostsへの書き込み
$bash -c "ssh-keyscan  -f servers.txt" >> ~/.ssh/known_hosts

と、これだけです。
このようにして、全てのフィンガープリントを一気にknown_hostsへ追加する事ができます。

逆に、known_hostsのファイルから指定のドメインのフィンガープリントを行いたい場合は、以下のようなコマンドで行えます。

$ ssh-keygen -R domainname

番外

フィンガープリントの追加を自動で行う方法

StrictHostKeyChecking yes

ついでに、sshには、configファイルを持つ事ができます。
デフォルトでは下のようにファイルの読み込みを行いますが、

/etc/ssh/ssh_config
↓
~/.ssh/config
  • F オプションで、自分の指定した設定ファイルを読む事ができます。

複数のサーバーで作業する事が多いときは、このconfigファイルをうまく使うと運用が楽になります。

# ~/.ssh/config
# sshの際にs1と入力すると、実際のホスト名 server1.com に、~/.ssh/server1.identityという秘密鍵を使って、ログインを行おうとする。
Host s1
    Hostname server1.com
    IdentityFile ~/.ssh/server1.identity
# server2にログインする際は、hogehogeユーザーで、~/.ssh/server2.hogehoge.identityの秘密鍵を用いてログインする。
Host server2
    Hostname server2.com
    User hogehoge
    IdentityFile ~/.ssh/server2.hogehoge.identity

設定項目などについては下のページが詳しいです。
http://www.unixuser.org/~euske/doc/openssh/jman/ssh_config.html

xdebugとwebgrindを用いたphpのプロファイリング

webページとかDB高速化の話を最近よく見ますね。
最近自分もページ表示の高速化を行っていたのですが、その中で、
phpで行ったxdebugとwebgrindを組み合わせたチューニング方法がとても簡単で便利だったので、やり方をメモしておきます。

php-pecl-xdebugのインストール

まず、xdebugのインストールpeclで提供されていて、パッケージが提供されているので、以下でインストール

$yum install php-pecl-xdebug

xdebug.ini(設定ファイル)の変更

その次に設定ファイルを変更します。

$vim /etc/php.d/xdebug.ini
; Enable xdebug extension module
zend_extension=/usr/lib/php/modules/xdebug.so
; "以下が今回追加した箇所"
; debug結果をファイルに書き込む
xdebug.profiler_enable=1
; より詳細にdebugしたい場合 xdebug.profiler_enableかどちから
;xdebug.profiler_enable_trigger=1
; 結果のファイルの保存先 (default:tmp)
xdebug.profiler_output_dir=/tmp

設定の詳細は以下のページを参考に 
Xdebug:Documentation

apacheの再起動

これで、xdebugの設定は完了です。apacheを再起動して適当なphpファイルを配置して、アクセスするとtmp以下に、以下のようなファイルができていると思います。

/tmp/cachegrind.out.~

デフォルト設定だと、cachegrind.out.~というファイル名ですが、これを変更したい場合は、
xdebug.profile_outputname
という値を変更します。

ただ中身を見てみても内容がよくわかりません。

$cat /tmp/cachegrind.out.~
$ cat /tmp/cachegrind.out.~
version: 0.9.6
cmd: /var/www/html/phpinfo.php
part: 1

events: Time

fl=php:internal
fn=php::phpinfo
3 3566

fl=/var/www/html/phpinfo.php
fn={main}

summary: 3629

0 63
cfn=php::phpinfo
calls=1 0 0
3 3566

ここで、webgrindというツールを用いて、より簡単にこの結果を確認してみます。

webgrindの導入

まず、webgrindを以下のサイトからダウンロードします。
webgrind Project Hosting on Google Code

DocumentRoot以下に配置

今回は、以下のように保存しました。

/var/www/html/webgrind/

config.phpの編集

その後、解凍したファイルの中のconfig.php内の以下の変数をxdebugの出力先のパスに変更するのですが、デフォルト値が/tmpなので、今回は特に変更しません。

/var/www/html/webgrind/config.php

あとは、webgrind/index.phpにアクセスするだけで、以下のように結果が出力します。
今回は、phpinfo()しかしていないので、あまり意味はなく感じますが、関数単位で、実行時間が測れるのでとても便利ですね。

xdebugだけでも、とても便利な使い方があるので、色々とやってるといいですね。
Xdebugを導入してみる - JavaのStackTraceが欲しい!

xdebugが有効の時は、実行速度が落ちるので、チューニングが終わったら、xdebug.iniをコメントアウトして、xdebugを無効にしましょう。

今回、意外にdateの処理が時間がかかっている事に驚きました。引数の場合にもよるけど、すべての関数にどのくらいの時間がかかっているか簡単に見てみたいな。

yuicompressorをコマンドラインで簡単に使えるようにしたので、そのメモ

以下のページからyuicompressorの最新版をダウンロード
http://yuilibrary.com/downloads/
あとは、自分の環境に応じて設定を行います。



以下は、Linux環境で環境を構築したメモ。(以下はjavaが動く事が前提です。)

"カレントディレクトリに移動"
$cd ~
"今回はSrcというディレクトリ配下にソースをおきます"
$mkdir Src
$cd Src
"zipファイルを取得(20101005時点では最新は2.4.2)"
$wget http://yuilibrary.com/downloads/yuicompressor/yuicompressor-2.4.2.zip
$unzip yuicompressor-2.4.2.zip
"これで、以下のようにすれば、圧縮ファイルを作成する事ができます。(example.jsというファイルはjavascriptファイル)"
$java -jar ~/Src/yuicompressor-2.4.2/build/yuicompressor-2.4.2.jar --type js example.js > compress_example.js

ただこれだと、圧縮するのに毎回パスなどを打つのが面倒なので、以下を.bashrcなどに追加

YUI_ROOT=$HOME/Src/yuicompressor-2.4.2/
yuicompress() {
     /usr/bin/java -jar $YUI_ROOT/build/yuicompressor-2.4.2.jar ${@}
}

これで、どこのパスにいても以下のようにしてyuicompressorを簡単に使えます。

yuicompress --type js example.js > compress_example.js

今回は自分のホームディレクトリ以下にファイルをおいたけど、どこにyuicompressorのソースファイルを置くのが適当なんだろう。。。

今日は、docomoの冬の最新機種の発表だ。。。