JSUG勉強会 2020年その6 LT大会 に行ってきた #jsug

先日、JSUG勉強会 2020年その6 LT大会 に参加しました。今回はオンライン開催。簡単に所感をまとめます。

jsug.doorkeeper.jp

所感

今回はLT大会ということで幅広い内容が聴けてよかったです。Liveness / Readiness や Graceful Shutdown のあたりは前回の JSUG 勉強でも話があったけど、内部の仕組みの話が聴けて参考になりました。SmartLifecycle インタフェースとか使う機会あるか分からないけど存在を知れてよかった。

Armeria は初めて知りました。あと、Azure Spring Cloud の話を聴いたのも初めてかも。

AWS と Spring アプリケーションのパターン集は知見が詰まっててすごい。あとで見てみよう。CDC は去年の Spring Fest でセッションがあったけど、とても便利そう。契約がドキュメント代わりになるのかー。用途として Swagger とかと少し重なるところがあるのかな。

Baeldung はベルダンって読むのか。(今まで気にしたことなかったけど)

YouTube の URL はこちら。

https://youtu.be/ojCaNdtEjVkyoutu.be

以下、メモから抜粋。

Spring BootユーザのためのArmeria入門

  • Armeria
  • 既存の Java アプリに組み込んで使える
  • LINEではよく使われている

Spring Boot 2.3のLiveness & Readiness Probes 対応について調べてみた

  • Liveness: アプリの内部状態
  • Readiness: トラフィックを処理できるか
  • Actuator のヘルスチェックで状態を取得
  • k9s 以外の環境でも活用できる
    • k9s 環境では自動で有効になる
    • 2.3.2 からプロパティが変わっている
  • Liveness と Readiness の状態の組み合わせでヘルスチェックの結果が変わる☆
  • 設定ありなしでヘルスチェックが UP になるタイミングが違う☆
  • 起動 > EventPublishingRunListener, ...
  • 取得 > ApplicationAvailability
  • 変更 > AvailabilityChangeEvent

AWSで作るSpringアプリケーション開発

  • AWS + Spring アプリケーションのパターン集
  • CI/CD, デプロイ
  • Spring アプリから CloudFormation でリソースを作成☆
  • S3 ダイレクトアクセス
    • 署名を付けたり
  • マイクロサービス
    • OIDC/OAuth2

今から始めるWebClient

  • Spring MVC + WebClient
  • RestTemplate は 5.0 でメンテナンスモードに☆
  • WebClient.Builder☆
  • Servlet API で使う場合は最後に block を呼び出す
    • リアクティブ型から通常のオブジェクトを取得
  • カスタマイズ☆
    • WebClientCustomizer インタフェース
    • ReactorNettyHttpClientMapper (WebClient 内部で使用している HttpClient)
  • 今後、新規で使うなら WebClient を使うとよい

Spring Boot × Spring Session × Herokuでオンライン研修に役立つアプリを自分で作った話

  • Spring Boot + jQuery
  • Spring Session でセッション共有
    • セッションは外部のデータストアに保存
    • LBで分散しても問題なし
    • データストアは Redis, JDBC, Hazelcast
  • 通信の暗号化
    • HTTPS
    • アプリ-データストア (sslmode=require)
  • Heroku

外国人(ミャンマー)へのSpring Boot教育ノウハウ

  • Baeldung (ベルダン)
  • 英語で Spring Boot を勉強する

Spring BootのGraceful shutdownって内部でどうやって実現されているの?

  • Graceful shutdown
  • 安全にサーバーを停止できるように
  • JettyWebServer
  • GracefulShutdown
  • WebServerGracefulShutdownLifecycle☆
    • SmartLifecycle インタフェースの stop メソッドから呼ばれる
  • SmartLifecycle インタフェース
    • ApplicationContext の起動/停止で任意の処理を実行できる

