JSUG勉強会 2019その6 Spring IO 報告会 に行ってきた #jsug

JSUG勉強会 2019その6 Spring IO 報告会に行ってきました。簡単に所感をまとめます。

jsug.doorkeeper.jp

所感

最近はレガシーなシステムのお守りに追われて新しい情報を追えてなかったので、いろいろと新鮮な情報がいっぱいでした。

とはいえ、なかなか Reactive なシステムを開発する機会がなく、RSocket や R2DBC などは未だに試せていない状態です...。GraalVM とかかなりホットな話題なので素振りしておきたいところ。以前、ちょっと触ってみた Micronaut あたりで GraalVM を試してみようか。もしくは Quarkus あたり?

あと、Moduliths はなかなか面白そう。アーキテクチャをテストできるという意味では、JJUG CCC 2019 Spring で紹介されていた ArchUnit と近いものがあるんだろうか。

JJUG CCC 2019 Spring に行ってきた #jjug_ccc - kntmr-blog

以下、メモから抜粋。

Spring Framework のロードマップと 5.2 の新機能

  • Spring 5.2 は 9/4 GA に延期
  • 5.x で取り入れた機能のアップデートがメイン
  • Reactive API
    • RSocket (マイクロサービス間の通信)
    • R2DBC (RDBMSへのリアクティブアクセス)
  • R2Socket
    • L7のバイナリプロトコル (HTTPと同じレイヤ)
    • Reactive Streams (Backpressure)
    • 4つのインタラクションモデル (片方向/双方向、Mono/Flux)
    • spring-boot-starter-rsocket
    • @MessageMapping
  • R2DBC
  • Reactor のデバッグ出力を改善
    • トレース生成のコストは高い
  • 関数型 API の整備
    • Router Function が MVC で使える
  • Spring 5.3
    • JDKアップデートに追従 (13-15)
    • Code Analysis Annotations
      • @Nullable
    • GraalVM
  • Spring 5.x で対応されないもの
    • Java 11 ベース
    • モジュールシステム
    • Jakarta EE (javax パッケージ?)
    • Project Loom

Spring 5.2 の Kotlin 対応

  • Coroutine 対応
    • WebFlux 向けの機能をサポート
    • ReactiveX に替わるものではない
    • Reactive と Coroutine は同じように使える
  • Spring Kofu
    • Experimental
    • Functional Configuration
    • アプリ起動の高速化、省メモリ

GraalVMの概要と、Native-Image化によるSpring Boot爆速化の夢

  • Graal コンパイラ
  • Truffle
  • Native Image
  • 現時点ではそのまま Spring Boot アプリを Native Image にはできない (制限が多い)
    • リフレクションや Dynamic Proxy で動的なクラス生成を多用しているため
  • Spring 5.3 で Native Image に正式対応予定
  • 今のところ Native Image のビルド時間は非常に長い

Spring Cloud Netflix

  • ほとんどがメンテナンスモードに
    • 脆弱性やバグfixは Pull Request で対応
  • Ribbon ⇒ Spring Cloud Load Balancer
  • Eureka ⇒ Spring Cloud Zookeeper
    • メンテナンスモード対象ではない
    • 移行パスを検討中
  • Zuul ⇒ Spring Cloud Gateway
  • Hystrix ⇒ Spring Cloud Circuit Breaker + Resilience4j
    • アノテーションが不要に
    • Circuit Breaker は様々なサーキットプレイカーを使えるように抽象化したもの
  • Hystrix Stream, Turbine, Hystrix Dashboard ⇒ Micrometer + Prometheus
    • メトリクス情報を収集して監視ツールにエンドポイントを提供する
  • Archaius ⇒ Spring Cloud Config Server
    • そもそもアーキテクチャが違う
    • Archaius は各サービスがプロパティを取得するためのエンドポイントを提供する
    • Config Server は各サービスにプロパティを配布して起動時にロードさせる
  • マイクロサービス開発を担うプロダクトは多い
    • 今後、統廃合があったりするかもしれない

Spring Boot で作るいまどきなモノリス

www.slideshare.net

  • Modular Monoliths
  • Moduliths
  • パッケージをモジュールで分割する (ドメイン)
  • main がある階層のパッケージがモジュールになる
  • モジュール間のDIを避ける
    • EventListener で依存モジュールに Event を送る
    • @DomainEvent
  • Bootstrap Modes
    • Standalone, Direct dependencies, All dependencies
  • モジュールのパッケージ直下に配置したクラスは他モジュールに公開される
    • サブパッケージ配下のクラスは他モジュールには非公開
  • 相互依存をチェックしてエラーにしてくれる
  • Documenter
    • モジュールの関連グラフを作ってくれる (PlantUML)
  • Java のモジュールシステムと関係があるものではない
    • Moduliths はテストをサポートするもの

