HashiCorp Waypoint のドキュメントを読んだ

リンク

Waypoint is 何

アプリケーションコードをビルドして任意のプラットフォームへ配置、公開するための環境を提供するソリューションでした。

機能的には AWS Code Pipeline とか Azure DevOps とか Google Cloud Build と同じレイヤーになると思うんだけど、開発効率を向上するほうに注目してる感じです。

アプリケーションコードをビルド

  • Maven や Gradle や sbt などのビルドツールより上位の概念としてのビルドを担当します
  • KubernetesNomad 経由で Cloud Native Buildpacks を使う場合が多そうです
  • シンプルな docker build も使えます

任意のプラットフォームへ配置、公開

第7回 Chaos Engieering 読書会@リモートのログ

learning.oreilly.com

javaee-study.connpass.com

引き続き Discord によるオンライン開催。

次回は 11/15(日曜日)で、Part IV Business Factors の 15 Chaos Maturity Model から。

javaee-study.connpass.com

対象範囲

  • Part III Human Factors(第三部 ヒューマンファクター)
  • 12 Experiment Selection Problem (and a Solution)
  • Part IV Business Factors
  • 13 ROI of Chaos Engineering
  • 14 Open Minds, Open Science, and Open Chaos

トピック

  • iPhone 12 が公開
    • AppStore アプリから予約するのが簡単らしい
  • 仕事部屋を絶賛改造中
  • Sourcegraph をお試し中
  • テニスを通じていろんな人と交流してる
  • 自宅のモバイルネットワーク品質が悪いことに気付いてがっかりしてる

ディスカッション

12 Experiment Selection Problem (and a Solution)

  • カオス実験で設定する問題事象は、それぞれの事象の発生頻度は極めて低いのに、無数の組み合わせから慎重に選択するモチベーションが理解できない
    • 大規模になればどれだけ低確率の事象でも普段から発生することになるから、やっぱり考慮しないといけない
    • とはいえほとんど生じない要素を取り上げるという考え方はおかしいだろう
  • 無数の実験から選択する方法は実質 1 つ - 専門家に委ねる
    • ただ、嘘をついてしまう場合があるので注意が必要
    • 問題として認識してるけど対応するのがすごい大変、とか
  • 収集したコールグラフにモデル式を適用することで優先して実験したほうがいい部分を導出する、みたいな研究すごい

Part IV Business Factors

13 ROI of Chaos Engineering

  • カオス実験により発見した欠陥を解消できたことで、より高い可用性を求められると困ってしまう問題
  • カークパトリックモデル
    • 投資対効果を評価する古典的なモデル
    • 1 反応 - 肯定的か
    • 2 学習 - 何を学んだか
    • 3 転移(振る舞い) - 学んだことから行動は変化するか
    • 4 結果 - 費用コストに見合う結果は得られたか
    • (この指標、仕事に使えるのでは・・・)
  • 費用コストに直結しない KPI でも合意さえあれば指標として実験の価値を示すことができる
    • カークパトリックモデルは指標ではなくあくまでも評価モデルでしかない (誤解してた)

14 Open Minds, Open Science, and Open Chaos

shop.oreilly.com

openchaos.io

Open Science now: A systematic literature review for an integrated definition - ScienceDirect

GitHub - open-chaos/experiment-catalog: A public and open source chaos engineering experiment catalog.

参考情報

「○○にしましょう」と呼びかけるより淡々とやっていく

いろんな活動や目標が当てはまるので汎用性が高い。仕事でも個人の活動でもだいぶ前からそういう思想で行動するようになった。

自分の望む状態があるなら、人に頼るより自分のできることを積み上げていくほうが可能性があるんじゃないか、という。

期待してないわけじゃなくて、助けてくれるなら嬉しいのは間違いない。

助けをあてにすると裏切られた気持ちになりがちで、それが相手に対する負の印象へ置き換わってしまうことを避けたい。

Oracle Developers Live Java 視聴ログ

developer.oracle.com

Java 15 のリリースに合わせて開催されたオンラインイベントのセッション動画が公開されたので面白かったところのメモ。



Java Language Futures—Mid 2020 Edition (35:32)

