Future Tech Night #10 に行ってきた #future_tech_night

Future Tech Night #10 に参加しました。オンライン開催。簡単に所感をまとめます。

future.connpass.com

所感

前半は Java 8 から Java 16 で追加された API のおさらいみたいな感じでした。Record の機能は Lombok でまかなえるっていう意見が TL で流れてたけど、標準機能として提供されるところに価値があると思う。

後半は Tomcat の話。Tomcat のコミッターで 詳解 Tomcat の著者。マニアックというだけあって、知らない内容もあってとても参考になりました。

今週末は JJUG CCC かー。

以下、メモから抜粋。

Javaレガシー言語からモダンな言語へ。どこまで知ってる?Java最新事情!

  • Java 8 から Java 16 の API おさらい
  • ラムダ式
  • Stream API
  • Optional
  • Date and Time API
  • var
  • HttpClient (HTTP/2)
  • Switch 式
  • テキストブロック
  • Record
  • instanceOf
  • Sealed Class

Future では 14 を使っているところが多い。16 へのバージョンアップもあるかも。バージョンの追随はコストとの兼ね合い。deprecated な API の調査が大変。

Tomcatコミッタがお送りするちょっとマニアックなコンフィグレーション10選

  • 設定値を外部リソースから読み込む
  • ポートオフセット
  • JSON Error Report
    • デフォルトの HTML ではなく JSON で返す
  • StuckThreadDetectionValve
    • 閾値以上、スタックしたスレッドの stacktrace が出力される
    • スレッドダンプのようなロック情報は見れない
  • レガシーアプリケーションベース
  • 静的クラスタメンバーシップ
    • クラスタリングのメンバーシップはデフォルトではマルチキャスト
    • StaticMembershipService
      • IPアドレスをキャッシュしているので要注意 (今後修正予定)
    • CloudMembershipService
      • k8s 向け
      • Pod に対して Cloud メンバーシップを設定する
      • 公式ドキュメントには記載がない (GitHub を見よう)
  • 組み込み Tomcat のコンフィグソース
    • new Tomcat() したあとの設定はどうするか
    • ConfigurationSource
    • CatalinaBaseConfigurationSource
      • server.xml をパースして設定してくれる
    • -generateCode 起動オプション
  • 多言語対応
    • ログは環境に合わせた言語で出力される
    • POEditor
    • 変なのがあったらコントリビュートしましょう
  • Tomcat 10 以降のバージョン体系
  • TomcatJava EE のサブセットをサポートしている
  • Tomcat 10 は Jakarta EE 9 をサポートする
  • Jakarta EE と併せて Java EE 8 は長めにサポートされそう
  • 自分のアプリケーションをどのバージョンの Tomcat で動かすか
  • Apache/Tomcat の通信は HTTP にした方がよい
    • AJP脆弱性があるため今後はやめる方向になりそう

macOS をアップデートしたあと Command Line Tools のインストールが失敗する

ちょっとハマったので備忘録。brew install でパッケージをインストールしようとしたらこんなエラーが出力された。

Error: The following formula cannot be installed from bottle and must be built from source.
Install the Command Line Tools:
  xcode-select --install

先日、macOS をアップデートした影響で Command Line Tools がなくなったっぽい。言われた通り、xcode-select --install を実行。

$ xcode-select --install

インストーラーが起動してそこそこ時間がかかった挙げ句、「ソフトウェアをインストールできません」と表示される。代わりに Apple Developers から dmg をダウンロードして実行してみたが同様。(こっちもそこそこ時間がかかる...)

解決策

OS アップデート前の Command Line Tools の旧ディレクトリが残っているとインストールが失敗するっぽい。(/Library/Developer/CommandLineTools)

$ sudo rm -rf /Library/Developer/CommandLineTools # 消すのが心配ならリネームでもOK
$ sudo xcode-select --install

現場からは以上です。

ユニコーン企業のひみつ

先日、『ユニコーン企業のひみつ』を購入して読んでみました。

「チームに権限を与える」「チームを信頼する」ことで 自律性のあるチームにする というのが全体を通して書かれており、そのために Spotify が取り組んできたことが紹介されています。

このあたりはなかなか興味深い。

この本の中で「エンタープライズ企業」とか「従来型企業」というのが頻繁に登場してユニコーン企業と比較されてるのですが、これらの前提が極端であまり納得感がない感じがします。

「計画や予算がゴールになりがちでプロダクトにフォーカスできていない」というのは確かにありそうだけど、いわゆる「従来型企業」でも準委任契約のプロジェクトでアジャイルスクラムのような形を取ることは今となっては特に珍しい話ではないと思われます。

ただ、これに関して個人的に悩ましいのは、こういうプロジェクトだとなかなか規模 (売上) がスケールできないところが課題として捉えられてしまうところ。「うまみのないプロジェクト」みたいに言われてしまうと、そのプロジェクトのメンバーは仕事に対する意義を見出しにくくなるような気がします。その点で、リソースに投資して自律性のある小さいチームにするというのは、わりと合理的なのかなって思う今日この頃です。

