oranie's blog

旧:iをgに変えると・・・なんだっけ・・・

【チラ裏】Android学習メモ-2

今日はFragmentを隣の人に少し教えて貰った。昨日のドキュメント読んでとか教えてくれた人は「こんな感じかな」というソースを見せて貰ってようやく何のため使うかとかは理解できたけど、既存のlayoutをFragmentに書き換える所がチンプンカンプン。これ、一連の流れで説明見ないと理解出来んな。
もうこれ以上ここに時間使いすぎてもアレなので、一旦Fragmentは離れて早めに終わらせそうなネットワーク通信やった。ただ、初めにメインスレッドで実行すると今のVerはException出るの知らなくて、ビルドしたら動かなくてなんじゃこれとなった。で、通信部分を別のクラスに分割したら、分割したクラスを上手く扱えない。補完では出てくるのに実際に記述するとそんなの知らないと出てくる。この辺はJavaの基本的な知識の欠如。Javaの書籍読みなおす。非同期処理の所とかもとりあえずコピペでやってしまっているので、ネットワーク通信も一旦置いておいて基礎的な非同期処理の所を明日やろう。

【チラ裏】Android学習メモ-1

異動してからとりあえずAndroidの学習をということで、mixiさんのAndroid研修カリュキュラムを教材に出されほぼ独学で読んでやっている。
https://github.com/mixi-inc/AndroidTraining
昨日までは
android studioとgenymotion入れて単体のプロジェクト作ってエミュ上で表示するレベルやって、レイアウトの所をちょろちょろやっていた。
で、今日は
2.02. Activity と Fragment
の実習・課題をやっていた。Activityの所はなんとなくホゲホゲ分かった。TCPソケットの状態遷移みたいな感じでActivityというのは状態遷移している。これで表示したりするものを切り替えている。ただ、Android Studioでデフォで作成されるHello World出すだけのプロジェクトだと、状態遷移全部記述していないけど、これって最低限記述しなければいけないのがonCreate()というお作法とかなのか理解出来ていない。そもそもJavaの知識足りてなさすぎるのと、リファレンスもまだ全然見れていないから分からないのだろう。
https://developer.android.com/reference/packages.html
Fragmentの所はまだチンプンカンプン。なんじゃこれ。

実習の所はFragmentの所で詰まって他が手につかないのはマズイので一回飛ばした。どっかでちゃんと確認する。
ControllerLifecycleAssignment1の課題はそれぞれprintfデバッグみたいに入れて表示して確認したけど、これやって欲しい粒度が合っているのかそもそも微妙な気がしている。明日聞く。
ControllerLifecycleAssignment2の課題はそもそもエミュだと状態保存されないはずの動作が初めから保存されているような動きっぽいけど、破棄されるタイミングちゃんと分かっていないから勘違いしているのかな。とりあえず保存・復元する処理自体は書いたけど、動作が変わっていない気がするのでちゃんと動いているのか確認出来ていない。明日聞く。

この辺で辛くなって少しでも分かりそうなネットワーク通信の課題をちょっと気分転換に見て
https://github.com/mixi-inc/AndroidTraining/wiki/2.09.-%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E9%80%9A%E4%BF%A1
画面操作・表示より全然楽そうでそこやってしまおうかと現実逃避しそうになった。

Android Studioの機能をちょろちょろ見始めている。とりあえず背景は黒くした。背景が黒は正義。
明日は周りの人が見るに見かねてペアプロばりに教えてくれるらしいので頑張ろう。

半年後とかにはこのグダグダした「わからない」「出来ない」連発のメモを黒歴史に出来るようにしたい。

サーバ側のSSL Session Cache状況を確認する「rfc5077」というツールが便利

この2日ぐらいスマートフォンアプリ開発エンジニア必須スキルのNginxを触りまくっていて、同僚が見つけて来て触ったら便利だった。
githubはこれ。
https://github.com/vincentbernat/rfc5077

手順はREADMEに書いてあるけど、

sudo yum install openssl-devel  gnutls-devel nss-devel  libpcap-devel libev-devel  nspr-devel pkgconfig
git clone  https://github.com/vincentbernat/rfc5077.git
cd ./rfc5077
git submodule init
git submodule update
make

で完了。カレントディレクトリに/rfc5077-clientというファイルが出来るので、

./rfc5077-client -p 443 example.com

とかやると

な感じでSSL Session IDがどう変化しているか、SSL Session Ticketが有効だとどうか?というのが分かる。

この辺のそもそも知識はid:nappa_zzzさんのブログやスライドが詳しいので、そちらをどうぞ。
ブログ
http://d.hatena.ne.jp/nappa_zzz/20111204/1322961826

