ラベル アーキテクチャ の投稿を表示しています。 すべての投稿を表示
ラベル アーキテクチャ の投稿を表示しています。 すべての投稿を表示

2025年8月26日火曜日

未熟だったと思う技術的解決方法

技術者としてとても浅い知識と解決方法だったと今思うと恥ずかしいことがとても多い。

勉強をすればするほど自分の無知の知が広がり、自分がまだまだだったということを思い知る。無知の無知をどれだけ減らせるかがこれからは重要だと思っている。

今思ったらこれはこういうふうに解決するべきだったと思うことはいっぱいあるので筆頭を書きたい。特に職務経歴書には良いことしか書いていないからなんか本当はもっといっぱい書くことあるんだけどなと思ってここに書いておく。

メモリリーク+長時間ジョブを保持しサーバーのリソース食われている問題

→これをEC2インスタンスのスケールアップで対処するという解決方法。

そもそもサーバーの性能を上げるというのは最終手段としてその前にやることはいっぱいあった。

原因はSidekiqのワーカープロセスのメモリリークと、Redisへの長期間ジョブ保持の設計が重なってリソースを食っていた。(Sidekiqというのはジョブキューのワーカープロセッサ。例えばAWS SQSと代替性がある。)

Sidekiqメモリリーク問題はそのコードの書き方や処理の仕方に問題がある。

加えて最大7日間Redisにスケジュールを保持して7日後にジョブを実行するというワーカーなど長時間Redisにジョブを保持させるような仕組みが数あった。

このような長期間スケジュールが必要なジョブは、Sidekiq ではなくバッチサーバーや専用のスケジューラーで実行する方が適切だった。ずっと使われているものに疑問を持ち、問題の原因を見極める目を持つのが本当の技術者だったと思う。

ユーザーがイベント操作をした後がやたら重い

メルカリでいう"出品ボタン"を押した後や"購入した後"、やたら待機時間があり裏で処理が完了するのを待たされるという問題。

社長やプロダクトオーナーはこういうところをよく見ていて、指摘されてすぐ解決しようとして開発者たちは浅い解決をしてしまうんじゃないかなと思う。

これはおそらく原因は出品イベントを実施した後に全ての大量の処理を同期的に処理していたから。(例えば商品のバックグラウンド配信処理やポイント計算など)

関心の分離がそもそもできておらず、"出品"という関心ごと以上のことを全て同期処理をしていたためにその処理たちが終了するまでユーザーが画面待機しているということが実際の問題だった。

それを『CDNを設置したら解決する』とか『一部リファクタリングをしたら解決する』などという間違えた方法で解決しようとしていた。(ていうか解決していない)

本質的には出品が完了したらさっさとユーザーは体感的にはすぐ終了し、その後の処理はイベント駆動型アーキテクチャでメッセージキューに非同期的に送るということで根本的には解決していたはずだ。(実はメール通知やその他些末な部分についてはSidekiqで最低限非同期化はされていた。)

パフォーマンス改善は何かツールを立てればいいと浅い経験者だと思いがちだけど、アーキテクチャにまで考えを巡らせることが大切だった。

冗長化、分散化検討の不十分さ

管理者画面からは大量のデータを参照したりCSVダウンロードしたりする。その際にアプリケーション全体の処理が重くなっているという問題を我々はWebサーバーを分けて解消した。

それ自体はまだ一歩前進だったなと思う。

これから管理者サービスとしてマイクロサービス化させるとかして好きに別言語で書き換えても良いだろう。

問題はそのあとで、すべての処理は単一のデータベースを見ており、DBのI/O処理は変わらずリソースを食い合っていたという問題がある。その辺りの問題を見ていなかった。

データベースはレプリケートし、管理者画面からの参照系のクエリはリードレプリカを読み取るように設計をしなければならなかった。

書き込み系トランザクションと読み込み系のトランザクションを分離することで、ユーザー向け処理のパフォーマンスを守ることができたはず。