Spring Cloud ContractでCDCをしたい話

  • サービスの E2E テストをしたい
  • 外部サービスに依存しているときにどうするか
  • CDC (Consumer Driven Contract)☆
    • Contract = API の規約
    • 契約通りに API サーバーが実装されているかテストする
    • 契約に基づいたスタブを作成してテストする
  • Spring Cloud Contract☆
  • 契約/スタブは Maven リポジトリで後悔される
  • スタブモード: LOCAL or REMOTE
  • JVM 言語以外でも CDC をサポートしている
    • Docker で Java のレイヤーを抽象化
  • Contract がドキュメントになる

コンテナ時代のデプロイメントパイプラインのさわり

miro.com

  • コンテナイメージと JAR の違い
    • ビルド時間, サイズ, 作成方法, コンテナ基盤の都合, ...
  • Repository
    • コンテナ運用の場合は必須
  • AWS ECR ⇒ ECS
    • Pipeline から直接渡さない
    • レジストリを経由してデプロイ
  • bootBuildImage☆
  • 環境要因をイメージに含めるのは避けるべき
  • 最初はイメージをデプロイするところを作る☆
    • ビルドのところはビルドツールに任せる
  • 秘匿情報の扱い
    • コンテナに含めるか含めないか

Azure Spring Cloud 5分クッキング

  • マイクロサービス開発で用意するものが多くて大変
  • Azure Spring Cloud
    • マイクロサービスアーキテクチャを構築するためのプラットフォーム
    • 周辺サービスがフルマネージドで提供されている
    • 基盤は k9s
  • IDEA からデプロイ可 zipkin.sender.type=web
    • プラットフォーム側に HTTP のトレースが送られる

BPStudy#155〜要件定義・仕様化・実装の継ぎ目をなくすCCSR開発手法に行ってきた #bpstudy

先日、BPStudy#155〜要件定義・仕様化・実装の継ぎ目をなくすCCSR開発手法に行ってきました。オンライン開催。簡単に所感をまとめます。

bpstudy.connpass.com

所感

これまでに増田さんの DDD のセッションは何度か聴いたことがあり、CCSR もブログでは読んだことはありましたが、直接、話を聴くのは初めてでした。RDRA はあまり分かっていないので、そのあたりはちょっと理解が追い付かず...。とりあえず、RDRA ハンドブックを読んでみるか。あと、CCSR のパターンカタログとか参照実装を見ながら勉強するといいのかなぁ。

今回の CCSR の話はこのブログにまとまっています。

masuda220.hatenablog.com

自然言語による要件や仕様の定義では抜け漏れが起きやすく、複雑なソフトウェア開発に対応できない。論理的に明確に要件や仕様を定義してシームレスに実装まで落とし込むというサイクルをいかに回すか、複雑なものはどうしたって単純にすることはできないので複雑なものをいかにコントロールするか、というのがこれらの手法を取り入れるポイントなのかなと思います。

「仕様が変わる」とは、これまで見えていなかった暫定仕様が正式仕様に変わっただけ、というのが目から鱗でした。あと、パネルディスカッションの最後に言っていた「要件定義と実装は近い」というのも印象的でした。なるほど。

以下、メモから抜粋。

要件定義・仕様化・実装の継ぎ目をなくすCCSR開発手法

www.slideshare.net

  • CCSR手法
    • 継続的, 並行的, 段階的改善
    • 複雑なソフトウェアは1歩ずつ改善するしかない
  • コードを書く開発者が主体的に取り組む☆
    • 全体像の認識を合わせる
    • つながりを整理する
    • 軸/中心を強化して周辺を広げる
  • 要件定義の質を高くする
    • RDRA 2.0
    • つながりによる整合性
  • 仕様を明確に記述する
  • ビジネスロジックを軸にする
  • 値の種類(型)でモジュール化する
    • 手続きでモジュール化しない
  • ビジネスルール > ファクト, ロジック, リザルト
    • ファクト ⇒ フィールド/引数
    • ロジック ⇒ メソッド
    • リザルト ⇒ メソッドが返す型
  • ハンドブック, パターンカタログ, 参照実装
  • ビジネスルールの可視化
  • 強い型付け言語がよい
  • enum (バリエーションを表す)
  • JIG
  • 一覧にするとフラットに見てしまうので軸を持つ