JDK 15 で導入されたフィーチャーの紹介。

  • Records (JEP384)
    • ボイラープレートコードを省略すること自体は目的じゃない
    • 他の言語でいうタプルのような存在
  • Pattern matching for instanceof (JEP375)
    • instanceof でガードしていたキャストは撲滅できる
      • 論理積演算子 && でつなげるから真偽値を返す?
      • 式なのか文なのか…
  • Sealed Classes (JEP360)
    • 特筆することがない…
  • Text Blocks (JEP379)
    • 紹介されなかった

Java 15新機能まとめ - Qiitaを読めばいいことがわかった。

ZGC: The Next Generation Low-Latency Garbage Collector (39:26)

発音:ズィージーシー

今利用できる GC アルゴリズムと特徴

  • ZGC はレイテンシ(GCによる停止時間)の削減を目指してる
  • スループット(GCによる処理数)を大きくするアルゴリズムはヒープメモリの使用効率を向上しようとしてる
GC Optimized for
Serial Memory Footprint
Parallel Throughput
G1 Throughput/Latency Balance
ZGC Low Latency

ZGC の特徴

  • リージョンベースで並行処理
  • NUMA対応でトレーシング可能
  • ロードバリアによるコンパクション
  • 単一世代で色ポインタを利用する
    • ヤング・オールドみたいな世代はない
  • 停止時間はヒープサイズやライブセットサイズに依存しない(ルートセットサイズに依存する)
  • クラスアンロードもできる

ZGC の振る舞い

  • マークスタートフェーズ
    • 10ms 以下
    • 対象オブジェクトにマークする
    • マッピングを修正する
  • マークエンドフェーズ
    • 10ms 以下
    • マークしたオブジェクトをリアロケートするための準備
  • リアロケートフェーズ
    • 10ms 以下
    • 準備したオブジェクトをリアロケートする

色ポインタ

  • オブジェクトポインタの構造
    • 未使用ビットとオブジェクトアドレスの間の 4 bit をメタデータとして利用する
    • マーク済み、とか、リアロケート対象、とか
p = 未使用 (16 bit) +
    色ポインタ (4 bit) +
    オブジェクトアドレス(44 bit, 16 TB に相当する)

ロードバリア

  • ヒープのオブジェクトを参照するときに JIT がコード片を挿入する
  • ロードしたタイミングで色ポインタをチェックする
  • チェックして問題があれば修復する

ZGC の性能

ZGC の未来

  • GC停止時間のさらなる削減 - 1 ms 以下にしたい
  • GC停止時間がルートセットサイズに依存しないようにしたい
    • 今のところスレッドスタック処理に未対応なため (JEP 376 で議論してる)
  • 世代別 GC

Keeping Your Java Applications Secure: Cryptographic Improvements and Best Practices (37:09)

Cryptographic Improvements

  • 安全なアルゴリズムの提供
    • JDK のリリースごとにより優れたアルゴリズムが追加されている
    • バックポートされているから昔のバージョンでもアップデートしていく必要がある
  • 安全でないアルゴリズムの使用を制限
  • 関連する警告やイベントを出力するようになっている
    • keytooljarsigner の出力に気を付けよう
    • JFR で観測できるイベントが増えている
      • jdk.SecurityPropertyModification
      • jdk.TLSHandshake
      • jdk.X509Validation
      • jdk.X509Certificate

Secure Programming Best Practices

Secure Coding Guidelines for Java SE の紹介。

コーディングガイドは10章構成。

  • 1-3章は基礎
    • DoS
    • 機密情報の保護
    • 注入攻撃
  • 4-10章はコードと権限に関連する

Java に限定した話じゃないので注意が必要。

要するに、プロセスの外部から入力されるデータは信用できないので、言語機能を公開するべきではない、みたいな感じ。

自分でコーディングする場合以外に、フレームワークやソリューションを選定するときも注意したほうがいいと思う。

This Ain’t Your Parent’s Java (40:45)

個人的に心の中で Java 芸人と呼んでいるベンカット・サブラマニアンのマシンガントーク (貴重な Emacsen でもある)。

Project Loom: Modern Scalable Concurrency for the Java Platform (38:34)