なんだったら、管理者画面を操作するのは平日の昼(とか月曜日)にアクセスがバーストするのでEC2で常時動かすのではなくてコード上のモジュールを分離してコンテナ化した後、ECS+Fargateなどで使用量に応じた従量課金制の方が多分コストもより最適化されていただろう。

大層なツールを使うのはまだ早かった

要するにElasticsearchとかCloudFlareとかそこまでビジネスがスケールしていないうちからツールを使って解決しようとするもの。実はもっとビジネスがスケールしてから検討を開始するべきだっただろう。

最近のXで質問箱という単純なシステムなのにk8sを使っている形跡があったりして話題となっていた。

技術者の幼稚さというかなぜそれを使ったというような感じで、コストも嵩んでおり、履歴書駆動開発という揶揄があったりした。

ツールや最新技術を使うというのはそれが目的となってはいけないと思った。まあ検討材料として幅広く知る必要はあるが、大切なのは問題の本質を見極めるイシューだなと思っている。

サービス・関心事を分離していない

せめてBユーザーとCユーザーのログイン画面くらいは分離をしないといけなかったけど、そのログインが一緒だった。つまり、ユーザーのjobだかroleだかのカラムでBかCを判断しているというものだった。(まあ最初のスタートアップの立ち上げ期が過ぎてからここを変えようというのが最初の開発者たちの考えだったんだろうけど、、そのもうちょっと余裕ができるステージが全然来なかった。)

これはサブドメインでサービスを完全に区別するなどして内部のバックエンドやチームをうまく分担することが今思うと大切な取り組みだったなと思う。

ドキュメントを整備すれば良かったけど全然自分たちも整備していなかった

以前の担当者たちが全員辞めてしまって新しく入った開発者メンバーたちで担当をしたけどドキュメントが古いという問題があった。それは自分たちでまた最初から作り直すなどしてスタートは遅くなるがそうする時間は必要だったなと思った。

なぜならその後に入ってくる開発者たちにも同じように口頭で説明をしたり、自分たちでリバースエンジニアリングをして同じ道を辿ってもらわなければならないからだ。

ADR(Architecture Decision Record)→アーキテクチャがなぜそのようになっているかを知るした仕様書を書く。

ドメイン仕様書→主要な機能やドメインの仕様書は自分たちのリバースエンジニアリングをした結果としても記したい。

手順書→多分これはせめて書いている人やチームは多いと思う。気にせず、変わった部分があれば常に最新にしておくのがよい。

2025年8月23日土曜日

社員数が少ないベンチャー企業の疲弊とそれでも上場しようとした時の問題

ビジネス側がやりたいこと

・組織が充分に成熟していない状態であろうとも上場をするという目標を達成したい

・上場審査を通過するためにメインの収益を安定、向上したい

開発者はビジネスがスケールするかどうか中身が見えている状態。だからビジネスサイドが見えていることと開発者が見えていることは根本的に異なり疲弊が生じる。

相手側に「これくらいやれるだろ」という意見や不満が生じる。

開発部の疲弊問題

→ビジネスサイドと開発部との接合点が近いことで組織の力関係が偏っている

こういう会社に入ったら

ドキュメント整備してシステム全体像を図式化、構造化して問題点を洗い出しする

政治(メンバーとして入ると良くないかもしれない)

開発者がやることは

・業務効率化

・アーキテクチャ再構築

・要件再定義・再設計・再実装

業務効率化

例:

カスタマーサポートが疲弊→プロダクト根本的問題を解決する、チャットボットを作る、Q&Aページを再編、構造化して問い合わせ前の解決を促進する、ビジネス問い合わせとカスタマー問い合わせを分離する。

開発者のシステム運用の手間を減らす。インフラ運用を減らす。手動でのデータ転記を自動に。

アーキテクチャ再構築

モノリスから責務が重そうなコアドメインを特定、分散化。データベースのレプリケーション。CQRSを適用、最適なアーキテクチャのトレードオフを考慮して選定し移行。

要件再定義・再設計・再実装