スライド

NginxでSSLセッションキャッシュを有効にした際に新規セッションが張れなくなる事象について

多分Nginxでゴリゴリやっている人ならm9(^Д^)プギャーだろうけど、メモっておく。

サーバサイドでSSL処理をする際に少しでもCPU処理を軽くする+レイテンシを下げたい目的で

    ssl_session_cache shared:SSL:128m;
    ssl_session_timeout  300m;

的な設定を入れた所、負荷が高い時間帯に

[alert] 14099#0: *1627571 could not allocate new session in SSL session shared cache "SSL" while SSL handshaking, client:〜省略〜

というログが出た。ソースコードをほげほげ読んでみると
ngx_event_openssl.cのngx_ssl_new_session
で記述されている処理でおそらく

  1. キャッシュ領域に書き込もうとする
  2. 溢れている時は一度古いのを消す
  3. 但し、空けた瞬間に別のリクエストがそこを使ってしまう
  4. もともと空ける処理をしていたところは再度書き込みに失敗する
  5. エラーとなる

という流れっぽい。

その為、CPU負荷も問題が無かったことから一旦キャッシュはnoneで設定するようにした。

【チラ裏】色々あって社内ジョブチェンジでスマートフォンアプリエンジニアになりました。

昨今の殺伐としたインターネットを見ていたら「インフラエンジニア(狭義)は死んだ」というのを発見し、内容にいたく感銘を受けこれではマズイと思ってジョブチェンジしました。



本当の所は深淵なる諸事情とかもあるが「まあアプリ書けたらエンジニアとして良いよね」というノリで、ジョブチェンジする事になりました。
正直サーバサイドの運用担当から離れる事は結構未練や不安はあり、特にこの2年間くらいはCassandra運用に結構専念させて貰っていた(まあCassandraのソースちゃんと読んだりするレベルとかは他のエンジニアが調べたのを教えて貰ってというレベルですが)おかげで、第一人者には程遠いですがCassandra芸人チックなレベルにはギリギリなれた感はあったので、サーバサイドアプリではなく今までの経験があまり活用できないかもしれないスマートフォンアプリに行くことは「本当にキャリアにとっていいんだろうか?」とかは思いましたが、

@riywoさん(運用エンジニアから開発エンジニアになるためにやったこと)や@marqsさんが運用エンジニアから開発も〜という流れを見たりしていたので、「まあ、どう考えても開発も出来る方が良いよね」「他の開発者も同じ人間なんだからなんとかなるだろ」「Cassandraの運用とどっちが難しいのかな」とかを知る意味でもいい機会かなと思いました。ただ、riywoさんの記事を改めて読んで、自分はこういう時の為の準備を全然していない事に気付いて意識の低さを再認識しましたね。記事をブクマはするけど結局何も準備せずにこの体たらくかと。

まあ、「スマホアプリ開発に比べたら分散データストアの運用なんて簡単やったんや!今度は心を入れかえてもっと真剣に運用します!」ってなれば、まあそれはそれで良いのかなと。あとはCassandraがJavaで書かれていることから、結局Java分からないと運用のクオリティが上がらない為、もしまた運用に戻った時も今よりはマシな運用が出来る様になるかなというのもあります。

あとは2年間プラットフォームサービスの運用チームをやっていて、良くも悪くも今のチームでは割りと好き勝手にやらせて貰っていたので、僕がいたせいで優先度を下げられていた事とかが別の人が担当になる事で「いや、ここは改善しないと駄目だろ!前任者クソか!」となり今後は改善されるなどの新陳代謝も期待出来ます。また、Cassandra運用とか進行中の案件もある中、それをほっぽり出して行く事になるのを引き継ぐid:rx7先生やメンバーには感謝しています。きっとこれからはid:rx7ブログにはCassandra記事が量産される事でしょう。僕の生み出した負債を頑張って返済お願いします><

なのでサーバサイドレイヤは一旦お休みで、Android(java)とiOS(Swift若しくはObjective-C)をまずは学び、順調に行けばそれから本格的に開発業務へ・・・という予定。情報収集やらのレベルからまだ勘所分かっていないので、詳しい人は是非「こんな本読むと良いよ」「このイベントや勉強会行くと良いよ」「この人のTwitterやブログ参考になるよ」などの情報を教えて貰えると幸いです。

とりあえずJava関連は

EFFECTIVE JAVA 第2版 (The Java Series)


明解Java 入門編


パーフェクトJava (PERFECT SERIES) (PERFECT SERIES 2)


Effective Android


Androidのなかみ InsideAndroid