並列性の目的はスループット

  • スループットはリトルの法則 L=λW に支配されている
    • λ - 並列度 (制御できる)
    • W - 平均レイテンシ (外部サービスへのアクセスなど、制御できない部分が混在する)
    • L - 並列性の度合

現在の Java スレッド

  • OS スレッドのラッパー
    • タスクスイッチにカーネルモードへの切り替えが伴う
    • OS のスケジューリングに依存
    • キャッシュの局所性が悪い
  • スレッドごとの消費リソースが大きい
  • スレッドプールを使えば再利用できるけど別の問題が生じる
    • トランザクションが完了したら戻すモデル (request thread 的な話)
      • スレッドローカルがリークする
      • キャンセル処理が複雑化する
    • 待ち状態になったら戻すモデル (nio 的な話)
      • API に互換性がない
      • コンテキストを維持できない
  • 結局のところ同期処理と非同期処理のトレードオフになる
    • 人間にやさしい vs マシンにやさしい
    • 簡単 vs 複雑
  • いいとこどりしたい
    • 前方互換性を保ちつつ( 既存の資産を守りつつ ) 新しい機能を導入したい

そこで Java スレッドの再設計

  • Thread.currentThead() はあちこちで使われてるので注意が必要
  • Java 5 以降は Executor/Future を利用するようになってるから直接的に Thread API を使う場面は減っている
  • Thread API を大掃除すればかなりフットプリントを削減できる

新しい Java スレッド = Virtual Threads

  • スタックのサイズを可変にする
    • メタデータに 2kB 使っていたのを 200-300B にする
    • スタックに 1MB 使っていたのを可変にする
  • ユーザーモードコンテキストスイッチできるようにする
    • 長くて 10μs から 200ns 以内に短縮する
  • スケジューラーを交換可能にする

利用者にとってのメリット

構造化並列性という概念の導入

  • 構造化とは ?
    • ランタイムの振る舞いをコードに反映すること
    • libdill(C)や Trio(Python) で採用されている

Executor API の改善

  • 1 ThreadExecutor は Auto-Closeable になり、すべてのタスクが完了するまで待機する
    • スレッドプールにタスクを submit する API は変わらない
  • 2 指定した期間を経過したらタスクを実行してるスレッドを interrupt する
  • 3 join や wait や cancel を簡単に扱えるようになるはず

コード例。

// 1
ThreadFactory factory = Thread.builder().virtual().factory();
try (var executor = Executors.newThreadFactory(factory)) {
    executor.submit(task1);
    executor.submit(task2);
}

// 2
ThreadFactory factory = Thread.builder().virtual().factory();
try (var executor = Executors.newThreadFactory(factory)
                             .withDeadline(Instant.now().plusSeconds(30))) {
    executor.submit(task1);
    executor.submit(task2);
}

// 3
try (var executor = Executors.newVirtualThreadExecutor()) {
    String first = executor.invokeAny(List.of(
        () -> "a",
        () -> { throw new IOException("too lazy for work"); },
        () -> "b"
    ));
    System.out.println("one result: " + first);
} catch (ExecutionException e) {
    e.printStackTrace();
}

Collections Refueled (30:16)

JDK 9 以降の Collections Framework の改善について淡々と紹介。

簡潔なファクトリメソッド

  • 不変コレクションを生成するための of
    • Collections.unmodifiableList(Arrays.asList(xxx))List.of(xxx) で代替できるようになった
    • Collections.unmodifiableSet(new HashSet<>(xxx))Sets.of(xxx) で代替できるようになった
    • Collections.unmodifiableMap(xxx) にも代替案がある
      • Map.of(k1,v1,k2,v2) みたいな感じ
      • Map.ofEntries(Map.entry(k1, v1), Map.entry(k2, v2)) というのもある
  • 冪等な複製を得るための copyOf
    • 不変コレクションは copyOf しても新しいオブジェクトを生成しない (知らなかった!)
  • Stream から不変コレクションを生成するための Collectors.toUnmodifiableXXX

