Hands-On Reactive Programming in Spring 5を読んだ(1章)

2021-01-01T17:24:12

Hands-On Reactive Programming in Spring 5を読んだ(1章)

概要

原題がWhy Reactive Spring?であるだけあって、一章は終始なぜReactiveというアプローチを取る必要があるのか、という点に関して重点的に説明されます。

Reactiveというのは複雑なものですが、それそのものを学ぶ前にどのようなシーンで必要とされ、生み出された技術なのか、という点にフォーカスしています。

この記事では、個人的に重要と感じた下記に関して紹介します。

  • Reactiveが必要とされる背景
  • Reactiveシステムに求められているものが何なのか

挙げられている具体例について

ビジネスケースの具体例として、ウェブストアが例に挙げられています。

リアクティブの価値を理解するために、スモールビジネスを開発しているとしましょう。それを、最先端の商品を魅力的な価格で提供するウェブストアであると仮定します。

この分野のプロジェクトの大半がそうであるように、私達はソフトウェアエンジニアを雇い、遭遇する問題を解決することになります。

私達は伝統的な開発アプローチを選択し、いくつかの開発を経てウェブストアを作成しました。
その結果、通常、私達のストアには1時間あたり1000人のユーザが訪れます。通常の需要に応えるため、私達は最新のコンピュータを購入し、TomcatのWebサーバを実行するだけでなく、500個のスレッドプールを設定しました。

大多数のユーザリクエストの平均応答時間は約250msであり、その厚生の容量を素朴に計算すると、1秒あたり2000件のユーザリクエストを処理する性能があると言えます。

統計によると、先にのべたユーザ数では、平均して1秒あたり1000件のリクエストが発生しています。つまり、現時点の負荷に対しては十分な容量を持ったシステムを構築することができています。

ところが、11月最後の金曜日であるブラックフライデーではそうは行きませんでした。

いつの間にか予想を超える負荷がかかっていました。スレッドプールにはユーザのリクエストを処理するための空きスレッドがなく、結局レスポンスタイムの悪化と断続的なサービス停止を引き起こしました。

この時点でいくつかのユーザのリクエストを失い、クライアントは不満を感じて競合他社に流出しました。

結果、多くの潜在的顧客と売上を失い、店舗の評価を下げることになりました。これらはすべて、仕事量の増加に耐えられなかったことに起因しています。

Hands-On Reactive Programming in Spring 5, 1章より。翻訳は私なので間違っている可能性あります。

このシンプルなビジネスケースと、抱える問題点は現実のシステムにも十分適応できる話です。つまるところ、リアクティブではないシステムは変化にとても弱く、極端な負荷の増加に対応することが難しいです。

これは、クラウドを選択しても同じです。たとえオートスケールを設定していてもスパイクには耐えられません。時間を区切ったセールというのは恐ろしいもので、0時をまたいだ瞬間に数百倍に登るアクセスが瞬間的に行われることがままあります。

さて、こういった変化にどう対応するかという観点で、本書ではリアクティブ宣言と呼ばれるものが引用されており、頑強(ロバスト)なシステムを構築する上で必要な要素と、それを叶えるためのメッセージ駆動モデルに関して説明されています。

リアクティブ宣言

詳細は上記リンクを閲覧してください。英語版のマニフェストでは下記のような画像ですが、日本語訳されて掲載されています。
(また、本書で使われている画像はPDFにまとめてカラー版のものが公開されています)

本書いわく、分散システムで実装されたビジネスの一番の価値は即応性(Responsive)にあるとされます。
応答性の高いシステムを実現するには、弾力性(Elastic)、対障害性(Resilient)を満たす必要があり、それを実現する方法としてメッセージ駆動が存在すると説かれています。

字面で勘違いしがちですが、即応性は下記のように定義されています。

即応性 (Responsive): システムは可能な限りすみやかに応答する。即応性とは使い勝手と実用性の基盤だが、しかしそれだけではなく、問題が素早く検出され効果的に対処できることを意味する。即応性のあるシステムは、迅速で、かつ一貫した応答時間を提供することに主眼を置く。システムは応答時間に信頼性のある上限を確立し、一貫した品質のサービスを供給する。この一貫した挙動によってエラー処理が単純化され、エンドユーザの信頼を醸成し、さらなる相互作用を促す。

リアクティブ宣言より

学んだもの

本書のまとめでも書かれていますが、自分の大きな気付きとして「Reactive」はアーキテクチャの面とプログラミングの面の2面で成り立っているという事がありました。

プログラミングとしてのReactiveにフォーカスすると、自分のイメージとしてはノンブロッキングなプログラミングである、ということになるのですが(これも一面を捉えてるだけに過ぎないのだとは思う)、アーキテクチャとしてのReactiveはリアクティブ宣言にあるように複数の要件を満たしたシステムのことを指しています。ノンブロッキングであることはメッセージ駆動を実現する手段の一つでしかありません。

本記事ではフォーカスしていませんが、SpringFrameworkにReactiveがきちんと取り入れられたのは最近の話で、少なくともVer4の段階ではあまりうまく統合されていなかったと記載されていました。
その流れで、ノンブロッキングでないプログラミングがいかにReactiveの要件を満たせないかという検証が長々とあったりして読み応えがありました。

Webサービス開発ではマルチスレッドを意図的に書くことは禁忌になる面が多いので、非同期プログラミングの知見はどうしても薄くなってるなという感想です。