読みやすくてなかなかおもしろい内容だったし、こういう本を通して自分たちのチームの課題に向き合うきっかけになったらいいのかなって。

Vegeta attack

以前から名前は知ってたけど、パフォーマンステストをするのに Vegeta が手軽に使えて便利そう。README にだいたい書いてあるけど取り急ぎ使いそうなところだけ備忘録。

github.com

$ brew update && brew install vegeta
$ echo "GET http://localhost:8080/" | \
    vegeta attack -rate=10 -duration=60s | \
    tee results.bin | \
    vegeta report

-rate は単位時間あたりのリクエスト数。デフォルトは秒間。分間で指定する場合は -rate=10/m のように書けばよさそう。-duration はテストの実行期間。

リクエストヘッダは -header で指定する。例えば、Authorization ヘッダを付ける場合はこんな感じ。

$ echo "GET http://localhost:8080/" | \
    vegeta attack -header "authorization: Basic $(echo -n '{username}:{password}' | base64)" -rate=10 -duration=60s | \
    ...

実行結果を vegeta report で出力するとこんな感じ。

Requests      [total, rate, throughput]         600, 10.02, 10.01
Duration      [total, attack, wait]             59.956s, 59.902s, 54.164ms
Latencies     [min, mean, 50, 90, 95, 99, max]  38.694ms, 56.504ms, 49.225ms, 70.715ms, 85.368ms, 175.937ms, 576.39ms
Bytes In      [total, mean]                     1059600, 1766.00
Bytes Out     [total, mean]                     0, 0.00
Success       [ratio]                           100.00%
Status Codes  [code:count]                      200:600  
Error Set:
  • Requests
  • Duration
    • total : テスト実行時間の合計 (attack + wait)
    • attack : すべてのリクエスト送信にかかった時間 (total - wait)
    • wait : レスポンスが返るまでの時間 (total - attack)
  • Latencies
    • min, mean, max : レイテンシの最小値, 平均値, 最大値
    • 50, 90, 95, 99 : パーセンタイル
  • Bytes In, Bytes Out
    • total, mean : リクエストボディ, レスポンスボディのバイト数の合計, 平均値
  • Success
  • Status Codes
  • Error Set : エラーレスポンスのステータスコードが列挙される

vegeta plot で実行結果をグラフ表示できる。

$ cat results.bin | vegeta plot > plot.html

f:id:knt_mr:20210507000758p:plain

現場からは以上です。

HIGH OUTPUT MANAGEMENT

以前、あるラジオで紹介されていた HIGH OUTPUT MANAGEMENT を購入して読んでみました。とは言っても購入したのは年初で、途中ちょっと積読しつつようやく読み終えた...。著者の Andrew Grove 氏はインテル社の CEO を務めていた方らしい。

「自身が率いる組織のアウトプットを最大化」をテーマにマネージャーがやるべきことが細かく書かれています。書かれてることをざっくり分類するとこんな感じ?

  • プロセスや品質のモニタリング&改善
  • ミーティング, 1on1
  • チーム運営
  • タスクコントロール
  • 評価, フィードバック
  • 面接

もともとこの本が書かれたのは30年以上前らしい。もちろん加筆や修正はあると思うけど、今では当たり前のように使われている 1on1 やスクラムなんかも、この本の内容がもとになっていたりするんだろうか。いわゆるバイブル的な本なのかもしれないです。

読書メモをこのツイートのリプライにまとめてみました。内容をふりかえりたいときに読み返そう。スレッド全部を貼り付けたかったけどやり方がわからない...。

リクエストの二重送信防止に UIEvent.detail を利用する

更新系のボタンクリックでローディングを表示して二重クリックを防止する実装をよく見かけるが、次のような操作をするとリクエストが二重送信できることがある。

  1. ボタンクリック (ローディング表示)
  2. キーボードの Enter or Space 押下

ボタンクリックでボタンにフォーカスが当たるが、ローディングを表示してもボタンのフォーカスは外れない。なので、キーボードの Enter や Space 押下でボタンの click イベントが走ってリクエストが二重送信される。

たぶん、ボタンを disabled にするのが簡単かもしれないが、以降は UIEvent.detail プロパティを使って回避する方法。

developer.mozilla.org

サンプルコード

サンプルコードでは、ボタンクリックで overlay が表示されてボタンが二重クリックできなくなるが、キーボードの Enter や Space を押下するとコンソールに submit! が何度も表示される。

これに対して、ボタンの click イベントでキャンセルイベントを呼び出すようにすると事象が発生しなくなる。(L49 のコメントアウトを外す)

window.addEventListener('click', cancelKeyEvent, true)

event.detail プロパティには現在のクリック数 (> 0) が設定される。一方、キーボードの Enter や Space 押下のときは値は常に 0 になる。あとは、stopPropagation() でイベントをキャンセルする。

ちなみに event.pointerType === 'mouse'IE 用の判定。

現場からは以上です。