イテレーション順序のランダム化

  • Set および Map キーの順序の話
    • HashSet と HashMap (のキー) の順序は未定義
    • 新しく JDK がリリースされても順序の一貫性は保たれていた
    • もし順序が変わると既存のコードが壊れる可能性がある
  • 新しいファクトリメソッドが生成する不変コレクションは 順序をランダムにした
    • 潜在的な順序依存性を解消するため
    • 既存の HashSet や HashMap はそのまま
    • 順序を保ちたければ LinkedHashSet LinkedHashMap を使うようにして欲しい

重複する要素の扱い

  • Set.of(a,a) Map.of(k1,v1,k1,v2) Map.ofEntries(...)IllegalArgumentException をスローする
  • リテラルで記述するためのメソッドなのでコーディング誤りの可能性が高いから

空間効率について

ファクトリメソッドはサイズに応じた実装のコレクションオブジェクトを生成する(複製する?)。

素数 実装
0 シングルトン
少数(10以下?) フィールドベースの実装
多数 配列ベースの実装

testcontainers のための Docker への接続情報を環境変数で指定する

前提

  • Java (Kotlin) プロジェクト
  • ビルドツールは Gradle
  • テストコードで testcontainers-java を使ってる

課題

解決方法

ファイルレイアウトはこういう感じになります。

./build.gradle
./settings.gradle
./src/main/java/xxxx
./src/test/java/xxxx
./.env

.env ファイルの内容は次のような感じです。

DOCKER_CERT_PATH=C:/Users/path/to/docker/certs
DOCKER_TLS_VERIFY=1
DOCKER_HOST=tcp://dockerhost:2376

最終的な build.gradle は次のような感じになります。