辺りを買ったので片っ端から読んで触って行きたいと思います。他にもAndroid系のオススメやiOS関連のオススメあれば教えて下さい(・ω<)


という訳で、一旦お休みではありますがキリの良いところではありますので、oranie datastore summit〜oranieくん Cassandra卒業会〜の幹事とお寿司奢ってくれる人を待っています。
今のところ、開発スキルが全然向上せずついていけなくてリストラされるのが一番の心配です。リストラされたら慰めの寿司をご馳走してくれる人を待っています。

MySQLのslow query logを可視化するnata2が大変便利そう

MySQL Casual #6で@studio3104さんが発表していたnata2を触った。

で、とりあえずローカルにnata2を起動しtd-agentを入れてプラグインを入れてmysqlslapを実行してみた。
動作環境はRuby2.1.2で。1.9系は動かなかった。

手順はgithubにも書かれているが、
https://github.com/studio3104/nata2
https://github.com/studio3104/fluent-plugin-nata2
以下は簡単な流れ。

まずnata2自体の設定。
git clone https://github.com/studio3104/nata2.git
cd ./nata2
bundle install

vim ./config.toml
中身は
dburl = "mysql2://test_user:user_password@127.0.0.1/nata2"
で。

次にMySQL側の設定。
/var/lib/mysql/slow-query.logを出すようにして、
mysql -u root -p
CREATE DATABASE `nata2`
GRANT ALL ON *.* TO test_user@'127.0.0.1' IDENTIFIED BY 'user_passwd';
flush privileges;
exit;
完了したら、再度nata2の設定で
bin/nata2server_init_database
bundle exec rackup

で起動する。

td-agent.confはこんな感じ。

/usr/lib64/fluent/ruby/bin/fluent-gem install fluent-plugin-nata2
でpluginをインスコして、
<source>
  type mysqlslowquery_ex
  read_from_head
  path /var/lib/mysql/mysql-slow.log
  tag slowquery.oranie.localhost
  pos_file /tmp/slowquery.log.pos
  last_dbname_file /tmp/slowquery.log.lastdb
</source>

<match slowquery.**>
  type nata2
  remove_tag_prefix slowquery.
  server 127.0.0.1
  port 9292
</match>

を設定しservice td-agent restartする。
これでちゃんとmysql-slow.logが出力され、fluentdがmysql-slow.logを読めていたら、

mysqlslap \
  --user=test_user \
  --password=user_passwd \
  --host=127.0.0.1 \
  --port=3306 \
  --engine=innodb \
  --auto-generate-sql \
  --auto-generate-sql-load-type=read \
  --auto-generate-sql-add-autoincrement \
  --number-char-cols=3 \
  --number-int-cols=5 \
  --number-of-queries=10000 \
  --concurrency=3 \
  --iterations=10

とかでゴリゴリ負荷を掛けてslowquery logを出すと

な感じでslowquery logの可視化がされていて大変便利ですね。

みんな使って色々@studio3104さんにナタを投げつけてあげると良いと思います!

nginx 1.7系である条件を元にアクセスログの出力を抑制する場合の設定

nginx 1.7系を設定している時に、まあ良くある要望でリバースプロキシの設定をしたいんだけど、アプリ側が静的ファイルを返す時にそれはアクセスログに出したく無いって設定でハマった。
初めはlocationの内部でif文書いてaccess_log offとかでやろうとすると、何故かファイル自体へのアクセスがそもそも404になる。で、じゃあ画像用のlocation切ってやろうとすると、locationの条件に正規表現を使った場合は

nginx: [emerg] "proxy_pass" cannot have URI part in location given by regular expression, or inside named location, or inside "if" statement, or inside "limit_except" block in

こんなエラーになってしまう。

じゃあどうすれば良いかと言うと1.7系ではaccess_logディレクティブに

The if parameter (1.7.0) enables conditional logging. A request will not be logged if the condition evaluates to “0” or an empty string. In the following example, the requests with response codes 2xx and 3xx will not be logged:

    map $status $loggable {
        ~^[23]  0;
        default 1;
    }

    access_log /path/to/access.log combined if=$loggable;

The following parameters configure logging to syslog:

というのが追加されていて、
http://nginx.org/en/docs/http/ngx_http_log_module.html
以下の様な設定を入れる事で設定出来た。

    map $uri $loggable {
        ~.*\.(gif|jpg|png|ico|js|css)$ 0;
        default 1;
    }
    access_log  /var/log/nginx/access.log  ltsv if=$loggable;

そもそも前のエラーになる場合の設定ミスをまだ深く追えていないので行き当たりばったり感たっぷりのメモでした。