CCSRを実現するRDRA活用法

www.slideshare.net

  • 大きな手戻りを起こさないためにどの段階からくり返しを始めるか
  • くり返しの単位は?
  • BUCを管理単位にする (バックログなど)
  • BUC単位で仕様化して実装
  • BUCは価値や責務を表す
  • 関係者間で認識を合わせやすい
  • テストを考えやすい
  • MVPは最小のビジネスパラメータの組み合わせ
  • バリエーションはビジネスパラメータになる
    • 個人顧客/法人顧客, ...など
  • RDRAレイヤー
    • システム価値
    • 外部環境 (システムがどう使われるか)
    • 境界 (システムの入出力)
    • システム (システム化対象の情報と状態)
  • 1つの業務フローがビジネスユースケースの単位になる
  • ユースケースはシステムの境界
  • くり返し開発では手戻りは起こるもの
    • 情報, 状態, バリエーションの変更は手戻りが大きい☆
    • ここを先に固く作る?
    • 決められないところは暫定仕様で作る☆
  • 暫定仕様を正式仕様にする
    • 暫定仕様をマーキングする☆
    • 暫定仕様の影響範囲を把握する
    • 計画的な手戻り
  • 要件-仕様-実装をシームレスに
  • RDRAの図の関連はツールに頼る
  • CCSRで無駄な作業が減る/気が付く
  • 設計と実装はほぼ同じ
  • 要件定義と実装は近いもの

Chrome DevTools の Network タブでたまに使う機能

Chrome DevTools には仕事でよくお世話になっています。とはいえ、まだまだ知らない機能がたくさんあって全然使い切れていません。その中で、最近たまに使う Network タブの機能2つです。

Initiator

リクエストを投げたファイルやプロセスを表示します。JavaScript コードの場合、リンクをクリックするとソースコードの該当箇所にジャンプします。

(余談)

ある画面でメニューリンクをクリックするとモーダルが表示される機能があるのですが、先日、そのメニューをクリックするとモーダル表示と同時に画面全体がリロードされる不具合がありました。リロードというか、表示中のページURLをそのままリクエストしている感じ。

当初、メニュー周りの実装にバグがあるかと思って調べてたのですが、どのタイミングで誰がリクエストしているのか分からず。

ここで、DevTools の Network タブで Initiator を確認します。誰がそのリクエストを投げているのか一発で分かります。

結局、ある jQuery ライブラリがメニューのリンクに click イベントを引っかけていて、特定の条件でリクエストが投げられていることが分かりました。ライブラリ側の設定で回避。

Timing

リクエストの内訳を詳細表示します。

(余談)

ある画面で、更新ボタンをクリックしたところ非常に時間がかかるという問い合わせがありました。

当初、サーバー側の更新処理が遅いかと思ったのですが、アプリケーションログを見ても特にレスポンスが遅いところは見られず。

ここで、DevTools の Network タブで Timing を確認します。Request/Response の欄を見ると Request sent に 10 sec 近くかかってる...。ちなみに Waiting は 1 sec 以内。

結局、画面側にファイルを添付する機能があり、このファイル送信に時間がかかっていました。更新とファイルアップロードを分離して、少しは UX 改善になったはず...。

(参考)

developers.google.com

並び順をカラムに持つテーブルの設計

最近の話ですが、もともとフラットに管理されているデータに、次の要件を追加する対応をしました。

  • カテゴライズ
  • カテゴリの中で任意に並び替え可

で、この要件を実現するためにテーブル設計を変更したのですが、なんとなくイマイチな感じになってしまったので、後学のために再考しています。備忘録。


もともとフラットに管理されているデータがある。

f:id:knt_mr:20200718012208p:plain:w160

これにカテゴリの機能を追加する。カテゴリは1階層のみ (カテゴリの入れ子はない) で、データは1つのカテゴリに属する。

f:id:knt_mr:20200718012631p:plain

さらに、カテゴリの中で任意にデータを並び替えられるようにする。いくつか案を考えたのですが、並び順をカテゴリに対する属性と考えて、こんな感じにしてみました。