Postman の GraphQL を試してみる

気が付いたら Postman が v7.2 で GraphQL に対応してました。

blog.getpostman.com

まだ Beta 機能のようですが、手元の v7.2.2 で試してみます。とりあえず、GitHub の GraphQL API で。

事前に、GitHub 側で Settings > Developer settings > Personal access tokens > Generate new token からトークンを生成します。とりあえず、スコープは repo あたりをチェック。

で、Headers タブで Authorization: bearer <token> を追加。Body タブで GraphQL をチェックして、https://api.github.com/graphql に POST するとレスポンスが返ります。

f:id:knt_mr:20190624124851p:plain

あと、左ペインの APIs でスキーマを設定できます。

f:id:knt_mr:20190624125250p:plain

ここでは、GitHub の graphql-schema を設定してみます。

github.com

GraphQL の右隣りにあるプルダウンでスキーマを選択すると、GraphiQL のように自動補完ができるようになります。

f:id:knt_mr:20190624130752p:plain

なかなかいい感じ。

「ふりかえり」をどのようにやるか

システム開発の現場において設計レビューやコードレビューをすることはよくあるかと思いますが、チームや自分自身の仕事を 継続的に改善する ために取り入れたいことのひとつとして「ふりかえり」があります。

で、ふりかえりのツールとしてよく取り上げられるのが「KPT」です。以前から実践しようと思いつつなかなかできてないのですが、実際に取り組んでみることを想定して方針などをまとめてみようかと。

前提

  • 「今回は○○を試す」など、事前に目標を決める
  • 前回の Try があるなら、それを目標に含める

Keep

  • 試してみてよかったこと
  • これから続けたいこと

単純に「○○がよかった」だけではなく、なにがよかったのか、どのような効果があったのかを併せて書く。現在形で書くとよさそう。

Problem

  • 試してみてだめだったこと
  • 不満点や問題点
  • これからリスクになりそうなこと

単純に「○○しなかった」だけではなく、なにがだめだったのか、どんな問題があったのかを併せて書く。あと、あたりまえだけどメンバーを否定するようなことは書かない。

Try

  • Keep を強化すること
  • Problem を解決すること

具体的 (定量的) なアクションを書く。次回の KPT で Keep のふりかえりをするために期待する効果を書くとよさそう。

参考記事

kuranuki.sonicgarden.jp

boxil.jp

BPStudy#141〜DDD(Domain Driven Design)実践の現場に行ってきた #bpstudy

BPStudy#141〜DDD(Domain Driven Design)実践の現場に行ってきました。簡単に所感をまとめます。

bpstudy.connpass.com

所感

最近、価格計算のロジックを実装する機会があり、個人的にはなかなかホットな内容でした。とはいえ、自分の場合は特にドメイン駆動設計という感じではなかったのですが、価格計算のロジックはアプリケーションのレイヤから分離するようにしました。で、今回の話を聴く限りではこのアプローチ自体はあまり間違いではなかったのかなとなんとなく実感を得られました。

あと、モジュールやメソッドの切り方を考えるときに個人的に意識していることはテストがやりやすいかどうかということ。特に、モックを多用せず、シンプルにテストコードが書けるかどうかは重要かなと思っています。なので、今回の事例として挙げられていた「料金計算ロジックをどうやってコードで表現するか」ということに関して、テストがやりやすいかどうかという観点で考えるのは割とありなのかなと思っている今日この頃です。

そういえば、増田さんの本は読んだことがあるけど、エヴァンスの本は手が出しづらくてまだ読んでない...。そろそろ読んでみるか。

現場で役立つシステム設計の原則 ~変更を楽で安全にするオブジェクト指向の実践技法

以下、メモから抜粋。

ドメイン駆動設計の正しい歩き方~どこに焦点をあわせ、どう実践するか

