Chonaso's Commentary

InternetやIT技術などについて知ったこと、試したこと、考えたことを書いていきます。

近況など(2017年末)

今年夏ごろに異動しましてグループ会社で働いています。 転職後、配属部署→グループ会社に出向→帰任、からの出向なので新卒入社を会社から通算して感覚的には5社目です。

それまでは新規事業のシステム担当でした。 ロクに要件も無い中から開発1年でローンチ、その後も膨大な数のシステムを作り続け、膨大な数の障害連絡をもらいました。 結果5年半携わりましたが自分の中では最長記録です。

今回は初めて自分で希望を出しての異動です。 元々B2C志望だったのにいつの間にかどっぷり基幹/業務システムに漬かってしまっていて、いいかげん軌道修正したいという思いがありました。 あと体調面。はっきり言ってしまえば電通顔負けのブラック部門だったのでこの最初の3~4年で心身共にだいぶやられてしまっています。 最近は親会社の強い圧力でオフホワイトくらいにはなっていると思います。

そもそもローンチさせたらすぐ抜けられると思っていたのですが、先に周りが脱落していくという状況だったため自分の中でいいタイミングがつかめませんでした。 そこで「この事業が黒字になったら辞めよう」と決めていました。自分の中のケジメみたいなものです。 そしてようやく昨年度に黒字がほぼ決定的になったので異動の希望を出しました。 自分が携わっている事業がブレイクイーブンに到達したのは初めてですが、思ったほど感動はなかったです。 (その前の事業は債務超過状態からの参画でしたが黒字転換の1か月前に帰任でした)

異動については強制力のある制度を使ったので異動自体は上手く行きました。 思えばこれまで社内やグループ会社からのオファーは私に降りてくる前に全部潰されてるんですよね。 社内ハックとしてこの制度をうまく使えばよかったなとかなり後悔しています。

異動の際、上司に「ここで得たものはあるのか」と聞かれ、答えに詰まってしまいました。 技術的な部分は誰かから教わったものはほぼ無く、やっていく中で自ら勉強して身に付けたものばかり。 強いて挙げれば業務システムを作る上での経験則でしょうか。 今思い返すと細かいレベルでは色々ある気がします。

というよりも、社会人になって以来何か直接的に教わったことはほとんど無く、ただひたすら試行錯誤と実践の場を与えてもらっただけだなぁ、と改めて感じました。 もちろんそれだけでも恵まれているとは思います。

で、今はとあるスマホ向けゲームの会社でゴリゴリPHPを書いています。 同年代は少ないですが、周りはオタクばかりで楽しいです。

プロジェクト管理や定例MTGなどは無く、1日中コーディングしてるなんて新卒の時以来かもしれません。 PHP自体はPHP4の時代に仕事でちょろっと書いていたくらいなので、ほぼゼロから始めたようなものですがなんとかやれています。 さすがに数か月PHPを触っていると思うことも色々あるのでそのうちエントリにしたためたいと考えています。

JJUG CCC 2017 Spring #jjug_ccc に行ってきました

ここ1年、業務へのモチベーションが全く上がらず、それにつられて業務外での情報収集も怠っておりました。

環境も変わる兆しが見えてきたところで少しはモチベーション上げていかないとなぁ、ということで刺激を求めてJJUG CCC 2017 Springへ参加してきましたので感想などを。

スライド関連はまだ出そろっていないようなので、随時補完していきます。


#ccc_c4 Unified JVM Logging: Java 9 から変わる JVM ログ

Java 9にはJVMログ出力の新オプションである-Xlogオプションが追加されるという話です。

JVMログ、といっても個人的にはGCのログくらいしか扱ったことがないですが、 人に説明するにも難儀するあのGCログが読みやすくなるようなら良さそうですね。 過去記事でもGCログをパースしてメモリリークの検出する、みたいなことを書いてますが、 「とはいえGC設定変えるだけで書式変わるしパーサ書くのつらいんですが」みたいなことを言われても「仕方ない」の一言で済ませてましたし。

-Xlog[:[what][:[output][:[decorators][:output-options]]]]

  • what:出力項目
    • tag:ログ種別(カテゴリ)
    • loglevel:debug,infoなど
  • output:出力先
  • decorator:ログ行頭に出力する情報(日付など)
  • output-options:ローテーション設定など