f:id:knt_mr:20200718012950p:plain

一応、これで実装は進めたものの、なんとなく違和感が...。関連テーブルと属性テーブルにそれぞれデータIDとカテゴリIDがあって役割が被ってるような気がする。属性テーブルの設計がイマイチっぽい。

というわけで、こんな感じにするのはどうだろう。

f:id:knt_mr:20200720172246p:plain

あるカテゴリのデータを並び順で取りたいときはこんな感じ。

SELECT * FROM Item as i
JOIN ItemCategoryRelation as rel ON rel.item_id = i.id
JOIN Category as c ON c.id = rel.category_id
JOIN ItemCategoryAttribute as attr ON attr.relation_id = rel.id AND attr.item_id = i.id
WHERE c.id = 12345
ORDER BY attr.order

うーん、特にクエリがシンプルになるわけでもないし、どっちもどっちな気がする...。現場からは以上です。

インターネットの情報とどう向き合うか (子供向け)

普段、子供には iPad を使わせていますが、ちょっとしたゲームや学習アプリを使う程度で、YouTubeSafari は自由に使えないように制限をかけています。とはいえ、そろそろインターネットを使っていろいろ調べられるようになった方がいいのかなと。それなら、インターネットの使い方やインターネット上の情報とどう向き合うか、親として伝える必要があるかなと思っています。

というわけで、子供向けにまとめました。


インターネットが広く使われるようになって、自分の知りたい情報が簡単に手に入るようになりました。分からないことを自分で調べて解決できるようになることは、とても大事です。インターネットはそういうときに役に立ちます。

インターネットの難しいところは、『そこに書いてある情報が正しいとは限らない』ということです。

今、目の前にある情報が本当に正しいのか、もしかしたら間違っているんじゃないか、しっかりと疑って自分の頭で考えることが大事です。

もう1つインターネットの難しいところは、『インターネットに残した情報は残り続ける』ことです。インターネットに流した情報は簡単には消せません。

自分や家族、友達の個人情報写真を安易にインターネットに流してはいけません。

インターネットにはいろいろな情報があり、それらの情報はたくさんの人が見ることができます。知らない人がどこかで自分の情報を手に入れているかもしれません。インターネット上で自分がやったことや言ったことは常に誰かに見られていると思って行動しましょう。

もちろん、誰かの悪口や批判をインターネットに書いてはいけません。直接、その人や家族に言えないようなことは書かないようにしましょう。

インターネットにはいろいろなことが書いてあります。自分でもいろいろなことを書くことができます。同じ文章でも読む人によって捉え方が違います。ある人はその文章を読んで笑うかもしれません。別の人はその文章を読んで悲しくなるかもしれません。自分は悪口だと思っていなくても、相手は悪口と感じるかもしれません。誰かに何かを伝えるということは難しくてデリケートなことです。

ちなみに、これはインターネットだけではなく、実際に人と話をするときも同じです。相手が言ってることは正しいとは限りません。自分はおもしろいと思っていることが相手もおもしろいと感じるとは限りません。もちろん、それはパパやママが相手でも同じです。

インターネットにはいろいろな情報があります。それはとても役に立ちます。しかし、その中には見てはいけないものもたくさんあります。もし、「これは見てもいいのかな?」「見てはいけないものを見てしまったかな?」と思うことがあれば、迷わず相談してください。そのあとどうするかは一緒に考えましょう。

そして、インターネットに書いてあることがすべてではありません。本を読むことも大事です。人と話をすることも大事です。インターネットを上手に使ってください。

マージリクエストにラベルを付ける

以前、GitLab の運用についてこんな記事を書きました。

kntmr.hatenablog.com

現在もだいたい同じような運用をしているのですが、最近、少しだけマイナーチェンジしました。タイトルの通りなんですが。

現状

これまでのメンバーの作業の流れはこんな感じ。

  1. チケットで作業を振られる
  2. feature ブランチを切る
  3. 実装 & commit
  4. 実装完了次第、マージリクエストを投げてレビュー依頼する