www.slideshare.net

  • ドメイン駆動設計はアーキテクチャや設計に限った話ではない
  • ソフトウェアの核心にある複雑さに立ち向かう
  • 複雑さはビジネスの複雑さに起因する
    • 複雑になる要因はたくさんある
  • ビジネスルール
    • 制約や約束事 (システムやITは関係ない)
  • ドメインロジック
    • ビジネスルールをシステムやソフトウェアとして実現するもの
  • 核心にある複雑さを適切に扱う
    • 周辺の複雑さが整理される
    • 条件分岐を外に抜き出すと入出力は単純になるはず
      • 分岐が散在するから複雑になる
    • 全体の構造が改善する
  • ドメイン層を独立させる (アーキテクチャの話)
  • ビジネスの活動を継続的に学ぶ☆
  • コアドメインに集中することにどれくらい時間を費やせるかがポイント☆
  • 個人ではなくチームの基本方針としてやっているか☆
  • 全体を均質にやるのではなくポイントを絞って深掘りする
    • 複雑なものを整理して単純なIFで使えるようにする
  • ドメイン層に入出力の関心事(画面やテーブル)を持ち込まない
  • モデルと実装は切り離さない
    • 実装のためにモデリングする
    • コードをうまく書くにはどのようにモデルを整理すればよいかを意識する
  • 例) 複雑な料金計算ルール
    • ドメインロジックを独立させる
    • 画面やDBのことを一緒に考えない
  • モデルで整理してモデルと実装を密に結合する
    • ルールを整理する
    • モデルで仮説を立ててコードで実現してみる
    • コードのリファクタリングとモデルへのフィードバックを繰り返して改善する☆
  • コアドメインに集中する
    • ある軸を選んで簡単なコードを書く、別の軸で簡単なコードを書く☆
    • 実験することでモデルの妥当性を検証する
    • 中核のルール、周辺のルール、除外すべきルール
  • ビジネスを深く洞察する
  • システム間の秩序の改善を続ける
    • 連携するシステムや人間を意識する
    • どのようにデータを持つべきかがわかってくるはず
  • ドメイン駆動設計を現場に導入する
  • ドメインエキスパートがちゃんと説明してくれるとは限らない
    • 具体例を提示して質問する
    • あえて間違っていることを質問して語ってもらうのもあり
    • バックオフィスの人の方がルールを知ってるかも (経理のベテランや営業支援スタッフとか)

教材セット

www.slideshare.net

モデル駆動型開発によるビジネスをソフトウェアに落し込む1つのやり方

  • モデリング
    • モデルを作ることで分かりやすくする
  • ビジネスとソフトウェアは乖離する
    • モデルを中間成果物としてビジネスとソフトウェアを繋げる
  • モデル駆動型開発(MDA)
    • CIM, PIM, PSM, CODE ☆
  • 言語の抽象度は上がっている
    • プラットフォームの複雑さから分離する
  • モデル駆動開発のいいところ☆
  • 言葉を共有
  • 言葉の乖離
    • ドメインエキスパート⇔開発者
    • 開発者による抽象化は設計の支えにはなるがドメインエキスパートには理解されないかも
  • ユビキタス言語
    • モデルを言語の骨格とする
    • コミュニケーションとコードではその言語を用いる
    • 用語集とは違う
    • 形式知として全体に浸透するもの☆
  • わからない言葉を整理してビジネスの外観を捉える
  • 言葉を整理する中で気をつけるポイント☆
  • トランザクションスクリプトになりがち
    • 関心事が入出力に寄ることでドメイン層がただの入れ物になる
    • テーブル設計から入るとドメインがデータの器になりがち
    • ビジネスルールが書かれていない
  • どこにビジネスルールを書くか
    • 育てる

JJUG CCC 2019 Spring に行ってきた #jjug_ccc

JJUG CCC 2019 Spring に行ってきました。簡単に所感をまとめます。

www.java-users.jp

セッション資料は以下で公開されると思います。

GitHub - jjug-ccc/slides-articles-2019Spring: JJUG CCC 2019 Spring 登壇資料まとめ

所感

今回、会場に WiFi が設置されてました。快適。

Java そのものやフレームワークの話ではなく、事例や設計手法の話が以前より増えた気がする。CfPでそういうのを選んでるんだろうか。あと、アンカファレンスがおもしろそうだった。次回はそっちを聴いてみよう。

以下、メモから抜粋。

初めてのgRPC

寝坊して朝イチのこれが聴けなかった。あとで資料を読む。

What's new in Jakarta EE and Eclipse GlassFish (May 2019)

www.slideshare.net

  • JavaOracle の商標
  • javax.* の copyright は Oracle
    • javax.*jakarta.* に変わる予定?
  • Jakarta EE 8
    • Java EE 8 とほとんど変わらない
  • Jakarta EE 9
    • APIのテコ入れ
    • JSFメジャーバージョンアップ
    • CDIとの結び付きが強くなる?
    • APIに手が入るところはパッケージが変わるはず
    • javax パッケージは互換性のために残る
  • Java EE に比べて開発スピードはかなり早くなるはず
  • Java EE 8 に対応したベンダーは Jakarta EE にも追従するはず
  • https://jakartablogs.ee/