どのタグを出力するか、という設定は論理式っぽいもので指定するのですが、 -Xlogは複数書けるので種類ごとにファイルを分けちゃった方がわかりやすいんじゃないかなと思った次第。

あと、jcmdでログ設定の変更や強制ログローテート可能、ログ内でpauseを含む行に記載されている秒数はいわゆるstop the world状態とのこと。


#ccc_g5 Introduction of Project Jigsaw

Java 9に組み込まれる(かどうか不明になってしまった)注目機能。 仕様検討自体はずいぶん前からあったわけですが、Java 9になっていよいよ組み込まれるということになっています。

Javaでは関連するクラスファイルをJARファイルにまとめることである機能毎のライブラリとして管理していますが、 JARファイルの連鎖的な依存関係、パッケージ内クラスのスコープの制約(どうしてもpublicにせざるを得ない問題)が運用上の課題です。

このソリューションとしてModuleという新概念が作られました。

  • module-info.javaにrequires(依存パッケージ)とexports(公開するパッケージ)を記述
  • jarコマンドでmodule化(suffixは.jar)
  • Javaランタイムも機能グループ毎にモジュール化される
    • jlinkコマンドで任意のモジュールのみを含めたオリジナルJREが作れるようになる
    • 既存のスコープにも影響が出てくる。リフレクション系など
  • 既存のJARファイルは一定ルールに乗っ取って自動的にmoduleのように扱われる

逆にmoduleをJARとして扱われた場合にはおそらくスコープ等は関係ないことになってしまいますね...

ところがこのJSR376 JigsawはJavaコミュニティの投票でNGとなってしまいました。 (Jigsawが含まれるJSR379 Java9がOKにもかかわらず、です)

ざざっと話を聞いた限りでは拙速感は否めず、NGを出されたのも理解できます。 (元々の問題の全てを解決できてない部分もあるような…)

あと、最新版では以前あったオプションや機能が変わったりオミットされていたりするようで、 数か月前以上の記事等はあまりアテにならない部分が色々出てきているようです。

そもそも今書いているこの内容すらウソの可能性もありますが…


#ccc_c6 劇的!データベース・ビフォーアフター 時代はディスクからインメモリーへ――

10年くらい前にOpen terracottaが話題になったなぁ、というのをふと思い出しました。 (あの頃は多くの人が「アレ面白そうだよね!」で終わっていた気がします)

RDBMSディスる体でのプレゼンでしたが、インメモリデータグリッドの効果的な適用シーンの紹介という内容です。 NoSQLに置き換えても文脈がかわらない内容なので、NoSQLとの比較が欲しかったと個人的には感じました。 (この内容でもNoSQLより速そうだというのはわかるんですが)

  • 複数VM間で同一Mapオブジェクトを共有するイメージ
  • メモリが主、RDBMSがバックアップ(非同期で書き出す)
  • データは複数台で冗長して保持、1つが落ちても自動的にPrimaryが移行・他にバックアップ作成
  • キャッシュミスしたものはDBから取り出すことで大容量データに対応
  • 高速処理が可能、スケールアウトが可能
  • Spark+HDFSにおいてspark workが多いときのメモリ利用効率向上
    • ダブったデータが集約される
  • SQLライクなクエリはRDBより遅い

SparkとHDFSの間に挟めるというのは面白い活用だと思いました。 他のクラスタを組むJavaプロダクトへの活用もありそうですね。

成功事例を聞くと明日からコレ使うわwwwみたいな感じになりがちですが 遍く全てのアプリがインメモリへマイグレートしていくことはなく、 現実的には効果的な部分に適宜適用していく形になるのでしょう。

細かいところですと、開発においてはVM立ち上げた直後のデータはどうしているのか、 プレゼン中では表面だけ説明したトランザクションの中間処理はどのように解決したのか、 この辺りが気になるところです。

Doma勉強会 in 東京に行ってきました #doma_tokyo #eventdots

DomaJava のDBアクセスフレームワークです。(Welcome to Doma — Doma 2.0 ドキュメントより)

私が仕切る案件では基本的にDomaを使っています。 部門的にはSeasar2+S2JDBCがスタンダードでしたが、Seasar2が公式アップデートはぼちぼち終了になるので、 今後の案件はおそらくSpring+Domaという組み合わせになるでしょう。