ちなみに弊社で使ってる GitLab のバージョンはとても古いです。お察しください。

課題

メンバーが作業途中でも適当なタイミングでレビューしたい。特に、朝会などで昨日までの実装分をお互いに見ながら軌道修正しつつ開発を進めたい。そのためには、作業着手して feature ブランチを切るのに併せてマージリクエストを投げてもらえばいいが、作業途中のブランチを誤ってマージするのは避けたい。昔の GitHub の PR みたいにタイトルに「WIP」とか付けてもらってもいいけど、もっと機械的にフィルタして作業ミスを防ぎたい。というか今の GitHub なら Draft Pull Request とかあるのにね。

ラベル

今さらですが、デフォルトのラベル以外にカンマ区切りで任意のラベルを設定できることに気が付きました...。ラベルを使えばいい感じに整理できそう。

f:id:knt_mr:20200702105709p:plain

運用

feature ブランチを作成したらマージリクエストを投げて in progress ラベルを付ける。in progress ラベルのブランチはマージしない。

実装が完了してレビューするタイミングになったら in progress を外して review ラベルを付ける。レビュワーは review ラベル (とマイルストーン) でフィルタして、必要なブランチだけをレビューしてマージする。


余談ですが、master や開発のメインブランチなど、feature ブランチのマージ先となるブランチは Protected にする。Git に不慣れなメンバーが勝手にマージリクエストを Accept しちゃうので...。このあたり、権限設定とかもう少し細かくできるんだろうか。他の現場ではどうやってコントロールしてるんだろう。

メンバーにどのような情報を伝えるか

開発チームのメンバーに作業を依頼するときに、どのような情報を伝えるかは重要なポイントになります。メンバーが十分に理解して納得して作業に取り組んでもらった方が、認識齟齬によって生じる手戻りを防げるし、メンバー自身にも主体性が生まれるだろうと思っています。

で、伝える情報をどのように整理するか。例えば、次のような観点で整理してみます。

Why

なぜこの作業が必要なのか、エンドユーザーが困っていることは何か、全体を俯瞰して概要や影響範囲を説明します。これから自分が取り組む作業にはどんな意味があって、これをやることでどんな効果があるのかを認識してもらいます。さらに、メンバー自身がこのチームに存在する意義を見出して欲しいと思っています。「自分は誰かの役に立っている」と認識することで、主体性と責任感を持って作業に取り組んでもらえればと考えています。

What

Why の課題を解決するために何が必要か、これから何を作るのか/改善するのかを説明します。Why の内容と対になるように説明することでより理解しやすくなると思います。

How

What をどのように実現するか、どうやって作るか、そのためにどのような前提知識が必要になるかを説明します。メンバーのスキルレベルによって伝える情報の粒度を変えたりします。すでに独力で進められるメンバーであればざっくり説明して任せるし、経験の浅いメンバーであれば図解して説明したりドキュメントに落とし込んで説明します。いずれにしても、何かしらの形で設計のレビューはします。

When (How much)

作ったものはいつリリースするのか、そのためにはいつまでに作業を終えて欲しいかを説明します。リリースやテスト/レビューの時間を考慮していくつかマイルストーンを置きます。あらかじめ無理のないスケジュールを設定しますが、朝会などで進捗を確認して必要に応じて都度調整します。

Who

なぜこの作業をあなたに任せるのかを伝えます。「仕様を把握しているから」「過去に類似の作業をやったことがあるから」「フロントエンド、あるいはバックエンドが得意だから」「詳細なドキュメントを作って欲しいから」など、こちらから伝えられることは伝えるようにします。ただ、このあたりはメンバーの性格や仕事の進め方などを分かっていないと、なかなかこちらの意図通りに伝えるのは難しいかもしれません。

とはいえ、だいたいいつも「今、手が空いてるひとがあなたしかいないのでぇ~」みたいな雰囲気になりがち。


このような観点で情報を整理すると自分の理解にも役立ちます。当然、自分がきちんと理解していないとメンバーに正確に伝えられないので。現場からは以上です。