ビジネスサイドがプロダクト価値を向上させる観点やどうやればいいかがわからない場合は開発がヒアリングを主導しぐちゃぐちゃな要件定義を再定義し再編する。ドメイン知識が必要そうな部分をドメインエキスパート(一番詳しそうな人)にヒアリングしドキュメント化。

改善不能になる要因

アーキテクチャの問題と組織構造の問題とマインドの問題

コンウェイの法則→組織構造がアーキテクチャやシステム設計に反映される法則。

コンウェイの法則に加えてその場を支配しているマインドも力学に関与している。

例:

生産性とか言う前にまずやれ思考→業務を効率化したり生産性を上げるように仕組みを変えるなどという思考に至らず疲弊した社員で構成される。

残業をしていた方が評価される→効率化させたり、仕組みが変わったりすることは考えない方が得。仕事がいっぱいある方が得。効率が悪い方がお得。

上司に従順じゃない人は幼稚→マイクロマネジメントでメンバーが他責化・受け身思考化。どうしても社長やトップが幅を利かせてしまい、誰も提案がなされない組織になる。思考することは無駄っていうことになり、アーキテクチャ改善や業務効率をするための思考ができない。

部署ごとの力関係→選択肢を考慮できる部署が偏っている場合、その部署の先導でシステムがどうしても作られてしまう。営業優先だと営業の御用聞になり、システムは手続型の構造になり深い思考が反映されている抽象構造化されず、スケールしない。

上場をする際にベンチャーがぶち当たったシステム観点

セキュリティ監査

→認証・認可問題(管理者画面、画像の永久URL表示)、会計経理不整合

売上で大事なドメインがスケールしていない

2025年8月10日日曜日

BtoCオークションサイトの理想的なアーキテクチャを構想する

モノリスで構築した際、パフォーマンスとスケーラビリティに問題が出るパターンを目にしたため、理想的なアーキテクチャを考える。

Cの出品者が出品というイベントにより、Bの査定事業者に非同期ストリーミングされる設計が理想。

事業者と出品者は根本的な操作が違うため、ログイン画面、ドメインURLが違っても構わない。(ドメイン駆動設計で言えば境界的コンテキストだろうか)

規模が大きくなれば、マイクロサービス化し、査定サービスと出品サービスでコンテナを分けると将来的には良い。

大きく分けてシステム管理者(入出金処理、申請処理、チャット閲覧機能、ユーザー情報検索機能など)、査定事業者、出品者で分けることができるため、サービスは3つに分ける。

こうするとイベント駆動型アーキテクチャとマイクロサービス化を組み合わせた分散型のアーキテクチャにすることができる。


Ruby/RailsのWebアプリケーションはドメイン駆動設計を当てはめることができないのでmastodonのような設計方針にする

Ruby/Railsはinterfaceキーワードがないため、JavaやC#のようなinterfaceクラスを定義することができないが、Duck Typingという概念により楽しいを優先した実装が可能になっている。

かといってRuby/Railsのフレームワークに全てを託してMVCを構築して密結合なソースコード、ディレクトリ構成になると後々きつい。

ドメイン駆動設計の実践的ソースコードとしてはそれを実践している企業のソースコードをみたらめちゃくちゃ勉強になるけど、できない場合はCargo Trackerを読むと良い。

エリック・エヴァンスのドメイン駆動設計を読んでいると途中でCargo Trackerのドメインを例に説明している箇所が出てくるのでJavaで実装されているCargo Trackerのソースコードを読んで、概念を具象に置き換えて読むことができる。

Railsをドメイン駆動設計で設計をするとなぜRailsを選択したのかがわからない設計方針になってしまうため、Railsでドメイン駆動設計を実践している企業はあまりないはずだ。

mastodonはMVCを基本構成としていながらModelには基本メソッドを用意し、Serviceに業務ロジックを書いている。Serviceに書かれたロジックをModelが呼び出しているため、Modelがファットにならない。