ちょうどGWあたりにパッケージの話が流れてきた気がする。誰がわるいということではないし、開発スピードが上がるので Jakarta EE はまだまだこれからとのこと。

ArchUnit で Java / Kotlin アプリケーションのアーキテクチャを CI する

確かにアーキテクチャ暗黙知になりがちで時間がたつにつれてブレる気がする。今回、初めて ArchUnit を知ったけどなかなかよさそう。ちょっと調べてみよう。

Catch up Java 12 and Java 13

www.slideshare.net

  • Java 12 の変更点はそれほど多くない
  • APIの削除はなかった
  • Javaが持っているGCは全部で7個に
  • 新しくGCは入ったがツールはこれから対応される見込み
  • OSから借りたメモリは基本的にはOSに返さない
    • Java 12 で未使用のメモリを返すように
  • Switch が文から式に (プレビュー)
    • break ⇒ break-with?
  • JMHはマイクロベンチマークの選択肢として便利

個人的には Switch 式と String#transform が気になる。要復習。

Java クライアント実装におけるAPIスタイル頂上決戦! 野良REST vs GraphQL vs OData vs OpenAPI (Swagger)

CData JJUG 2019 Spring 参考資料 · GitHub

  • APIをもっと楽に使えるように
  • API開発でなぜ苦労するのか
  • RESTはソフトウェアアーキテクチャのスタイル (原則であって規約ではない)
    • ドキュメントを読み解かないとわからない
  • OData
  • GraphQL
    • ネストした情報を一発で取得できる
    • RESTではそれぞれ取得するか、専用のエンドポイントを用意するか
    • Javaで使うのはまだつらい...?
  • CData JDBC Driver
    • Web APISQL で実行できる

以前、GraphQL を少し試してみたけど、確かに Java ではまだまだ使いやすいとは言えない感じだったかな。今後に期待ですが。OData はあまり聞いたことがなかったけど、エンタープライズ向けには割と使いやすいみたいなので、ちょっと押さえておこうかな。どうでもいいけど、タイトルがずっと "クライント" になってるのが気になった。

LINEのBOT Platformの裏側の話

  • LINEではJava利用が圧倒的に多い
  • Kotlinも増えてきている
  • Streaming API
    • リアルタイム性が重要
    • Server-Sent Event by Spring WebFlux
    • 双方向通信の必要はなかったので WebSocket は採用しなかった
  • Redis の Pub/Sub と Kafka の組み合わせ
  • SSE は長時間イベントを送らないと接続が切れる
    • ping 送信用の Flux を merge (10秒間隔で ping 送信)
  • SSE の再接続
    • Last Event ID
  • Data Hub として Kafka を使っている
    • Consumer Group で複数サービスに配信?
  • logback + MDC
    • ThreadLocal ベースで実装されている機能
    • ログに reqeust 情報を追加する
    • WebFlux で使う場合はひと工夫が必要?
  • モニタリング

もしかしたら普通なのかもしれないけど、LINE では Kafka をいろいろ活用されてるんですね。そこらへんのノウハウがいっぱいありそう。

ストラングラーパターンによるマイクロサービスマイグレーションの勘所

ストラングラーパターン。モノリスなアプリケーションを段階に置き換えるという話。機能やアーキテクチャより、ログ管理やインフラ周りの運用がキモに思えた。

マイクロサービス:4つの分割アプローチの比較

www.slideshare.net

  • マイクロサービスを実現する技術においてコンテナの存在は大きい
  • 4つの動機のうち今日のメインは機能分散
  • 最初にモノリスで作って、抜き出せる機能/移行を検討する
  • モノリスで有効な設計はマイクロサービスでも同様のはず☆
  • クラウドによって非同期はやりやすくなった/当たり前になってきた
  • 論理的なモジュール分割は積極的に大胆に
  • 物理的な配置と運用単位は慎重に
  • マイクロサービスではモノリスにはない考慮ポイントが多い
    • ノウハウがあればいいが最初のうちは慎重にやる
  • マイクロサービス間の通信の勘違いと真実☆
    • ネットワーク全体は等質ではない
  • 4つのアプローチ☆
    • 実際には択一ではなく組み合わせ
  • 部門の構造とシステム構造が一致させるのがよいとは限らない?
  • ユースケースで分割するとトランザクション単位のマイクロサービスになる
    • ユースケースサービスを薄くして、後ろに各サービスを置く リソースで分割
    • リソースをまたがった参照が複雑になりがち
      • 外部キー制約が使えない、JOINが使えない
    • モノリスでは識別単位の情報にいろいろ持たせ過ぎていた?
    • リソース管理単位を分割する
  • ビジネスルールの分割パターン
    • 入出力はシンプルになる
  • トランザクション分解パターン☆
  • モノリストランザクションはマイクロサービスでは適用できないかも