ちなみに私がDomaを選んだ理由は以下の通りです。

  • JavaコードとSQLを完全分離できる
  • SQLを知らないと使えない(強く意識させる)
  • 2Way SQLが使える
  • 特定のフレームワークにロックしない
  • 多くのRDBに対応している

また、実際に使っていてよいと感じた点が以下の通りです。

  • 静的チェックが強力
  • SQLJavaコードの行き来が簡単
  • ドメインクラス機能が超便利

では本編。主に感想です。

Domaの紹介

http://backpaper0.github.io/ghosts/doma-intro.html

  • Domaの機能の紹介ですが、Domaは結構ハイペースでバージョンアップを続けていてフォローしきれていない機能(Embeddableなど)があったので、改めて勉強になりました。
  • EntityListenerでDIってよさげですね。たぶん今度使います。
  • どこかで発表があったかもしれませんが、doma-genなどの細かい(深い)話も聞いてみたいなぁ、と個人的に思いました。

ドメインクラスの話

http://backpaper0.github.io/ghosts/doma-domainclass.html

  • Domaという名前の由来でもあるドメインクラスの話。
  • ドメインって意味が広すぎてつらい、っていう意見ももっともですが、仕方ないですね。
  • 私の身の回りではDomaのおかげで「Enum値をgetValueして比較する」みたいな悲しいコードが無くなりました。
  • 「どこまでドメインクラス化するか」問題は皆共通の悩みだったようです。設計書にドメイン一覧とか書く案件だったら全部クラス化してもいい気がしますね。

とあるDoma2の使い方

http://gakuzzzz.github.io/slides/doma_practice/

  • 関数型ゴリゴリなDoma2の使い方。Java8 Stream APIを理解していない人は見ても仕方ないスライドです。逆に理解している人にとっては非常に面白い教材ですね。
  • というかDoma 2 素案 · GitHubで見かけたやり取りに対するアンサーだなぁ、と思ったら発表者はコメント付けた方でした。
  • IN句、NOT IN句にNULL入れた時の挙動って調べたこともなかったなぁ。

Domaの開発で大切にしている10のこと - Qiita

http://qiita.com/nakamura-to/items/099cf72f5465d0323521

  • Doma開発者の中村さんの発表。Domaの開発ポリシーについてです。
  • さりげなくJPA以外のCriteriaフレームワークにフォローを入れつつも、どの程度Criteriaを使うか、に対する一つのアンサーとも言えます。
  • 個人的には概ね同意というか、S2DAOからS2JDBCに移ることに納得のいかなかった人々へのノアの方舟といった感じです。
  • 逆に全体的に同意しかねる!っていう人は他のフレームワークに移った方がいいかもしれない、そんな内容です。(この辺りは唯一の正解は無い話ですね)
  • 実は私もツイートを拾ってもらって、Domaに反映されたことがあります。(たまたまリリース候補と合致してただけかもしれません) https://twitter.com/chonaso/status/683506363553583104

(LT)Doma2とMVC1.0でJava EE Webアプリを作ろう! // Speaker Deck

https://speakerdeck.com/masatoshitada/doma2tomvc1-dot-0dejava-ee-webapuriwozuo-rou

  • SpringBoot with Doma2対抗のPayara Micro with Doma2。
  • Domaとは全然関係ないですが、JerseyMVCじゃなくMVCでもいいかもね、ってちょっと思いました。

(LT)Doma2 with Kotlin

http://www.slideshare.net/yyyank/doma2-with-kotlin

  • Kotlinって正直ほとんど言語仕様をフォローしていないんですが、KotlinがサポートしてるのってJava6なんですね...
  • Kotlin関係ないですが、Domaって手軽にJDBCを使うツールとしても使えるんだなぁと認識させられました。

その他質問など

  • Q:せっかくなのでちょっと気になってた件。

    A:データソースごとにパッケージ分けた方がいいです。

  • あの場では特に聞かなかったですが、ドメイン使いだすとありがちな「DAOメソッドをオーバーロードしたい」問題って私だけですかね?

まとめ

  • Domaを好んで使う人たちの集まりだけあって「Doma最高!」連呼の若干宗教じみた雰囲気を感じました。
  • 今回発表されたスライドではないですが、これも面白いです。

Domaで複数データベースを扱う

