小さなウェブは美しい
原文は Ben Hoyt により に公開されました。 このブログを購読する
要約:小さなウェブサイトは見た目が魅力的であるだけでなく、巨大テック企業に魂を売ることへの抵抗にも役立つと私は考えています。このエッセイでは、「小さなウェブ」というビジョンと、それを支える小さなソフトウェアやアーキテクチャについて紹介します。おまけとして、マイクロサービスについての小言も少々。
今から15年ほど前、私はE・F・シューマッハーの『Small is Beautiful』を読みました。経済学には特に興味がなかったのですが、そのメッセージには心を動かされました。それ以上に惹かれたのは、本のタイトルの簡潔で詩的な響きでした。質素な生い立ちや、自分自身の美意識とも共鳴するものだったのです。
そろそろテクノロジー版のあの本が必要な時期だと思います。ウェブ開発についての章を加えて、たとえばこんなタイトルで――『The Small Web is Beautiful: A Study of Web Development as if People Mattered(小さなウェブは美しい――人間を大切にするウェブ開発の研究)』。誰かがそれを書くまでは、このエッセイで代用することにします。
ここで言いたいことには二つの側面があります。一つは小さなチームや会社についてです。これについてはここではあまり触れませんが、Basecampをはじめ多くの人が語っています。このエッセイで私が焦点を当てたいのは、小さなウェブサイトとアーキテクチャです。
「小さなウェブ」について語ったのは私が初めてではありません。ただ、意外なことに、その言葉を使って論じている人はそれほど多くありません。私が見つけられた主なページは次のとおりです:
- Rediscovering the Small Web by Parimal Satyal:商業的なウェブとは対照的な、小さく独立した(時にはレトロな)ウェブサイトの喜びについて書かれた素晴らしい記事です。
- What is the Small Web?, by Aral Balkan of the Small Technology Foundation:具体的な内容というよりは巨大テックによる監視に反対するマニフェストに近いものですが、それでも興味深い内容です。
これほど高速でメモリも潤沢な時代に、なぜあえて小ささを目指すのか。理由はいくつもありますが、私にとって特に重要なのは次の点です:
- 可動部品が少ない。より堅牢なシステムを作りやすく、何か問題が起きても修正しやすくなります。
- 小さなソフトウェアは速い。ダウンロードするデータが少なく、コンピュータのメモリを圧迫しません。
- 消費電力が少ない。これは地球を守るという大きなスケールでも重要ですが、スマートフォンやノートPCのバッテリー持ちという身近なスケールでも重要です。
- 軽やかで質素な美意識。これは個人的な好みですが、後述するように、私だけではありません。
では、詳しく見ていきましょう。さまざまな切り口を、それぞれ見出しを立てて取り上げていきます。
小さなソフトウェア
小さなウェブについて語るなら、まずは小さなソフトウェアから始めなければなりません。
10代の頃、私はx86アセンブリとForthでプログラミングを学びました――変わった選択かもしれませんが、父がForthに熱中していた影響ですし、何より言語自体がとてもシンプルで、自分でブートストラップしたコンパイラを書けてしまうところが気に入っていました。
キャリアの出発点は組み込みプログラマでした。といっても「組み込みLinux」ではなく、16KBのRAMがあれば十分すぎるほどというマイクロコントローラの世界です。私の今のノートPCは16GBのRAMを積んでいますが、今日の基準ではそれほど多いわけでもありません。当時は、その100万分の1のメモリでIPネットワークにつながる製品を作っていたのです。あのようなマイコンは文字通りチップ並みに安く、今でも小型の電子機器やセンサー、IoT製品などで広く使われています。
1バイト単位でやりくりし、サイズ最適化を有効にしてコンパイルし、バッファを使い回す。現代のウェブ開発とはまったく別世界です。そこではJavaScriptアプリをコンパイルすると1MBのバンドルになり、Pythonのオブジェクトは中身のデータを入れる前からヘッダだけで16バイトを食い、Goのhello worldですら本当のコードを書く前から2MBのバイナリになります。
どうすれば小さなプログラムを作れるのでしょうか。主なポイントはサイズを気にかけることだと思いますが、たいていの人はそんな時間はないと考えています。組み込み開発以外では、デモシーンというプログラミングのサブカルチャーがまさにそれを気にかけています。彼らは4KBデモのコンペを開催しています。4096バイトの実行ファイルにどれだけ強烈なグラフィックを詰め込めるかを競うのです。多くのファビコンよりも小さいサイズです!(Elevatedやcdakは、最も評価の高い4Kデモの2つです。)多くのデモシーナーがその後ゲーム開発者になっています。
実行ファイルのサイズだけの話ではありません……次にコマンドラインツールを作るとき、GoやRust、あるいはCを使えば、PythonやJavaで作る同等のものよりもはるかに速く、小さく、メモリ使用量も少なくなります。しかもインストールも簡単です。なぜそうなるのかわからない方は、ぜひ学んでみてください。(このエッセイの本筋ではないので要約すると、Go、Rust、Cはすぐに実行できる機械語にコンパイルされ、仮想マシンを抱え込まず、整数のようなオブジェクトに余計なメモリオーバーヘッドがかからないからです。)
では、同じ原則をウェブ開発に応用してみてはどうでしょうか。ウェブの世界で主なコツは、どの依存関係を取り込むかに注意すること、そしてそれらがさらに何を引き込んでくるかに注意することだと思います。端的に言えば、node_modulesを理解すること――あるいはもっと言えば、no node_modulesを目指すことです。詳しくは後述します。
Pascalで知られるニクラウス・ヴィルトは、1995年にA Plea for Lean Software [PDF]という有名な論文を書いています。彼の見立てでは、「複雑さの主な原因は、ソフトウェアベンダーがユーザーが望む機能をほとんど批判なく採用することにあり」、「システムの能力が機能の数で測られるとき、量は質よりも重要になってしまう」のだといいます。続けて彼は、複雑さの問題解決に役立つと考えたコンピュータ言語(いくつかの点でGoを思い起こさせます)およびOSであるOberonについて述べています。ぜひ読む価値があります!
私はこの問題について何年も前から考えてきました――2008年には、肥大化したAdobe Readerを皮肉った記事を書いています。Thank you, Adobe Reader 9! 当時でさえ33MBのダウンロード、220MBのディスク容量を要求していました(今では150MBのダウンロードになっています。どれだけディスクを食うのかは、最近はインストールしていないのでわかりません)。
ただ不満を言うだけでなく、どうすれば実際にこの問題を解決できるでしょうか。具体的に、私たちは次のことを始める必要があると思います:
- サイズを気にかける:当たり前に聞こえますが、重要だと思われて初めて物事は変わります。
- 計測する:実行ファイルのサイズと、プログラムのメモリ使用量の両方を。できれば経時的に計測し、リリースごとにx%以上増えたらブロッカーとして扱う。あるいは定期的にメモリ削減スプリントを開催するのもよいでしょう。
- 言語:可能性のあるバックエンド言語を選ぶ。例えばRust、CやC++、サーバーならGoなど。これらの言語が常に最適というわけではありません(データ変換スクリプトのような用途には向きません)が、小さな実行ファイルを生成し、CLIやデスクトップアプリには適しています。
- 削る:機能を絞り込む。少数精鋭の高品質な機能を目指しましょう。私の車は空を飛べないし水に浮かぶこともできませんが、それで構いません――よく走ってくれるからです。
- 新機能にノーと言う:自分の思想に本当に合致する場合や、プロジェクトの寿命全体で見てコスト以上の価値をもたらす場合を除いて。
- 依存関係:取り込む依存関係それぞれのサイズと複雑さを理解する。可能なら組み込みライブラリだけで済ませましょう。
小さなウェブサイト
小さなウェブサイトに関心を持つ人が増えてきているのは嬉しいことです。
数か月前、Hacker Newsでは自分の小さなウェブサイトを登録できるさまざまな「クラブ」についての投稿が相次ぎました。1MB Club(コメント)、512KB Club(コメント)、250KB Club(コメント)、さらには10KB Club(コメント)まで。ミニマリズムへの関心が再燃していることを示す楽しい指標だと思います。ただ、サイズだけでは不十分だとも言っておきたいです――中身のない2KBのサイトに大した価値はなく、512KBの重く遅いJavaScriptを抱えたページは、選び抜かれた画像で構成されたキビキビ動く4MBのサイトよりもたちが悪いこともあるのですから。
私のお気に入りの小さなウェブサイトをいくつか紹介します:
Hacker News:個人的にはミニマルでブルータリストともいえるデザインが好きですが、それ以上に軽さが気に入っています。試しにトップページをダウンロードしてみたところ、すべてのリソースを含めても転送量はわずか21KB(非圧縮で61KB)でした。巨大なコメントスレッドがあるページでも、圧縮データで約100KB程度で素早く読み込まれます。肥大化してしまったRedditと比べると雲泥の差です。Hacker Newsよ、このままでいてくれ!
Lobsters:似たようなニュース/投票サイトですが、少しだけ「モダン」なスタイルになっています。多少のJavaScriptやプロフィールアイコンは使っていますが、それでもクリーンで高速で、トップページの総転送量はわずか102KBです。良いウェブサイトを作るのに何メガバイトも必要ないことがわかります。
Sourcehut:Drew DeVault氏のビジネスのコンセプト自体も好きですが、ウェブサイトが小さく無駄がないところが特に気に入っています。彼はSoftware Forge Performance Indexというミニサイトを立ち上げ、有名なソースコードホスティングサイトのサイズやブラウザパフォーマンスを計測していますが、Sourcehutはずば抜けて軽く高速です。トップページでさえ、スクリーンショットのサムネイルをいくつか含めて81KBしかありません。
SQLite:SQLiteは小さくパワフルなSQLデータベースエンジンであるだけでなく、ウェブサイト自体も驚くほど小さくコンテンツが充実しています。7000語に及ぶテストに関するページでさえ70KBしかありません。どうやって実現しているのか。魔法ではありません。高品質なテキストコンテンツに集中し、最小限のCSS、JavaScriptなし、画像は小さなロゴと一部のSVGだけ、という徹底ぶりです。
LWN:少し贔屓が入りますが、私自身記事を寄稿したこともあり、Linuxやプログラミングのニュースサイトとして素晴らしいと思っています。技術的に極めて質の高いコンテンツ(執筆者へのハードルも高い)を提供しています。かなりニッチで、「コンテンツの質にこだわり、毎年CSSを更新することにはこだわらない」という佇まいですが、23年間にわたって素晴らしいコンテンツを出し続けています。トップページのダウンロード量はわずか44KB(非圧縮で90KB)です。
Dan Luuのブログ:これはかなりストイックな例です。インラインCSSはわずか200バイト程度(ページはほぼ装飾なし)、HTMLソースには改行文字すら含まれていません。ある意味面白いこだわりですが、一方で20KBのGoogle AnalyticsのJavaScriptを読み込んでいるのですが……
ある友人が指摘していたように、これらのウェブサイトには「アンチ美学という美学」のようなものがあります。私はそれをまったく気に入っていますが、一方で、小さいからといって見た目が悪くなければならないわけではありません。小さなウェブのアプローチを取り入れつつ、よりタイポグラフィ的に魅力的な個人ブログやサイトも増えてきています:
- Armin Ronacher’s Thoughts and Writings
- Chris Wellons’ “Null program” blog
- Eric Radman’s BSD and SQL blog
- Hugo Tunius’ programming blog
- James Hague’s “Programming in the Twenty-First Century”
- Julia Evans’ programming blog
他にも数えきれないほどあります。プログラマーのSijmen Mulder氏はテキストのみのウェブサイトの素敵なリストを作っています――小さいことと厳密には同じではありませんが、確実に重なる部分があります!
しかし、重要なのは単なるサイズではないということです。大切なのは「小ささのエトス」です。サイトを訪れるユーザーのことを考えること。ページが速く読み込まれ、読みやすく、興味深いコンテンツがあり、GoogleやFacebookのトラッカーのために大量のJavaScriptを読み込むことがないようにすること。ゼロからウェブサイトを作ることが誰にでも向いているわけではありませんが、私たちのように作る人間にとっては、小さく質を量より重視するサイトを生み出すテンプレートやツールを広めていけるかもしれません。
このウェブサイトについては、クラフトビールを作るヒップスターのように、HTMLとCSSの1バイト1バイトを手作業で愛情を込めて作り上げました。冗談はさておき、良いコンテンツに注力するのであれば、ほんの数行のHTMLとCSSでシンプルなテンプレートをゼロから作るのは難しくありません。小さく高速で、そしてあなただけのものになります。
このエッセイの読み込み時の転送量は、ファビコンと解析スクリプトを含めて約23KB(非圧縮で56KB)です。小さく、速く、デスクトップでもモバイルでも読みやすい。見た目も悪くないと思いますが、何よりコンテンツ中心のミニマルなデザインを目指しています。
HTMLとCSSを小さく保つことに加えて、画像は適切に圧縮するようにしてください。基本は二つです。カメラから取り出した超高解像度の画像をそのままアップロードしないこと、そして写真はJPEGで適度に圧縮すること(スクリーンショットやベクターアートはPNGで)。大きな画像でも、たいていは75%や80%の圧縮でJPEGノイズのない十分な画質を保てます。例えば、私のサイドビジネスのトップページの上部にある大きな1920x775の画像は、わずか300KBです。
ヒーローイメージについて言えば、ブログ記事の冒頭に大きくて無関係な画像を置く必要はありません。ページの重量を数百KB(時には数MB)増やすだけで、何の価値ももたらさないからです。そして記事中にアニメーションGIFをばらまくのもやめてください。画面上で何かが動いていると、テキストを読むのに集中できなくなります――私だけではない はずです。バイト数に見合う価値を提供する、関連性のあるストックではない画像を載せましょう。雑誌の記事のように、テキストだけでも構わないのです。
IndieWeb.orgはこの点で素晴らしいリソースです。ただし彼らは「small」ではなく「indie」という言葉を使っています。このムーブメントはSmall Technology Foundation(デジタルなグリーンウォッシュだと批判されたことさえあります)よりも有機的に見えますし、Wikiにははるかに多くの実用的なコンテンツがあります。IndieWebは地域ごとのHomebrew Website ClubやIndieWebCampミートアップも推進しています。
サーバーサイドを重視し、JavaScriptは控えめに
JavaScriptはウェブにとって諸刃の剣であり、小さなウェブサイトにとっては害になることの方が多いです。ダウンロードサイズと時間が増え、パフォーマンスを損ない、アクセシビリティにも悪影響を及ぼし、使い方を誤ればSEOにも悪影響があります。しかも、コンテンツ中心のウェブサイトであれば、そもそもそれほど役に立たないことも多いのです。
誤解しないでください。JavaScriptが避けられない場面もありますし、適材適所では素晴らしいものです。GmailやGoogle Mapsのようなブラウザベースのアプリケーションを開発するなら、ほぼ確実にJavaScriptを使うべきでしょう。しかし、次にブログや企業の紹介サイト、プロジェクトのドキュメントサイトを作るときは、ぜひプレーンなHTMLとCSSを検討してみてください。
多くのサイトがそうであるように、あなたのサイトがその中間で軽いインタラクションを含む場合でも、必要な部分にだけJavaScriptを使うことを考えてみてください。フォームを一つ追加するためだけに、サイト全体をReactやReduxで作り直す必要はありません。サーバー側でHTMLを生成することは、今でも高速なウェブサイトを作る有効な手段です。
Stack Overflowはその好例です。彼らは当初からページをサーバー側でレンダリングし、レンダリング時間を計測・削減することでパフォーマンスを機能と捉えてきました。Stack OverflowのコードはJeff Atwood時代からかなり変わっているはずです――今では広告のために大量の追加リクエストを発行しています――が、それでもコンテンツは速く読み込まれます。
Hacker News(またまた登場です)はサーバーサイドの古典です。たった一つの小さなJavaScriptファイルで投票機能を担い、あとはサーバーが生成したHTMLがすべてをまかないます。そしてどうやら今でも1台のマシンで動いているそうです。
15年ほど前、プログレッシブ・エンハンスメントという素晴らしい考え方がありました。誰にでも使えるHTMLコンテンツを提供しつつ、JavaScriptが有効だったり回線が速かったりするユーザーには、より洗練されたUIを持つ強化版を提供するというアイデアです。実際、Hacker News自体がプログレッシブ・エンハンスメントを採用しています。2021年になった今でも、JavaScriptをオフにして投票ボタンを利用できます。投票のたびにページの再読み込みが必要になるため多少ぎこちなくなりますが、問題なく動作します。
プログレッシブ・エンハンスメントは2021年でもまだ意味があるのでしょうか。議論の余地はありますが、JavaScriptをオフにする、あるいは信頼できるサイトでのみ有効にするという頑固な人もまだいます。しかし、私が最も重要だと思うのはその考え方です。開発者がパフォーマンスやサイズ、そして多様なユーザーのことを気にかけている姿勢を示すからです。もしHacker Newsの投票がJavaScriptなしで動かなかったとしても、それは大きな問題ではないでしょう――でも、動くということ自体に、ある種のオタク的なこだわりが表れています。しかも、使われているJavaScriptはわずか2KB(非圧縮で5KB)なのです。
Redditのトップページが読み込む8MB(非圧縮で14MB)と比べてみてください。しかも201回ものリクエストが発生します――冗談抜きで!――そのほとんどが広告やトラッキングのためのJavaScriptです。素晴らしいですね……
もちろん、このように開発するのに「フレームワーク」は必要ありませんが、このスタイルのサーバーサイド開発を容易にするツールはいくつかあります。Basecampの人たちによるTurbolinksは初期の例で、今ではTurboに置き換わり、彼らのメールサービスであるHeyを支えているそうです。私は個人的に使ったことはありませんが、アイデアは巧妙で(そして驚くほど昔ながらです)。通常のリンクやフォーム送信を使い、プレーンなHTMLを配信しつつ、利用可能であればWebSocketやJavaScriptで高速化するというものです。ちょうど今日も、Hacker Newsに「ウェブソフトウェアの未来はHTML-over-WebSocketsにある」と主張する新しい記事が投稿されていました。Heyを見る限り、この手法は高速です!
一方で、どうせJavaScriptが必要になるのであれば、ページ全体にJavaScriptを使うことで全体の複雑さをむしろ減らせる場合もあります。例えば、私の結婚式の引き出物登録サイトの登録ページはクライアント側でレンダリングされています(実際にはJavaScriptにコンパイルされるElmを使っています)。JavaScriptによるインタラクティビティが必要ですし(単なるコンテンツというより「シングルページアプリケーション」に近い)、これらのページにサーバーサイドレンダリングやSEOは必要ありません。トップページはシンプルなサーバーレンダリングのテンプレートですが、登録ページは完全にクライアントレンダリングです。
静的サイトとサイトジェネレーター
最近また注目を集めているものに、静的ウェブサイト(昔は単に「ウェブサイト」と呼ばれていました)があります。静的なHTML(とCSSやJavaScript)を静的ファイルサーバーにアップロードする、それだけです。
それを発展させたものとして、多くの「静的サイトジェネレーター」が存在します。これらはシンプルなテンプレートから静的サイトを生成するツールで、サイトのヘッダーやフッターをすべてのHTMLファイルに手作業でコピーする必要がなくなります。記事を追加したり変更を加えたりしたら、スクリプトを実行して再生成するだけです。シンプルなサイトやブログ、あるいはニュースサイトを運営するのであれば、これは素晴らしい方法です。結局のところ、それはインタラクティブなアプリケーションではなくコンテンツなのですから。
このサイトでは、無料でSSLに対応し、変更をプッシュするたびにJekyll静的サイトジェネレーターで自動的にサイトをビルドしてくれるという理由でGitHub Pagesを使っています。標準のヘッダーを用意し、同じCSSをすべてのページで簡単に使い回せますが、必要であれば複数のテンプレートや「レイアウト」を用意することもできます。ほとんどの人が私のサイトでは1、2記事しか見ないので、CSSはインラインで埋め込んでいます。HTTP/2ではそれほど違いはありませんが、LighthouseではインラインCSSで約200ms、外部CSSで300msという結果でした。
シンプルなJekyllページがどのようなものか、例としてこのエッセイの冒頭部分をお見せします:
---
layout: default
title: "The small web is beautiful"
permalink: /writings/the-small-web-is-beautiful/
description: A vision for the "small web", small software, and ...
---
Markdown text here.私はHugoも使ったことがあります。これはGoで書かれた非常に高速な静的サイトジェネレーターで、数千ページある大規模なサイトでも数秒で生成できます。他にもたくさんの選択肢があります。
依存関係は少なく
ソフトウェア(やJavaScriptバンドル)のサイズを膨れ上がらせるものほど、サードパーティの依存関係ほど手っ取り早いものはありません。ウェブプロジェクトのnode_modulesディレクトリを見るたびに気が滅入ります――あの中にある膨大な量のものを思うだけで悲しくなります。
言語によって「依存関係の文化」は異なるようです。JavaScriptはもちろん、「ライブラリにできるものはライブラリにすべき」という姿勢で悪名高く、left-pad騒動や、3行しかないisarrayのような極小ライブラリを生み出しました。Moment.jsのような大きく重いパッケージもあり、圧縮しても160KBにもなります。すべてのロケールを必要としなければサイズを小さくする方法はありますが、デフォルトではないため、ほとんどの人はそうしません(date-fnsのようなよりモジュール化されたアプローチを選ぶ方がよいでしょう)。
Goは最近のmodulesツールによって優れた依存関係管理を備えるようになりましたが、「可能なら標準ライブラリを使おう」という文化もあります。Russ Cox氏は依存関係を安易に取り込むことの欠点を論じた優れたエッセイOur Software Dependency Problemを書いています。Goの共同作成者であるRob Pike氏は、これをGo proverbsの一つにまでしています。「A little copying is better than a little dependency.(ちょっとしたコピーは、ちょっとした依存関係よりましだ)」お察しのとおり、私はこのミニマリストなアプローチが好きです。障害点を減らすだけでなく、プログラムも小さくなるからです。
Python、Ruby、Java、C#はその中間あたりに位置するようです。ある程度の依存関係は使われますが、私が見てきた限りではより慎重に扱われており、node_modulesほど手に負えなくなることはありません。もっとも、Python(や他の言語)はJavaScriptよりも標準ライブラリが充実しているため、単純な比較は少し不公平ではあります。
YouMightNotNeedjQuery.comというウェブサイトでは、ライブラリが必要だと思い込んでいるタスクの多くが、実際にはプレーンなJavaScriptでいかに簡単にできるかを示しています。例えば、私のプロジェクトの一つでは、次のような関数を使ってプレーンなXMLHttpRequestでAPIリクエストを行っています:
function postJson(url, data, callback) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState === xhr.DONE) {
callback(xhr.status, JSON.parse(xhr.responseText));
}
};
xhr.open("POST", url, true);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.send(JSON.stringify(data));
}教訓は、依存関係を追加する前によく考えることです。ウェブサイトもプログラムもより小さく信頼性の高いものになり、後できっとRuss Cox氏に感謝することになるでしょう。
小さなアナリティクス
ほとんどのウェブサイト運営者は、どれくらいの訪問者がどこから来ているのかを知るために、何らかのアクセス解析を求めます。定番のツールはGoogle Analyticsです。簡単に導入でき、UIもかなり充実しています。しかしコストもあります。ページにかなりの重量を加え(19KBのJavaScript、非圧縮で46KB)、大量のユーザーデータをGoogleに収集させてしまうのです。
ここでも、近年はより小さくプライバシーに配慮した解析システムへの関心が再び高まっています。ちょうど今朝、Hacker Newsで高く評価されていた「Google Analytics: Stop feeding the beast」という刺激的な記事を読みました。
昨年、私はこのテーマでLWNに2本の記事を書いたので、ここではあまり詳しくは触れません:
- Lightweight alternatives to Google Analytics:軽量でオープンソース、プライバシーに配慮した代替手段への置き換えについて。具体的にはGoatCounterとPlausibleを取り上げています。
- More alternatives to Google Analytics:よりヘビーな代替手段と、ログベースの解析ツールについての簡単な紹介です。
このウェブサイトではGoatCounterを使っています。低コストのホスト型サービス(非商用なら無料)としても、セルフホスト型ツールとしても利用できます。Martin氏がここでやっていること、そしてこのツールがいかに小さくシンプルであるかが私はとても気に入っています。余計な機能はなく、たいていの人が求める基本的なトラフィック数だけを提供してくれます。
小さなアーキテクチャ(マイクロサービスではない)
小さなウェブサイトはユーザーにとって素晴らしいものですが、小さなアーキテクチャは開発者にとって素晴らしいものです。小さくシンプルなコードベースはメンテナンスが容易で、相互作用する箇所が多い大規模で複雑なシステムよりもバグが少なくなります。
「あちこちでマイクロサービス」というバズワードは大きな問題だと私は考えています。マイクロサービスはGoogleやAmazonではうまく使われているかもしれませんが、ほとんどの企業はそのように構築する必要はありません。コード、API定義、ネットワーキング、デプロイ、サーバーインフラ、監視、データベーストランザクション――システムのほぼすべての側面が複雑になります。なぜでしょうか。
- コード:たくさんの小さなリポジトリがあり、場合によっては言語も異なり、それぞれが他のサービスと通信する手段(HTTP経由のJSON、gRPCなど)を必要とします。モノリシックなシステムなら、すべてが一つの言語(小さなチームにははるかに適しています)で、他のモジュールを呼び出すのは単なる関数呼び出しであり、システム全体のリファクタリングも比較的容易です(特にGoやJavaのような静的型付け言語では)。
- API定義:多くのサービスが互いに通信するため、突然それらがどのように通信するかの標準化されたインターフェースが必要になります。gRPCやJSONスキーマ定義の設定に多くの時間を費やすことになります。一つのコードベースであれば、関数シグネチャそのものがAPI定義です。
- ネットワーキング:マイクロサービスでは関数呼び出しがネットワーク呼び出しになり、ネットワークインフラのセットアップ、タイムアウトやリトライの検討、サービス間認証の設計にまで時間を割くことになります。モノリシックなシステムでは、データベースやクラウドプロバイダー、ユーザーと通信するときだけネットワーキングを気にすればよいのです。
- デプロイ:以前勤めていた会社では、マイクロサービスで構築し始めた途端、急に凝ったデプロイツールと、それらすべてを管理する専任のインフラチームが必要になりました。数個のサービスだけをデプロイするのであれば、はるかに少ないもので済みます。
- サーバーインフラ:おそらく新しいインフラをセットアップする必要があるでしょう――たくさんの小さな仮想マシンや、Kubernetesベースのシステムです。Kubernetes自体が複雑な分散アプリケーションであり(Google自身でさえ複雑すぎると認めています)、適切に運用するには多大な労力――あるいは多額の費用――がかかります。
- 監視:問題をデバッグするために、Datadogのような高価な分散監視ソフトウェアが必要になります。障害が発生すると、どのサービスに責任があるのか、どのチームを呼び出すべきかなどを突き止めるのに慌てふためくことになります。単一サービスのスタックトレースや問題と比べれば、その差は歴然です。
- データベーストランザクション:これはマイクロサービスアーキテクチャでは困難、あるいは不可能です。うまく設計して回避できるかもしれませんが、それも簡単ではありません。モノリスであれば、
BEGIN ... COMMITとタイプするだけです。データベースライブラリがどう綴るにせよ。
以前から言われていることですが、マイクロサービスは技術的な問題ではなく人的な問題を解決するものです。しかしコンウェイの法則には注意してください。アーキテクチャは組織構造を模倣します。あるいはその逆で、マイクロサービスが必要とするアーキテクチャ――たくさんの小さなチームにたくさんのエンジニアがいて、各チームが数個のマイクロサービスを管理する――に合わせて採用や組織再編をしなければならなくなります。
だからといってマイクロサービスが常に間違った選択だというわけではありません。巨大なエンジニアリング組織では必要になることもあるでしょう。しかし、そのような会社で働いているのであれば、おそらく何年も前からマイクロサービスを使っているはずです。「Google規模」ではないのであれば、その開発手法を真似する前によく考えた方がよいでしょう。
では代替案は何でしょうか。「モノリス」という言葉には悪い評判がありますが、私はBasecampのDavidが言うようにモノリスは壮大であり得るという意見に同意します。Basecampは大規模なモノリシックアプリケーションですが、わずか十数人のプログラマで運用しています。Davidはすぐに指摘していますが、「壮大なモノリスが栄光への安全確実な道を提供してくれるわけではない」のです。それでも考え、設計し、良いコードを書かなければなりません。
ありがたいことに、人々はカーゴカルトから立ち直りつつあります。「why not microservices」で検索すれば、このテーマに関する優れた記事がたくさん見つかります。最近読んだものの一つに、TailscaleによるModules, monoliths, and microservicesがあります。
では、私からのアドバイスは?
- 会社名がGoogleやAmazonでない限り、モノリスから始めましょう。
- 問題が出始めたら、痛みのある部分を最適化またはリファクタリングしましょう。
- それでも問題があれば、より大きなサーバーを買いましょう。
- 分割すべき具体的な技術的理由があるなら、その問題を解決しましょう。
- それでも問題が残るなら、分割が必要なコンポーネントだけを切り離しましょう。デプロイや監視の対象が2つのサービスになりますが、マイクロサービスに全面移行するよりはるかにシンプルです。
さて、当初の予定よりもマイクロサービス批判が長くなってしまいましたが、まあよしとしましょう。
反例としては、やはりStack Overflowが思い浮かびます。ウェブで最も忙しいサイトの一つでありながら、比較的シンプルな2層のアーキテクチャを垂直スケール――つまり何百もの小さなサーバーではなく、メモリを大量に積んだ大きなサーバー――で拡張しています。ウェブサーバー9台と非常に強力なSQLサーバー4台に加え、タグエンジン、Redis、Elasticsearch、HAProxy用のサーバーが数台という構成です。このアーキテクチャのおかげで優れたパフォーマンスを発揮し、小さなチームでの開発が可能になっています。
私自身のサイドビジネスであるGiftyWeddings.comは、Stack Overflowとは比べものにならないほどトラフィックは少ないですが、利用可能な中で最も小さいEC2インスタンスであるt2.micro上で、SQLiteを備えたGoのHTTPサーバーを使っています。月額約8ドルで、メンテナンスすべきインフラはこの小さな一つだけです。デプロイにはAnsibleを使っています――これもまたシンプルなアーキテクチャの好例で、「とにかくsshを使え」に尽きます。
SQLiteといえば、ウェブサイトの運営にSQLiteを使うことを推奨する開発者が増えてきています。SQLiteの「when to use SQLite」ページには、「1日あたり10万ヒット未満のサイトであれば、SQLiteで問題なく動作するはずです。1日10万ヒットという数字は控えめな見積もりであり、厳密な上限ではありません。SQLiteはその10倍のトラフィックでも動作することが実証されています」と書かれています。その他のSQLite成功事例をいくつか紹介します:
- LitestreamはSQLiteにストリーミングレプリケーションを提供するオープンソースツールです。作者であるBen Johnson氏の記事Why I Built Litestreamをお読みください。
- Go開発者のDavid Crawshaw氏は、GoとSQLiteによる「ワンプロセスプログラミング」と呼ぶものについての記事を書いています。「N台のコンピュータでやる必要がないなら1台でやれ」という彼の言葉に要約されます。彼は他のドライバよりもSQLite固有の機能を多くサポートするGo用SQLiteライブラリも作成しました。
- Peewee ORMの作者であるCharles Leifer氏は、2016年当時に「Five reasons you should use SQLite in 2016」という記事を書きましたが、2021年でも非常に関連性があります。「SQLiteをぜひ試してみてください。本番環境に耐えないとか、ウェブアプリケーションでの使用に適さないといったFUDを信じないでほしい」という言葉で締めくくられています。
- Crave CookieのSam Eaton氏は、1台のサーバーとSQLiteで月商20万ドル(すごい!)のサイドビジネスを運営しています。Indie Hackersのインタビューをお読みください。
まとめ
企業はこれからも、企業らしく、見栄えがよく肥大化した「コンバージョン率の高い」ウェブサイトを作り続けるでしょう。職場で影響力を持ち、家に帰ってパートナーに「ねえ、ウェブを小さくしてきたよ」と言えるかもしれません。あるいは、個人プロジェクトだけで小さなウェブに注力するかもしれません。(断っておきますが、私自身は主に後者です――日々の仕事ではJujuに取り組んでいますが、これはほとんどの尺度で小さなシステムではありません。)
いずれにせよ、「小さなウェブ」という言葉も、その美意識も魅力的だと私は信じています。必ずしも視覚的な意味ではなく、自分で構築し、そのすべてを理解し、1台のサーバーや静的ファイルホストで運用しているという意味での魅力です。
小さなウェブサイトの優れた例は数千とあり、シンプルなアーキテクチャを作る方法も何百通りもあります――このエッセイでは、私が情熱を注いでいるものの中からほんのいくつかに触れたに過ぎません。皆さん自身のアイデアや体験もぜひ聞かせてください!LobstersやHacker News、あるいはプログラミング系Redditでコメントをお寄せください。
記事をランダムに読む
コメント
ログインしてコメントする