新しい取り組み、振り返り
今回、自身でフレームワークを選定して、それについて教えながら開発に取り組むことが初めてだった為、振り返りの為にやったことをまとめて置こうと思います。
開発前に準備したこと
- どんな風に進めていきたいかを考えた
- 開発後にどんなチームになっていたいかをイメージした
- メンバーにお願いしたいことを考えた
- メンバーの現在のスキル、今後どうなりたいか、現状を踏まえて自分はどう行動するといいかを考えた
- メンバーが出来るようになると、ハッピーになることを考えた
- 実践と説明が簡単な開発手法を探して、自分で実践してみた
- 実践したことをメンバーに説明して、取り組み方のイメージを描いて貰った
- メンバーが困ったときに参照出来るように、ツールや必要に応じて手順をドキュメントに残した
- ユーザーストーリーとタスクをバックログにまとめた
開発中にしていたこと
- バックログを見ながら進捗の確認と、課題や疑問の確認をした
- 一人で出来ないことは同じ画面をのぞき込んで解決した
- フレームワークの使いながら覚えて教えること
- 難易度が高い(と思っている)事の調査、コーディングをした
やりたいけれど出来ていないこと
- 他に時間を取らざるを得ず、出来るようになってほしいことをコーディングしながら説明することが出来なくなったこと
- ミーティングの開催頻度が下がったこと
振り返って思ったこと
- 調べて出来るようになることが多い
- やり方とやることを説明した結果、成果を見られるのは素直に嬉しい
- 自分からやってくれるタイプのメンバーなので、出来るようになってほしいこと(開発手法)を説明する何か(ドキュメントとか)があると、各自の都合に合わせて開発を進められそう
- 調査に時間を要し、自分一人の開発になっている
- 調査結果を共有していない
- 全部が全部、何々をしてから説明しようーとか考えず、お願いしたら出来る事はもっとあると思う
- こうしたいんだけどーって、メンバーに相談してみたらいいと思う
今回は、折角の機会なのでアジャイルに開発を進めてみようと Visual Studio Team Services を使って開発しているのですが、形だけで一人前であまりイテレーションを回せてません。同じイテレーションにタスクを増やしちゃっているし…(^_^;)
原因は、未経験の技術(フレームワーク)を使う事に時間が掛かっていることじゃないかな?と最初考えたのですが、経験していたら上手く出来るのか?と言うと…
自分がこの状況を改善する為に出来ることを考えてみると、自分で実践して分かったら伝えるーみたいな格好つけ精神が原因なのかなーと思いました。
自分の悪癖っぽいです。
後は、管理的なこと。他のこともやりながらなので、イテレーション期間中、各タスクにどれくらいの時間をかけようかを書き出して、予実を見ていくことが大事でした。
予実が見えれば今後のイテレーションの中で最低限、必要とする時間の確保にも走れますし。
つい、時間外や時間が出来たらとー自然と考えがちみたいなので、ここは意識してやろうと思います。
こう改まると、久しぶりに振り返った気がしてきます。
来月も振り返ろう。
スレッドについて調べる為に「Javaパフォーマンス」を読んだら良いことだらけだった話
きっかけ
普段からよく利用するTomcatにおいて意図したスループットを得るためには、どうやらスレッドについて理解すると良いんじゃないかと考えがこと。
そもそもJavaのスレッドってなんなのか調べようと思い、本書ではスレッドについて言及されていた為、本書を読みました。
- 作者: Scott Oaks,アクロクエストテクノロジー株式会社,寺田佳央,牧野聡
- 出版社/メーカー: オライリージャパン
- 発売日: 2015/04/11
- メディア: 大型本
- この商品を含むブログ (11件) を見る
結局、本書からは当然ながらスレッドに関する明確な答えは得られませんでしたが、アプリケーションの開発/運用において大切なことを学んだ気がするのでまとめたいと思います。
学んだこと
全体を俯瞰する
監視対象の状況を全体的に俯瞰するためにも、まずはテスト環境でJava Flight Recorderを使ってみたいと思います。その便利さを体感できたら、本番でも利用することを進言したいと思います。
意識する指標の明確化
今までのパフォーマンステストを振り返ると、スループット、レスポンスタイムのどちらもごっちゃになったテストをしていたように思います。
今後はこれらの違いを踏まえたテストをやり直そうと思いました。
CPU100%が悪いとは限らない
高負荷状態が長時間続いたら何かの予兆だと感じるのは大切だと思いますが、その瞬間で見ると複数のCPUが全て実行されていることで100%になっている場合もあります。
対象の環境での適切な状態をCPUのコア数を把握したりすることで、実行されるスレッドがいくつになるとCPUの使用率が瞬間的に100%になるのかを予め想定した上で、異常な状態を早期検知できるようにしたいなと思いました。
JITコンパイラの役割
JavaはJavaバイトコードと呼ばれるアセンブリ言語による命令を生成しますが、CPUに依存したバイナリコードはその時点では生成されません。
これがJavaのどの環境でも動作する所以なのですが、実際にJVMが実行する際にはJust In Timeコンパイラによってバイナリコードへと最適化されます。
この最適化の方法にも種類があり、ヒープの使用方法にも関係する為これを知らずにヒープのチューニングはできないと思いました。
JITコンパイラの種類
クライアントコンパイラでは早期に全コードのコンパイルが行われます。一方、サーバコンパイラは実行されるコードのうち、よく利用されるコードを最適化対象としてバイナリコードへとコンパイルします。
よって、ヒープサイズが大きければクライアントコンパイラによって全コードバイナリコードに最適化されますが、小さい場合は途中で最適化が止まってしまうこともあるようです。
ここを知らないとインタプリタ型の言語と同様の実行方法のままになってしまう為、要注意だなと思いました。なお、以下のコードキャッシュがそれに当たります。
起動処理の最適化
起動時間のスピードが求めらる場合は、早期に最適化するクライアントコンパイラを利用すると良いです。
コードキャッシュのチューニング
コンパイルされた命令が格納される領域であるコードキャッシュサイズを調整することもできます。ここの領域がいっぱいになると本来高速に実行されるべきコードが高速に実行されなくなる場合がある為。jconsoleでコードキャッシュサイズを監視する。
ヒープ領域
メモリにはヒープ領域と呼ばれる領域があり、old領域、young領域(eden、survivor)で構成されています。一般的に、オブジェクトは生成されるとedenに話入り当てられます。ガベージコレクションが発生すると利用中のオブジェクトはsurvivor、old領域に移ります。そして、old領域がいっぱいになると未使用のオブジェクトはフルガーベッジコレクションによって破棄されるーという仕組みになっています。
Javaの基本だそうですが、本書を読むまで私は知りませんでした。読み終わってから思ったことですが、これらはJavaアプリケーションが適切にメモリを使っているかを意識、チューニングする為の基礎知識ですね。
ガーベッジコレクタの種類
スループット型ガベージコレクタ、コンカレント型ガベージコレクタがあり、前者はold領域から未使用オブジェクトが破棄される際に、アプリケーションスレッドを停止しますが、後者はフルガーベッジコレクションに近い処理を行う前にコンカレントサイクルというold領域の解放をアプリケーションスレッドと並行して実行することで長時間のアプリケーションスレッドの停止を避けることができるようになっています。
一見すると後者の方が良さそうにも見えますが、old領域の解放だけでコンパクト化は行わないので、young領域からold領域への昇格にold領域の未使用オブジェクトの解放が追いつかない場合はconcurrent ode failureに伴うフルガベージコレクションに近い処理が走りアプリケーションスレッドが停止するので、ガベージコレクタの種類に応じたアルゴリズムを把握しておくことはパフォーマンス劣化の原因分析の為にも大切だと思いました。
ガベージコレクタのチューニング
ヒープサイズの変更
ヒープサイズが小さ過ぎれば、ガベージコレクションが多発しアプリケーションのパフォーマンスは下がります。
ヒープサイズが大きくても、ガベージコレクションの時間は長くなる上、スワッピングが同時に発生するとディスクI/Oも同時に発生し、パフォーマンスは下がります。これがフルガベージコレクションと同発すると自体は最悪になる場合もあります。
この為、適切なガベージコレクタを選択することと、アプリケーションが必要とするヒープサイズを知ることはチューニングの基本となることを知りました。
並列度の指定
ガベージコレクションによって実行されるスレッド数は指定できます。また、ガベージコレクションとアプリケーションのスレッドの実行比率を指定できます。
このことから、マシンの適切な状態をパフォーマンステストで予め把握できるなと思いました。
ガベージコレクタのアルゴリズムの理解
「ガベージコレクタの種類」でも思ったことですが、アプリケーション実行環境のガベージコレクタの種類とその特性を理解した上で、デフォルトの設定によるパフォーマンスが許容範囲に収まっているかを判断するのは、一つのパフォーマンステストに当たると思いました。
実行環境、JVM自体、JVMno設定を把握しておかないと、どのタイミングでフルガベージコレクションが走るかや、その際のCPU使用率がどうなるかーなども適切なパフォーマンステストもできないなーと思いました。
ガーベッジコレクションのログ
ガベージコレクションのログを記録しておくことで、ガベージコレクションの解析を行うことができます。その中でもGC Histgramを活用するとGCによるオーバヘッドをチェックすることができるので便利だと思いました。
また、現状を抑えておけば、取得しておいたログの解析時にガベージコレクションの振る舞いが現状で想定されるものなのかどうかも判断がつくと思いました。
ヒープヒストグラムとヒープダンプ
ヒープヒストグラムではヒープに存在するオブジェクトのヒストグラムを表示してくれます。この為、無駄に生成されているオブジェクトの発見や、ガベージコレクションが頻発する原因の分析に役立てられることを知りました。
また、解析にはその状況を再現する必要がある為、予めヒープダンプを取得しておくと良いということも学びました。
ヒープを非効率に使用するようなアプリケーションになっていないかどうかをチェックして改善するためのテストにも使えるなーと思いました。
ただ、オブジェクトの生成元を辿っていくのは大変みたいですが…
OutOfMemoryError対策
メモリリークやヒープ領域を使い尽くしていることが一つの原因として引き起こされるエラーですが、メモリのサイズが問題なのか、アプリケーションロジックが問題なのかを適切に状況把握する必要があることを知りました。
というのも、適切にメモリを使用するようにプログラミングされたアプリケーションに対して用意されたヒープのサイズが小さいだけといった単純な場合から、コレクションのように自動的に解放されないコレクションが残り続けるようなケースもあり、アプリケーション側で対応しなければならない原因もあるためです。
このようなケースについては、生成するオブジェクトが参照されなくなったらガベージコレクタに解放されるように参照状況を制御する必要があることを知りました。
オブジェクトの参照の仕組みを理解して、アプリケーション開発時のコードレビューするポイントとしたいなと思いました。
Javaアプリケーションの合計メモリ使用量
これはネイティブメモリとヒープの使用量を足したものです。
Javaアプリケーションの実行環境におけるメモリサイズと合計メモリ使用量の関係もスワッピングの発生によるパフォーマンスの低下と関係するため大切です。
まとめ
結局、本書からはスレッドとは何かーという本来知りたいことを調べることはできなかったのですが、Javaアプリケーション/利用するプログラムの動作原理を理解することの大切さについて気づかせてもらえたので、棚から牡丹餅だったと思います。
おかげで、今後こんなことをしていきたいなと思いました。
- パフォーマンスに関する要件定義、作り込み方の見直し
- アプリケーションのコードレビューの見直し
- アプリケーションパフォーマンステストの実施方法の見直し
- アプリケーションサーバ、アプリケーションの監視方法の見直し
また、今回の学習を通して調べたクラスローダーについて、こちらのサイトから以下のようなことも学ぶことができました。
IBM developerWorks 日本語版 : クラスローダーとJ2EEパッケージング戦略を理解する
- JVMが使用するメモリの構造(Permanent領域)
- クラスローダの働き・目的
- Webアプリケーションのクラスローダの仕組み
- JavaEEアプリケーションのパッケージング戦略
- サーブレットが参照するメモリ
後日談 ースレッドについて理解できた話ー
後日、Twitterで「JVMについてもっと知りたいなー」とつぶやいたら、親切な方が以下のドキュメントの所在を教えてくれました。
The Java® Virtual Machine Specification
これを読んだおかげで、次の情報を調べる糸口を掴むことができ、Javaのスレッドとスレッドとは何かーについて理解することもできました( ´ ▽ ` )
JVMのスレッドについて
Threads may be supported by having many hardware processors, by time-slicing a single hardware processor, or by time-slicing many hardware processors.
Threads are represented by the
Thread
class. The only way for a user to create a thread is to create an object of this class; each thread is associated with such an object. A thread will start when thestart()
method is invoked on the correspondingThread
object.
上記から読み取ったこと
- プロセッサがサポートするスレッドを作る為に、スレッド実装者がJavaのThread.classのオブジェクトを生成する。それを起動するにはstart()メソッドを使うーということ
- スレッドはJava固有の概念じゃなくてハードウェアに依存するものであるーということ
プロセッサがサポートするスレッドについて
プロセッサがサポートするスレッドをJavaで制御する様子
こちらの記事を見つけたおかげで、マルチスレッドはプロセッサ、OSがサポートするもので、それを利用する為にJavaプログラマはThread.classを利用してマルチスレッドを実現できるということを理解しました。よかったよかった。
結構な回り道になりましたが、Servletコンテナで意図するパフォーマンスを得るための勉強に今回学んだことを生かしたいと思います。
Pitalium を使って回帰テストを実践した時の話
はじめに
今回は12/18 に発表した「キーワード駆動テスト」の実践の中で利用したPitalium を使って、回帰テストを実践した時の話をします。
キーワード駆動テストシステムを構築した時は、マルチブラウザテストを並列実行するーというロールを委譲する対象としていました。
しかし今回は、並列実行以外にも任意のテストのデグレードを検知するーというロールの委譲先としても活用しました。
次節ではその時の考え方や実践内容について整理した話をします。
Pitalium を使って回帰テストを実践した時の話
まとめ
スライドではPitalium はもとより、ツールを理解するときのポイントと、ポイントを押さえる事で実現したいことを具体的に明らかにできることを示しました。
Pitalium はとても素晴らしいプロダクトだと思います。本スライドが少しでもPitalium を利用しようとしている人の役に立ち、ひいてはPitaliumの利用者拡大に繋がれば幸いです。
Selenium でキーワード駆動テストを実践したときのあれこれ
この度「第4回 日本Seleniumユーザーコミュニティ勉強会」で発表をさせて頂くことになりました。
日本Seleniumユーザーコミュニティの皆様、貴重な機会を頂きありがとうございます。
振り返れば10ヶ月
右も左も分からない状況ながら、今年2月3日に開催された第3回の勉強会に運良く参加をさせて頂くことが出来ました。
その時感じた日本Seleniumユーザーコミュニティの皆さんの温かさ、知識、そして私自身の興味を追い風に、約10ヶ月の間様々な方に助言を頂きながら次のことに集中して取り組むことができました。
- テスト
- キーワード駆動アプローチ
- システム開発手法
10ヶ月の成果
お陰様でこの10ヶ月間で取り組んだ成果を皆さんにお伝えする準備が整いました。
まだまだ足りない部分はありますが、この機会を利用させて頂いて一区切り付け、また次に向けて残る課題や新しい事にに取り組んでいきたいと思います。
今後も皆さんから力を借りることが多々あるとは思いますが、逆に私もこのような場やWebを通してお役に立てればと思います。
今後ともお付き合いの程、よろしくお願いいたします。
Selenium Serverをサービス化した時の話
はじめに
Selenium関係の情報をネットで検索すると「Seleniumを使ってー」、「Seleniumによるー」等といったキーワードをよく見かけます。
今回の記事では私も最初は次のようなタイトルを考えていました。
「Selenium をバックグラウンドサービスとして動かす方法」
"Selenium"と一口に言うけれど
今回のスライドを作る中で、W3C WebDriverのドキュメントを読んだり、
上記の記事を読むうちに、自分が言う"Selenium"って何を指すんだ?と疑問に思うようになりました。
本スライドの"Selenium"
本スライドでは"Selenium"という曖昧な表現はなるべく避け、"Selenium Server"という表現を用いました。
これは、"Selenium"が「プログラミング用のライブラリである"selenium-java"等」のことを指していたり、「WebDriverに定義されている"JSON Wire Protocol"に基づくHTTP通信の送受信をサポートするサービス」を指していたりする場合があるためです。
"Selenium"というキーワードに関して、この2点を抑えておけば混乱しないと思います。
Selenium Serverをサービス化した時の話
以上の前提を踏まえて、ご覧いただければと思います。
皆さんの自動テスト実行環境構築に役立てて頂ければと思います。
また、今回のスライドが便利な機能を提供してくれているJava Service Wrapperの今後の継続開発に何らかの形で貢献できればとも思います。
こちら会社に所属していたり、利害関係があるわけでもないのですが、純粋に大変便利なツールだと思うので多くの人に使われ続け、私も使い続けることができればいいと思っています(*^_^*)
スライド形式なので、説明不足な点があるかもしれませんが、何か気になる点、ご質問があればコメント頂けるとうれしいです。
テストを自動化したい人のための、テストランナーの選び方
はじめに
『自動テスト』というと、テストを自動で上手いことやってくれる印象を受ける方もいるかもしれません。
というのも、Selenium を知った頃の私がそんな感じだったからです。
当時の私はテストに苦手意識を持っていたので、「Selenium という夢のようなアプリケーションがあるらしい!」ーと勝手に思っていましたσ(^_^;)
自動テストシステム開発解説文献の有り難み
JUnitやTestNGといったテストランナーを実装したツールを知らない初心者の方が純粋なSelenium 本を最初に読むと、「たくさんあるテストケースをどうやって実行するのだろう?」「ループ文で繰り返すのかな?」なんて疑問に思うでしょう。(私だけかな?(^_^;))
はじめて間もないころにツールを使ったテストの実行方法を紹介した文献や実践してる人に出会えると良いのですが、そう上手くはいかないこともあるでしょう。
テストランナーの選び方
そこで、今回は私の経験を交えてその辺について整理しましたので、同じような悩みを抱える方は参考にして頂ければと思います。
やや物足りなさがあるため、今後追記するために余白を残しました。
JUnitやTestNG以外にも比較したり、TestNGのコードを掘り下げてみたりすることがあると思いますのでご容赦ください。m(_ _)m
Selenium でキーワード駆動テストを実践したときのあれこれ 『まずはやってみた編』
はじめに
12/18 Selenium 勉強会4で予定しているセッションの冒頭の話をします。
勉強会では、本編で浮き彫りになった改善点に取り組んだ話を、『リファクタリング編』として銘打ち、掘り下げて話す予定です。
それぞれ状況が異なれば、様々な見解があると思います。
セッションとうまく話が繋がればセッション内で言及したり、合わなくても後日お話をさせて頂きたいと思いますので、よろしければコメントください。
Selenium でキーワード駆動テストを実践したときのあれこれ まずはやってみた編
リファクタリング編との繋がりを考慮し、スライドによる投稿で失礼します。
※ 駆け足で資料を作成した為、後で手直しするかもしれないです。
すみません m(_ _)m
まとめ
最後のスライドの繰り返しにはなりますが、 はじめてみるとひとりの取り組みでさえも、様々な要求が湧いてきます。
これらをクリアする為に取り組んだ内容を、別日のアドベントカレンダーや勉強会4での『リファクタリング編』で紹介しますので、しばらくお待ちください(^ ^)