Railsのようなフレームワークと結婚をする場合はクリーンアーキテクチャやドメイン駆動設計を当てはめることはほぼないだろうが、MVCをService、Policy、Form、Query、Concernsで上手くバラす。

ドメイン駆動設計でいうエンティティとリポジトリはModel、複雑なクエリはQueryオブジェクトに分離される。

Policyは権限制御。Formは複数モデルを使用する場合のPORO。Concernsは複数モデルで共有してもよい小さい処理などを入れる。


2025年8月2日土曜日

ビジネスも分かっていないと結局何をしたらいいか分からない

 開発者は開発だけをしていたらいいのか?

私は1年前は開発だけできればいいと思っていた。開発、実装が早ければ、あとは勝手に要件定義ややるべきことを誰かが決めて、今やるべきことを振ってくれると思っていた。

だが、全然そんなことはない。ベンチャー企業に入ってRailsのシステムを保守・運用しながら再設計のフェーズになって分かったが、それじゃ意味がない。

システムはビジネスサイドが何をしたいかによって変わる。

サービスAを立ち上げていたけどサービスBが走り、メイン稼働はBである。Aをどうしたらよいか?システムAを移行するにあたって移行計画をする必要がある。

それは開発だけをしていたら良いという思考だと全然できない。

我々は要件定義や設計はもちろん、アーキテクチャを理解して自分が今やっているサービスはどういうアーキテクチャになれば最適なのかを知っていなければならない。

そうしなければ、今やるべきことが分からないし開発もできない。

なんだったらビジネスサイドは開発でどういうことができるのかさえ分からないのでこちらからアプローチして、どういうことをするべきなのか指針を示せるようにならないといけない。

私はこれからは最適なアーキテクチャの進化、システムの移行計画、要件定義、ドメインに沿ったアプリケーション設計ができるようにならなければならないと思った。

そのためには今まで参加したプロジェクトや開発をしたアプリケーションを再度自分だったらどのようにしたらいいか考えて表現することにした。

2025年8月1日金曜日

Ruby on Railsのモノリスをリアーキテクチャする

 Ruby on Railsはマイクロサービスやサーバーレスなどの分散型アーキテクチャとは相性が悪い。

モノリスでサービスを立ち上げ、高速でローンチするのには適切な言語、フレームワークだと思う。他にもPHP/Laravelなどの選定も良い。

インターネット上だとPHP/Laravel、Ruby/Railsのシステムはオワコンという内容の意見が溢れている。しかし、そうとは限らない。

最初からマイクロサービスを想定してGo、Pythonなどを選定してもエンジニアの採用が難しいしシステム構成も難しい。私も最初から学ぶ必要がある。

なので、最初はRuby/Rails、PHP/Laravelを選定するというベンチャー企業、スタートアップが多い。

しかし、事業が成長してサービスがスケールするとモノリスで作られたサービスはどんどん開発が遅くなる。ここで分散型へ移行する必要がある。

Ruby on Railsで作られたシステムはちょっとずつアプリケーション設計を疎結合にしていき、責務を分離しないといけない。その時にドメインの知識、サービスの流れを全て把握した上でどのコンポーネントが重いのかを把握する。

私が参加していたサービスは買取オークションというサービスで、出品者と事業者、システム管理者という明確な責務が分離できた。

なので、商品が出品された時に事業者に適切に配信されるためにモデルをドメイン事業になぞらえて再設計。その後、イベント駆動型に移行するといいだろう。

イベント駆動型とは出品というイベントが発火した時にメッセージブローカーが条件によって事業者に適切に配信する。

必ずしもマイクロサービス化が適切じゃないなら、イベント駆動型アーキテクチャ、サーバーレス化など少しずつアーキテクチャを進化させていくと良い。

Ruby on Railsで構築されたモノリスがスケールできなくなってきた

創業してから10年ほど経っているレガシーシステムを運営しているとあるサービス会社に入り私は初めてRuby on Railsを学びました。