きちんと探せばサンプルありそうな気がするんですが、こんな感じで解決しました、という一例として残しておきます。


Domaを使い始めて2年以上経ってるはずなんですが、振り返ると複数データソースは初めてでした。

daoやentityのパッケージングはどうしたものかなぁ、という課題を残しつつもとりあえず2つのデータベースを同時に扱えるようにConfigクラスやbuild.gradleを2つ準備してDoma-genまで上手く行ったのでアプリ起動!

と思ったらエラー。

org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [org.seasar.doma.jdbc.Config] is defined: expected single matching bean but found 2: HogeDatabaseConfig,FooDatabaseConfig

まだSpringは慣れてないけど、DI候補が2つあるからDIできないぞ、と怒られているというのは何となくわかりました。

問題の箇所はDAOから生成されたクラス(XxxDaoImpl)内のコンストラクタで、ConfigをDIしようとしている部分です。

    /**
     * @param config the config
     */
    @org.springframework.beans.factory.annotation.Autowired()
    public HogeDaoImpl(org.seasar.doma.jdbc.Config config) {
        super(config);
    }

DBが一つなら型インジェクションが普通に決まるので問題無く動くのですが、 エラーメッセージにあるHogeDatabaseConfigとFooDatabaseConfigはそれぞれorg.seasar.doma.jdbc.Configを実装したクラスなので確かにこれは動かないですね。

ってことで、それぞれのConfigクラスに名前を付けて、 DAO側では@Qualifierでその名前を指定するようにしました。

その結果、自動生成部分はこのようになりました。

    @org.springframework.beans.factory.annotation.Autowired()
    public HogeDaoImpl(@org.springframework.beans.factory.annotation.Qualifier("HogeDatabaseConfig") org.seasar.doma.jdbc.Config config) {
        super(config);
    }

これできちんと動いたので、doma-genのdao.ftlも修正しておしまい。


追記

確かに!

ということで修正しました。

S2DBCPのコネクションプール状態の取得

今さらSeasar2関連です。 HikariCPのデバッグログではコネクションプールの状況を逐一ログに出してくれるのですが、 S2DBCPはそういう機能が見つからなかったので作ってみました。

SAStrutsのアクションとして実装しています。

一つのアプリで複数のプールを使うこともありますので、全部出すようにしています。

Zabbix アクションが発動しない時にチェックする項目

自分用メモ。徐々に追記していきます。

  • アクションが発動しない(メールが飛ばない、など)

    • アイテム
      • 正しく取得できているか
        • 有効/無効
        • 実行間隔
        • 種別は正しいか(数値、文字列、ログ...)
    • トリガー
      • イベントが発生しているか
      • (ログの場合) ステータスが正常状態か or 「障害イベントを連続して生成」にチェックがついているか
    • アクションの条件
      • 有効/無効
      • トリガー(深刻度)
      • アイテム(アプリケーション)
    • ユーザ
      • メディア(深刻度)
      • ユーザグループ
        • 有効/無効
        • 権限
          • ホストグループ
          • テンプレートグループ

これらの掛け合わせなので、どれかが間違ってるとアクションは発動しません。

Zabbix難しいよ、って言う人はこの辺の理解でつまづいているように見えます。

理解できてもなかなかサクッと発動してくれなかったりするんですよね。何かいいテスト・デバッグ方法はないものでしょうか。

Bootstrapのbtnとdisabled

BootstrapのCSSを適用するとbutton以外のタグでもボタン化することが可能です。 さらにdisabledなどの状態も含めたCSSがセットになっているのでデザインにこだわらないWebアプリを開発する際には非常に重宝します。

これにAngularJSのng-clickやng-disabledなどを組み合わせることでお手軽にUIパーツが組めるのですが、どのタグにボタンを適用するかをその場のフィーリングで決めていたら軽く痛い目に遭いました。

具体的にはAタグをボタン化していたものについて、ng-disabledが効かずクリックできてしまうというものです。

ng-disabledが効かないというのは半分間違っていて、見た目上はdisabledなのですがクリック出来る状態で、見ただけじゃ気付かない罠でした。(マウスオーバーでカーソルも禁止マークになります)

サンプル http://plnkr.co/edit/sDYTmQFBUdc9VcxSw0BZ?p=preview

class="btn"はdivやspanでも使えますが、やっぱりクリックが発動します。