plugins {
    id 'java'
    id 'co.uzzu.dotenv.gradle' version '1.1.0' // プラグインの追加
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = JavaVersion.VERSION_11

repositories {
    mavenCentral()
}

dependencies {
    testImplementation('org.junit.jupiter:junit-jupiter-api:5.3.1')
    testRuntimeOnly('org.junit.jupiter:junit-jupiter-engine:5.3.1')
    testImplementation('org.testcontainers:junit-jupiter:1.14.3')
    testImplementation('org.testcontainers:postgresql:1.14.3')
}

test {
    useJUnitPlatform()
    // environment で指定した環境変数だけになるので、System.getenv() も指定しないとおかしなことになる
    environment = System.getenv() + [
        'DOCKER_HOST'      : env.fetch('DOCKER_HOST', 'unix:///var/run/docker.sock'),
        'DOCKER_TLS_VERIFY': env.fetch('DOCKER_TLS_VERIFY', ''),
        'DOCKER_CERT_PATH' : env.fetch('DOCKER_CERT_PATH', ''),
    ]
}

SpringOne 2020 Day 2 視聴ログ

SpringOne 2020 のセッション動画が公開されたのを視聴して面白かったポイントをメモ。こちらは Day 2。Day 1 はこちら

タイトルの 👍 の数は面白かった度合いです。



Connect Your Functions with RSocket 👍👍

Conect Your Function with RSocket

www.slideshare.net

RSocket と Spring CLoud Function を連携する話。

RSocket の基本的な説明

Spring Cloud Function と RSocket の関係

  • 別人かってくらいやる気がなくなってるけどライブコーディング始めたら少し元気になってきた
    • spring-cloud-stream-binder-rabbit を依存ライブラリに追加するだけで RabbitMQ につながる!
    • 起動引数だけで有効化する Function Bean を制御できる --spring.cloud.function.definition=nnn
  • RSocket を使うには spring-cloud-function-rsocket を依存ライブラリに追加する
    • Function Bean は4種類のどのコミュニケーションモデルでも利用できる
    • Function Routing という考え方が登場する
      • functionRouter という組み込みの部品を使う
      • メッセージに応じて Function Bean を分配するための仕組み
        • 例: ヘッダーで判断する spring.cloud.function.routing-expression=headers.func (func というキーの値で制御する)
        • コンテンツタイプとかいろいろ制御できる

Spring Cloud Function の Function Routing の制限をどうにかする仕組み

  • Spring Cloud Gateway から分離して rsocket の incubator プロジェクトとしてやっている RSocket Routing Broker という部品の機能 (rsocket-routing-client-spring という依存ライブラリ)
  • n 対 n 同期型のブローカークラスタを形成できるみたい
    • RabbitMQ で見たやつだ

Introduction to WebMvc.fn 👍👍

Introduction to WebMvc.fn

www.slideshare.net

WebMvc.fn の基本要素を紹介。

Spring Web MVCアノテーション中心の設計をプログラミングで実現するような感じで面白い。

メソッド引数への自動的なバインディングは無くなるけど、ルーティングの自由度は高まる。

Handler Functions

  • ServerRequest から ServerResponse へ変換する役割
  • RequestEntity を ServetRequest に、ResponseEntity を ServerResponse に書き換えるだけのような感じ
    • 便利アノテーションが使えなくなるけどそれは Router Function や Filter Function で対応する
    • Validated が使えなくなるのは不便だなぁ

Router Functions

  • ServerRequest に HandlerFunction を対応付ける役割
  • アノテーション @RequestMapping(vakye=”/path”, method={”GET”}) をビルダー route().GET(“/path”, handlerFunction) に置き換えるような感じ
  • ビルダーを構成する RequestPredicate にはもっと柔軟な制御をする機能がある

Request Predicates

  • 機能
    • リクエストメソッドの判断 RequestPredicates.method(HttpMethod.GET)
    • パスの判断 RequestPredicates.path(“/path”)
    • パスの拡張子の判断 RequestPredicates.pathExtension(“json”)
    • ヘッダーの判断 RequestPredicates.accept(APPLICATION_JSON)
    • リクエストパラメーターの判断 RequestPredicates.param(“type”, “json”)
  • 特徴
    • Predicate は合成できる predicateA.and(predicateB) predicateA.or(predicateB)

Filter Functions

  • Router Function の機能の一部
  • Spring Web MVC の ExceptionHandler をビルダーの onError で置き換える感じ

Spring Security Patterns 👍👍

Spring Security Patterns

www.slideshare.net

Spring Security の始め方から簡単な使い方までの紹介

Spring Security の始め方

  • 依存ライブラリに spring-boot-starter-securityを追加するだけで basic 認証が有効になる
    • 自前のエンドポイントだけでなく組み込みのエンドポイントにも
  • Secure by Default という考え方を覚えておくこと
  • 初期ユーザーは user、初期パスワードはランダム文字列
  • デフォルトプロファイルを本番プロファイルにしておくとよい
    • プロファイルの指定を忘れたときのため
    • ローカルファイルや h2 を使うプロファイルは dev とかにしておく
  • 未知のエンドポイントへのアクセスには 404 ではなく 401 を返すほうがいい
    • エンドポイントが存在するかどうかも秘匿すべき情報
  • パスワード再発行ページでは ユーザーが存在しない エラーを伝えるべきではない
    • ユーザーが存在してたらメールを送信しておくね くらいがちょうどいい

認証情報の使い方

  • Security Context Holder の static メソッドにアクセスする
    • リクエストを処理するのは1つのスレッドに限定されている
    • 認証情報はリクエストごとに生成したスレッドローカルオブジェクトに保存している
    • スレッドローカルの情報が他のスレッドに漏れることはない
  • DI する
    • Authentication オブジェクト
    • @CurrentSecurityContext(expression=”authentication.name”) String name

例: OAuth2 のリソースサーバーを構成する

  • Basic 認証は弱いのでトークンベースの認証に切り替えたほうがいい
    • たとえば OAuth2
    • 依存ライブラリにspring-boot-starter-security-oauth2-authorization-server を追加する
    • UserDetailService の代わりに RegisteredClientRepository Bean を登録する
  • クライアントが認証・認可サーバーから取得したクレームに含まれるスコープを Authentication#authorities (認可情報)として利用できる
  • JwtGrantedAuthoritiesConverter という組み込み実装を利用すると便利
    • トークンを GrantedAuthority に変換する Converter を構成できる
  • 継承ではなくコンポジションで利用するのが Spring Security の作法なので注意
    • 段階的に機能を拡張できるのがいいところ

例: 認証・認可情報の判断をビジネスロジックから追い出す

  • 宣言的セキュリティモデル、という考え方
  • メソッドベースのセキュリティ
    • @PreAuthorize(“hasAuthority('captain')”) みたいなメソッドアノテーションを利用する
  • リクエストベースのセキュリティ
    • WebSecurityConfigureAdapter を継承した設定クラスで DSL により構成する

Automated Virtualized Testing (AVT) with Docker, Kubernetes, WireMock and Gatling 👍

Automated Virtualized Testing (AVT) with Docker, Kubernetes, WireMock and Gatling

www.slideshare.net

AVT (自動化仮想テスト?) という考え方の紹介

伝統的なテストの課題

  • 不安定な環境
  • システム間の依存性
  • テストできる期間が限られてる
  • 信頼できない結果

AVT

  • 外部環境との結合を分離してコンテナ環境でモックを対象にテストする考え方
  • Liberty Mutual では Bitbucket Server + Bamboo を利用してる
  • コンテナ環境は Docker Enterprise
  • 性能テストのクライアントも同じコンテナ環境で実行する
    • 十分に負荷をかけるのが大変そうだけどどうなんだろうな
  • kompose で docker-compose.yml をマニフェストに変換してる
    • テスト結果は S3 経由で InfluxDB に記録して Grafana ダッシュボードで確認できるようにしてる、など

Enabling Cloud Native Buildpackas for Windows Containers 👍

Enabling Cloud Native Buildpackas for Windows Containers

www.slideshare.net

Build a Windows app · Cloud Native Buildpacks

Windows Container をビルドできる CNB を作った話

  • pack-cli によるビルダーイメージの構築部分を改修するためいろいろ頑張った
  • ライフサイクル管理の実装は bash を前提にしてたので改修するのがとてもとても大変だった
  • Windows イメージのレイヤリングは Linux イメージと全然違う
    • 特別な形式の TAR が必要になった
    • C:\Windows\System32\tar.exe を利用してるのかな
  • いろいろ大変だったけど完成した
    • Tanzu Build Service でベータ版を利用できる
    • pack-cli から利用できる
  • nanoserver のコンテナイメージは 4GB くらいある

Spring Boot Omakase: A First-Paced “Chef’s Choice” Dive into Fun and Useful Topics! 👍👍

Spring Boot Omakase: A First-Paced “Chef’s Choice” Dive into Fun and Useful Topics!

www.slideshare.net

SpringOne 2020 最後のセッション。Omakase = シェフのおまかせ。コンフィギュレーションやデプロイメントのおすすめレシピを紹介する話。

全編ライブコーディングなので動画を見ないとわからないやつ。🎥

Configuration

プロパティファイル、環境変数、アプリケーション引数をいい感じに利用する話。

  • Dtoクラスに ConigurationProperties で対応するプロパティキーを束縛できる
    • ConfigurationPropertiesScan も忘れずに
    • すると IDE がプロパティキーの型をクラスのフィールド型から推測できるようになる
      • コンストラクタにConstructorBinding を指定、引数にName でフィールド名とは異なるキー名を指定できる
    • 便利
  • Bean メソッドにも ConfigurationProperties を指定できる
    • 便利

Deployment

  • Shaded jar と Spring Boot の Executable Jar の違い
    • Shaded Jar や Uber Jar は依存ライブラリを展開して単一の jar ファイルに格納する
    • Spring Boot の Executable Jar は依存ライブラリをネストするのでクラスの読み込みとかが少し速い
  • Value で DI した値の取得元は Actuator で参照できる
    • 便利

SpringOne 2020 Day 1 視聴ログ

SpringOne 2020 のセッション動画が公開されたのを視聴して面白かったポイントをメモ。こちらは Day 1。Day 2 はこちら

タイトルの 👍 の数は面白かった度合いです。



Introducing Spring Framework 5.3 👍👍👍

Introducing Spring Framework 5.3 | SpringOne | September 2–3, 2020

www.slideshare.net

Spring Framework 5.x の歴史と 5.3 の新フィーチャー、そして未来の話。

  • Spring Framework 5.3 は LTS リリース
    • 2024 年くらいまでを想定してる
  • Spring Boot 2.4 および 2.5 は 5.3 ベースになる
  • JDK 8,11,15,17 をサポートする
  • 5.x 系列は打ち止め
    • 5.4 は出ない
  • 次のメジャーバージョン 6.x でやりたいこと
    • JavaEE から JakartaEE への移行
    • GraalVM の継続的なサポート
  • Java 14 で導入された record 型が活用されそう
    • フィールドやセッターではなく、コンストラクタインジェクションを推奨してるのはたぶんこのため。(おそらく Lombok サポートは廃れていく)

Game of Streams 🐉: How to Tame and Get the Most from Your Messaging Platforms 👍

Game of Streams 🐉: How to Tame and Get the Most from Your Messaging Platforms | SpringOne | September 2–3, 2020

www.slideshare.net

GitHub - mkheck/game-of-streams-aircraft-edition: Game of Streams meta repo for imperative AND reactive source/processor/sink microservices

メッセージングによるシステム連携を Spring Cloud Stream で簡単に実現してみようという話

  • Spring Boot: Up and Running という本を O’Reilly から出版するみたい (予定では 2021-02 になってる)
    • 「XXX: Up and Runnig」ていう本は日本の「YYY 実践入門」に相当する感じ
  • Auto Configuration とプロパティの定義だけで RabbitMQ や Kafka を利用したメッセージングが簡単に実現できる様子を実演してた
    • プロパティの命名規則に従ってキューやチャンネルを作るのはお勧めできないような気もする
    • デモンストレーションにはいいんだけど

If Hemingway Wrote JavaDocs 👍

If Hemingway Wrote JavaDocs | SpringOne | September 2–3, 2020

www.slideshare.net

Spring Project のテクニカルライターの人がどんなことに気をつけてるか紹介してた。JavaDoc の話はない。

  • 読者には初心者、中堅、エキスパートがいる
    • 釣鐘上の分布をしている
    • 壁を乗り越えて中堅からエキスパートに至る初心者はごくわずか
  • 探し物をしに来ているのであって文章を読みに来ているのではない
  • 冗長な表現をやめて、できるだけ簡潔に表現すること(ヘミングウェイとかの文豪からこの辺の格言を引用してた)
    • 不必要な言葉を消す
      • Before: “The fact that Java is used to implement the web service is an implementation detail -- an important detail, but a detail nonetheless.”
      • After: “Using Java to implement the web service is an implementation detail.”
    • 現在を表す時制にする
      • Before: “In this tutorial, we will define a Web service that is created by a Human Resources department.”
      • After: “In this tutorial, we define a Web service that is created by a Human Resources department.”
    • 短い表現にする
      • “utilize” => “use”
      • “allows you to” => “lets you”
    • 主語を置いて直接的な表現にする
      • Before: “Note that, in Spring-WS, writing the WSDL by hand is not required”
      • After: “Note that, in Spring-WS, you need not write the WSDL by hand.”
  • RFC とか重要な情報への外部リンクを設けるのは大事だけど “ここ” みたいに代名詞をリンク文字列にするのはよくない
  • 文字通りすべての読者を対象に考慮すること
    • ローカルな表現を入れない
    • i.e とか e.g みたいな古いラテン語由来の省略記法は理解できない人が多いので避けること
      • 自分が翻訳するときは軒並み文章に展開してるなぁ
    • 短縮形やジョークを入れない、一貫した用語を使う
    • 文学作品を目指すのではなく、ユーザーヘルプを目指す

Functions: Implement Once, Execut Anyware ! 👍👍

Functions: Implement Once, Execute Anywhere! | SpringOne | September 2–3, 2020

www.slideshare.net

Spring Cloud Function の紹介。

  • Spring Cloud Function は Java 8 Functional Interface の上位版として使える雰囲気がある。特に関数合成とかカリー化とか
    • Functional Interface を Spring Bean として登録、利用できる
  • Spring Cloud Function は FunctionCatalog という SpringBean を提供してる
    • 文字列リテラルで Fuction Bean にアクセスできる
    • たとえば “uppercase” という Bean には catalog.lookup(“uppercase”) でアクセスできる
    • 関数合成もできる
      • funA.andThen(funB)catalog.lookup(“funA | funB”) で実現できる
  • (真偽不明) Function Bean の引数は Spring の Converter で解決してる
    • Function<String, String> という Function Bean があるとする
      • fun.apply(1374) という呼び出しは Integer Converter が作用して Integer => Stringへ変換する
      • fun.apply(“{\”name\”:\”foo\”}”) という呼び出しは JSON Converter が作用して String => Map<String, Object> へ変換する
        • メディアタイプなどで判別している
        • 独自の Converter を作れば任意の Java Object へ変換できる
  • spring-boot-starter-web を追加するだけで Function Bean のための http エンドポイントを公開できる *たとえばuppercaseという Function Bean を登録していたら、http://localhost/uppercase/xxx` みたいにアクセスできる
    • なんかすげー

Making Spring Home (customization & extensibility) 👍👍

Make Spring Home (Spring Customization and Extensibility) | SpringOne | September 2–3, 2020

www.slideshare.net

GitHub - sasiperi/alexa-spring-boot

Spring Boot で Alexa Skill を 作る話。

  • 毎回準備するのは大変なので spring-boot-starter にしたほうがい
    • AutoConfiguration を実装する方法を説明してた
    • Maven Repository に公開するときの注意点も
      • javadoc はついてるかーとか、source はついてるか―とか、署名は大丈夫かーとか
  • 開発者体験を向上するには spring-initilizr から利用できるようにしないといけない
    • spring-initilizr を fork してカスタマイズしてた
  • その場で作ってデモンストレーション
    • Spring Security を利用して OAuth2 の認可コードフローを実装して、Alexa Skill 利用者がアカウントを紐づけする
    • ローカルPC で実行したアプリを ngrok で公開し、Alexa からアクセスできるようにしてた

A Deep Dive into Spring Application Events 👍👍👍

A Deep Dive into Spring Application Events

www.slideshare.net

Spring Data の中の人が Appliation Event について紹介してる。DDD や Event Sourcing の知識があるとわかりやすいな。

基礎

  • ApplicationEventListener のコールバック呼び出しは同期的に行われる
    • @EventListener をメソッドの付けるだけでリスナーになれる
    • イベントの種類はアノテーションで指定してもいいし、メソッド引数の型で指定してもいい
    • @Async を付ければ非同期にもできる
  • Spring の抽象 ApplicationEventPublisher をビジネスロジックに DI するのは嫌だよね
  • Spring Data の抽象クラス Aggregate にはドメインイベントの考え方が実装されてる
    • registerEvent すればアプリケーションイベントを発行できる
    • Eventuate-Tram でも利用してた気がする
    • Baeldung でも詳しく説明されてる

トランザクション制御

  • EventListener はトランザクション範囲に含まれる
    • 自分ではトランザクションを開始しない
    • 途中で失敗したら後続のリスナーは呼び出さない
  • TransactionalEentListener はそれ自体がトランザクション範囲になるイベントリスナー
    • それぞれのリスナーは独立してイベントを受信する
  • 実用例
    • バッチ的なリトライロジックの実現
      • spring-domain-events-starter という個人プロジェクトを利用してるみたい (もう削除されてた)
      • 別々のログを記録する @TransactionalEventListener を用意して、それぞれ成功したら捨てる。すると次回から空振りするようになる

アーキテクチャ

  • Inventory と Orders の関係性を考えてる
    • completeOrder というメソッドにはいろいろな機能追加がありそうだし Inventory を操作するのは違うんじゃないかという疑問
      • トランザクション範囲がどんどん広がってしまう
      • テストを書くと違和感がはっきりする
  • @ModuleTest で疎結合性を検証する
  • イベントで連携する場合はユニットテストじゃなくてインテグレーションテストで検証する
  • ビジネスロジックはきれいに分離できたのでイベントストアを外部化するのは簡単だと思うよ (どうかなぁ🤔)

雑感

  • プレゼンテーション資料に書いてない詳細をひたすら喋りまくる人ばかりで、再生速度を遅くして英語字幕(自動生成)も付けてようやく追いつける感じだった。
  • 巻き舌なインド英語を正確に文字化する YouTube の自動字幕機能はすごい (たとえば purpose をパーパスじゃなくてパルパスと発音するんだよね…)