それまで私は技術力の低いSIerでC#の基幹システム開発案件を3年ほど転々としていて、今回のWebサービス、他の言語に触れるのはとてもわくわくしました。

サービスは出品者が売りたい物を出品し、それをオークション形式で査定士たちがどんどん査定していくというオークション型の出品買取サービスでした。それで出品者が気に入った取引先が決まればあとはチャットをして送品、入出金されるというシンプルなサービスです。

そのうち商品をヤマトや佐川などで発送し、査定してもらうというシステムもおそらく構築するとメルカリみたいに楽でいいサービスになると思いました。

ですが、開発者にとって大きな問題があり、ビジネスサイドも無視できない問題がありました。

それはシステムがあまりにもレガシーでとてもじゃないけどこれ以上はスケールしないということでした。

あまりに巨大な泥団子状態になっており、もし先ほど言ったような発送機能なども追加しようものなら手を付けられないシステムになっていることでしょう。

Ruby on Railsは初心者でもとっかかりやすい言語、フレームワークとして有名です。

しかし、それゆえ私のようなあまり設計やアーキテクチャに明るくない人でもやりたいことができてしまい、ソースコードを追加に追加した結果、後から入ってきたエンジニアたちはコードが複雑化しすぎていて、仕様が把握しきれないということになっていました。

これ以上Ruby on Railsで開発し続けるならシステムを刷新する必要がありました。

依存関係や結合度を減少させる必要があり、モノリスをモジュラーモノリスか分散型アーキテクチャにして責務を分離させる必要がありました。

そうすることで、スケーラビリティ、パフォーマンスが共にぐっと向上し、より柔軟性の高いシステムになります。

一方で、密結合な方がテストしやすいしバグの原因を特定しやすい。環境を構築しやすいため、開発しやすさはトレードオフになると思います。そこら辺は会社、開発に余裕があるかを見る必要があるでしょう。

組織もRuby/Railsエンジニアを採用するのではなくて、アーキテクチャを変容させると同時にフロントエンドの専門、ソリューション解決の専門など人材を確保することでよりマルチプロダクト化、プロダクトの共通基盤を作ることができるでしょう。

それは今後私もアーキテクチャを学び、書いていくととして、今回言いたいことはRuby on Railsで構築されたモノリスがいかにスケールしないシステムになるかということです。

スタートアップはサービスを立ち上げて早く収益化させないといけません。

なので最初からマイクロサービスで構築してしまうと実装できる要員や開発スピードを確保できず、破綻してしまいます。

最初にRuby on Railsでモノリスを作ることはかなりいい選択だと思います。

経験のないエンジニアでもRuby on Railsに慣れたらどんどん書けるので採用に大金をかけられないスタートアップにとってはRuby on Railsは得策です。

しかし、そうやって書いてきたソースコードはあまりにも読むことが難しく、複雑で誰も把握していない仕様になってしまうので、余裕ができてきたらシステムはインフラ構成、アプリケーション設計、仕様、DB設計等あらゆる仕様・設計を再検討し作り替えていかなければならないです。

いつどのタイミングでリアーキテクチャしていくかは予算をどれくらい開発にかけてくれるかにもよりますし適切な人材をどれくらい確保できるかにもよりますが、モノリスはいつかは限界がくるということが分かりました。

エンジニアは今開発をしているプロダクトや会社、事業がどれくらいのフェーズにいるのか。どれくらいのサービスを求められているのかを考えることが必要でしょう。

特にAIがプログラムを書いてくれるようになったので、アーキテクチャやビジネス、プロダクトマネジメント、ソリューションアーキテクトの役割をどんどんつけていく必要があると思います。その上で役割を分担することでより良い組織になると思っています。

これからの時代に備える

2026年は失業の年か跳躍の年か アメリカではブルーカラーへの雇用が増加しており、ソフトウェア産業をはじめとしてホワイトカラーの就職が困難になっている。 データで分かるのは、若手、中間管理職層がリストラ対象というもの。アメリカでは『ジョブ型雇用』であるのに対して日本は『メンバーシ...