要復習。モノリスで有効な設計スキルはマイクロサービスでは同じとのこと。ただ、マイクロサービスに分割する際にはマイクロサービス特有の考慮ポイントがあることに注意する必要がありそう。

DB設計したいNight #4 そーだいさんと失敗から学びながらDB設計したいnightに行ってきた #dbsekkeinight

DB設計したいNight #4 そーだいさんと失敗から学びながらDB設計したいnightに行ってきました。

dbnight.connpass.com

所感

今回はパネルディスカッション形式でパネラーの失敗事例を題材にトークする感じ。事例を見てすぐに解決策を説明されてて、培ってきた経験とノウハウが圧倒的だなと感じました。短い時間でしたが、学びや刺激がありました。

今回のディスカッションで話していたことは書籍の内容がベースになっているものが多かったです。DB設計は奥が深いっす。まだ読み途中なので引き続き勉強しよう。

失敗から学ぶRDBの正しい歩き方 (Software Design plus)

以下、メモから抜粋。

桁、桁数、フォーマットが想定と違うケース。

  • アプリケーションに合わせたデータとマッピングするテーブルを用意する
  • トリッキーな手段で対応せず基本に忠実に
  • 実際のデータがどうなっているかは意識すること

共通項目が多いが部分的に異なる。STI (継承関係を1テーブルで表すこと) を採用したケース。

  • アプリとDBの親子関係は一致させる必要はない
  • 親子関係を逆転させる (共通テーブルを子にする)
  • typeごとにVIEWを用意する
  • PostgreSQLの継承を使う
  • 最初に小さく作る
    • あとからくっつけるのは簡単
    • 最初から大きく作るとあとから分けるのは大変

  • 共通テーブルのIDと親テーブルのIDx2を持つ関連テーブル
    • 親テーブルのIDの排他を担保するためにCHECK制約を使う
  • 共通テーブルのIDを親テーブルが持つ
  • 共通テーブルにフラグを持たせがち
    • 1つのテーブルに複数のステータスや状態を持たせない
  • 複数のステータスを条件にする場合は別テーブルに分ける
  • その共通項目は本当に共通なのかをよく考える

なんでも一発で取れるVIEWを用意したが、JOINが多すぎてパフォーマンスがわるい。画面などの用途ごとにVIEWを用意したが、VIEWの数が多くなり、VIEW同士のJOINやVIEW間の依存が煩雑になったケース。カラム追加でどこに影響があるか特定するのが困難に。

  • キャッシュ、マテビュー、サマリーテーブル
  • 更新頻度の少ないデータはjsonにしてS3に置いてDBアクセスを減らしたり
  • VIEWからVIEWを作る、2階層のキャッシュはNG
    • 古いキャッシュが残らないように
    • リフレッシュの順序を考慮する必要があったり
  • 最初にしっかり論理設計をしてから物理設計をする
  • VIEWやマテビューを使うときは、設計にミスがありそれをRDBの機能でカバーするということ
    • 可能であれば設計を見直す方がよい

  • VIEWを使うケース
    • リファクタリング時に互換性を保ちたいとき (テーブル分割など)
    • セキュリティ上、見せたくないカラムを隠蔽したいとき
      • 誤って select * ... してセキュアなデータが露出しないように
    • 事前に(複数の)フラグを解決したVIEWを用意したいとき
      • アプリ側で条件を書くと複雑になるため

不要になったカラムは消すか?残すか?

  • 確実に消していいことがわかるなら消す
  • アプリ側で抽象化してあると変更しやすい
    • 算出すればわかるデータはアプリ側で算出する (年齢⇛生年月日から算出)
  • カラムやテーブルに OLD などのプレフィックスを付ける
    • 将来削除されることがわかるようにコメントを残す
  • Oracleではメタデータで設定できる
    • クエリや実行計画、indexに使われなくなる

ログテーブル

  • 最近はS3など他の手段で実現することが多い
  • RDBに入れておくと検索しやすい
  • 不要になったログデータはS3などに退避させて削除する
  • 課金データなど、月単位でパーティションを切って、不要になったらdropする
    • 削除するときにdump取ったりS3に退避したり