ネットワーク・クラウド

2024/11/24

「RedmineのUbuntu+Docker構築への移行」の感想 #redmineT

第27回redmine.tokyo勉強会で講演された「RedmineのUbuntu+Docker構築への移行」は内容が参考になったと思う。
ラフなメモ書き。

【参考】
第27回勉強会 - redmine.tokyo

発表 #1609: 第27回 講演: <RedmineのUbuntu+Docker構築への移行> - redmine.tokyo

【1】今回の講演の背景としては、問題意識として、RedmineをCentOSで利用している場合、どのOSへ移行したら安全なのか、容易に移行できるのか、がある。
おそらく、Redmineはフリーで現場で使っているので、OSやサーバも自前で構築する時にCentOSを利用しているケースは非常に多い。
そこで、CentOSはサポート切れになってしまった状況では、セキュリティリスクがあるために、どこかのOSに移行せざるを得ない。
OSSのLinuxOSは数多くあるが、どれが最適であるのか?

さらに、どのOSが最適なのか、そして移行作業としてどれだけの工数や難易度が発生するのか、という問題も発生する。
RedmineというWebアプリ程度なら簡単だろうと思っていると、RubyやOSのバージョン、プラグインとの相性など色んな点で地雷を踏んでしまうリスクがある。

そういう背景を踏まえて、本資料を読み直すと価値があると考える。
本資料では2つの観点で整理できると思う。

【2】1つ目は、本資料では、CentOSからの移行先OSとして、Ubuntsを選択している。
移行要件詳細①を読むと、Ubuntsを選択している理由は明確だ。
s
Ubuntsを選択した理由を品質特性の観点で整理すると下記になる。

リリースの歴史が長く突然停止の可能性が低いこと
 →OSとして成熟しており、信頼性が高いと想定。

LTSの定期的な提供、2年単位の最新版提供により最新の機能が使える
 →最新の機能が使えるので、機能適合性が高いと想定。

Webクライアントとしてのシェアが高くナレッジ豊富
 →障害が発生しても障害解決の知見が豊富なため、信頼性(耐障害性)が高いと想定。
 →Ubunts上では、他のソフトウェアと共存し使用できる知見が多数あるため、互換性が高いと想定。

x86やARM等アーキテクチャを問わず稼働し、汎用性に優れる
 →x86やARM等アーキテクチャなど幅広く移植できるため、移植性が高い。

CentOS互換系のOS特有の機能を使わないのでCLIでよい
 →CLIでメンテナンス用プログラムを作成できるため、保守性が高いと想定。

CLIに慣れる事でLinuxに対する耐性や知見を上げる
 →CLIに慣れれば、UbuntsOSはCLIで操作しやすいため、使用性が高いと想定。

すなわち、信頼性、機能適合性、信頼性、互換性、移植性、保守性、使用性などでUbuntsの品質は高いと分析されている。
品質特性のかなりの数の観点が網羅されており、実際にRedmine移行で成功されたことを考慮すれば、Ubuntsを選択した理由には妥当性があると考える。

もちろん、RockyLinuxなど他のOSも候補に入るだろうが、普及されているUbuntsは移行先の有力候補になるだろうと思う。

【3】2つ目は、本資料では、Redmineの移行を今後も考慮するためにDockerを採用されていることだ。

vSphereの期限切れという事情もあるだろうが、Hyper-VとDockerのような仮想基盤の上にアプリ層を乗せる方が、今後の移行作業もコピーするだけでよく、作業しやすくなる。
「Redmineの移行」ページにソフトウェア構成図が記載されていて、Redmineが乗る基盤が層別に整理されていてイメージしやすい。

また、Dockerイメージを複製することで、移行後の動作検証やプラグイン検証、性能検証なども並行作業で実施しやすくなる。
本資料で注目すべき点の一つは、Redmine本体のDockerイメージ(sameersbn / redmine)とプラグイン込みのRedmineのDockerイメージを区別して準備されている点だろう。

既に準備されているRedmine本体のDockerイメージを利用する理由は、Webサーバやバックアップなどの基本機能が既にあり、プラグイン無しの標準機能がそのまま使えることだろう。
つまり、プラグインを使わずRedmine本体の標準機能だけで使うならば、公開されているDockerイメージをそのまま流用するほうが品質も担保されているし、検証や移行などの作業工数も無駄に使わなくていい。

一方、プラグイン込みのRedmineのDockerイメージはカスタムイメージで独自作成されている。
Lychee RedmineやFull Text Search等のプラグインを使われているそうなので、それらの動作検証を入念に行われたと記載されている。
確かに、プラグインの動作はRedmineのバージョンやプラグイン同士の相性、OSの相性にも依存するため、Dockerのカスタムイメージを作成した方が、プラグインを1つずつ入れて検証OKのDockerイメージを作りやすく、事前検証の先祖返りのリスクもないだろう。

本資料を読むと、View Customizeで改良した部分が動作しなかったり、Lychee Redmineのガントチャートの日本語表示はOSの日本語フォント配置で解決したり、応答速度低下のクレームにはインスタンスのスケールアップやMariageDBのチューニングで改善されたりしている。
やはり移行後には予期しないクレームも発生するので、色々対応せざるを得ない。
そんなケースでもHyper-VとDockerを使っているなら、インスタンスの性能チューニングも簡単だし、Dockerで移植し直すこともできる。

分かってしまえば簡単な内容かもしれないが、やはり実際に移行してみないと分からない時も多い。
そういう試行錯誤された事例として非常に価値ある内容と思う。

[商品価格に関しましては、リンクが作成された時点と現時点で情報が変更されている場合がございます。]

入門Redmine第6版 [ 石原佑季子 ]
価格:3,080円(税込、送料無料) (2024/11/24時点)


| | コメント (0)

2024/03/03

ソフトウェア工学の根本問題から最近のソフトウェア設計を考えてみる

ソフトウェア工学の根本問題は何なのだろうか?
僕は、ソフトウェアをいかに部品化して疎結合な構造とし、お互いの相互作用でいかに協調動作する仕組みを作るか、だと思う。
以下、直感的な思考を書き記しておく。

ソフトウェアの歴史をたどれば、構造化プログラミングからオブジェクト指向プログラミングへ発展した経緯を見ると、ソフトウェアの構造とソフトウェアを開発する仕組みをいかに透明化し、コントロールしやすくするか、に力点をおいているように思える。

@sakaba37さんから言われてはっと気づいたことは、ソフトウェアは密結合になりやすいこと。
トランザクションスクリプトのように、ちょっとしたロジックの処理を何も考えずに実装すると、密結合なプログラムになり、スパゲッティになりやすい。

そして、ソフトウェアを開発するプロセスも、ソフトウェアを開発する組織も、ソフトウェア構造を反映してしまうために、密結合なプロセス、密結合な組織になりやすい。

今、クラウドを基盤としたマイクロサービス設計が色々試されている。
マイクロサービス設計では、処理層とデータ層をまとめた一つのサービスを独立した単位とし、それらを協調動作する仕組みを作ろうとする。

しかし、今までのソフトウェアの歴史から類推すると、いかにソフトウェアを疎結合な構造にするか、いかにソフトウェアを管理するプロセスを透明化しコントロールしやすくするか、という根本問題から離れられていないように思える。

実際、マイクロサービスが独立した単位であっても、複数のサービスが協調動作させる仕組みをいかに安定して作るか、API設計や補償トランザクションなど、色々試行錯誤している。
ソフトウェアアーキテクチャ・ハードパーツ ―分散アーキテクチャのためのトレードオフ分析」を読めば、マイクロサービスをいかに安定して設計するか、を試行錯誤していることが分かる。

また、全てのマイクロサービスを横断して管理する仕組みとしてサービスメッシュという概念が導入されているが、それもサービスの耐障害性や可用性を担保するための監視サービス群のようなものだ。
ちょうど、Ciscoのネットワーク機器からなるネットワーク構造をSDN化したときに、データ層とコントロール層に分けて、APIを使ってコントロールしようとする仕組みと同じように思える。

他方、ソフトウェア開発の組織も今はスクラムをベースとしたアイデアに基づき、少人数のスクラムチームで開発するのが、特にマイクロサービス開発では相性がいい。
マイクロサービスでは、データ層も処理層も持つので、開発チームが必要なソフトウェア部品を全てコントロールできるからだ。
また、マイクロサービス同士のやり取りは、スクラムチームが協調動作する仕組みに置き換えられる。
実際、スクラムチームでは、プロダクトバックログというインプットとインクリメントとして付加価値を順次リリースするアウトプットが契約になるが、その中のプロセスは部外者は口出しできない。

つまり、スクラムチームは、まるで1つのソフトウェア部品のように中身はブラックボックス化されており、インプットとアウトプットというインターフェイスが保証されている仕組みと思っていい。
すなわち、スクラムチームという開発組織も、疎結合なソフトウェア部品と同様にみなせる。

そんなことを考えると、僕はクラウドやマイクロサービス設計の経験がないけれど、今までのソフトウェア開発の歴史を踏まえた根本問題から、マイクロサービス設計やその開発プロセスでは、過去の根本問題をどのように解決しようとしているのか、という観点で考えていた。
そして、その考え方から類推されるボトルネックは、昔の技術から現代のアーキテクチャに変わったとしても、症状として現れる事象が変わっただけであって、その本質は変わっていないはずだと思っている。


| | コメント (0)

2024/01/02

マイクロサービス設計は従来のアーキテクチャ設計と何が違うのか

マイクロサービスの設計は理解できていなかったし、今も理解が中途半端。
理解できたことだけをメモする。
ラフなメモ書き。

【1】「ソフトウェアアーキテクチャ・ハードパーツ ―分散アーキテクチャのためのトレードオフ分析」を友人と輪読しているが、まだ理解できたという気がしない。
今までのオンプレ環境で業務系Webシステムの設計や開発をしてきた経験、Java+Oracle+Linuxでベタに開発した経験をベースに理解しようとしていた。

そういう観点で読むと、「8章 再利用パターン」が一番理解しやすい。
なぜならば、コンポーネントやサービスの再利用性は、オンプレ環境のWebシステムであれ、クラウド環境のマイクロサービスであっても、同様の観点が通じるからだ。
たとえば、バージョニング戦略は、まさにソフトウェア構成管理と同じ。
後方互換性を見極める、Javaの非推奨(deprecated)のアノテーションのように廃止されたAPIは使わない、枯れた最新バージョンを使う、定期的にパッチ収集とパッチ適用の運用ルールを定める、とか、どこでも同じ。

しかし、マイクロサービスの本質はそういう所ではないはず。

【2】マイクロサービスを僕が理解できない原因は2つあると思っている。
まず、マイクロサービスを実装したモデルを考えようとすると、AWSサービスを使った実装を考えることが普通。
しかし、AWSサービスに特化しすぎると、AWSはサービスが多すぎて、どの場面にどのサービスを使うと良いのか分からなくて、混乱してしまい、何が重要なのか分からなくなる。

他方、AWSサービスのような具体的なサービスを外して、抽象的なマイクロサービス設計技法を考えると、逆に具体的なイメージが思い浮かばず、ふわふわした議論になってしまう。
オンプレ環境の経験を元に比較理解しようとするだけで、その本質までたどり着けない。

マイクロサービスの直感的イメージは、一昔前のSOAPでやり取りするWebサービスとほぼ同じと思っている。
現在なら、SaaSはほとんどがマイクロサービスで実装されているのではないだろうか。
たとえば、検索サービス、顧客サービス、商品サービス、在庫サービスなど、リソースやイベントの単位で区切られたドメインをマイクロサービスへ分割し、それらの間はRESTでデータをやり取りし協調しながら1つのユースケースを実現しているイメージ。
だから、マイクロサービスだからといって、そんなに難しかったり、高尚な概念でもないはず。

では、現代のクラウド上のマイクロサービス設計では、かつてのオンプレ環境のWebサービスと何が異なるのか?
ここさえ抑えれば理解できる、と思える本質的内容は何なのか?

【3】「絵で見てわかるマイクロサービスの仕組み」を読みながら、理解したことを書いておく。
今の自分のレベルではこれくらい噛み砕いたレベルでないと理解しにくかった。

絵で見てわかるマイクロサービスの仕組み」で自分に響いた内容は3つ。

【4】1つ目は、マイクロサービスは、数秒後から数時間後に動機が取れていればいいとする結果整合性が許容できる場面で活用すべき。
つまり、マイクロサービスではACID特性を厳格に守るのは難しいし、そういう場面では有効とは言えない。

よって、マイクロサービスが使えるユースケースは、業務が並列処理で動作しても良いケース、頻度は少ないが一時的にアクセス数や負荷がかかる時にCPUやメモリを動的に増やすスケールアップやサーバ台数を動的に増やすスケールアウトするケースなどだろう。
すなわち、性能要件を動的に拡張したいケースが当てはまるのではないか。
AWSやAzureのようなクラウドであれば、そういう拡張は、クラウド基盤が提供するマネージドサービスで簡単に実現できる。

一方、デメリットは、ACID特性ではなく結果整合性でしか担保しないので、基幹系システムでは難しいかもしれない。
たとえば、あるマイクロサービスで障害が起きてデータの不整合が発生した時、ロールバックをDBMSやフレームワークではなく、自分たちで作り込む必要があるかもしれない。
絵で見てわかるマイクロサービスの仕組み」では、異常系処理やロールバック処理を補償トランザクションで実現する方法が紹介されていた。
この辺りは実際の実装方法がよく分かっていないが、結局、自分たちでフレームワークを組み込んでいるのと同じような印象を受ける。

【5】2つ目は、コンテナオーケストレーションは、複数コンテナをクラウド基盤のAPIやマネージドサービスで制御する設計思想であること。

絵で見てわかるマイクロサービスの仕組み」では、コンテナ<Pod<ノードの順でグループ化されていた。
すると、複数のコンテナを手動で管理するのは面倒だし、ミスも多くなる。
また、頻度は少ないがアクセス数が一時的に増える場合にスケールアウトするようにコンテナを動的に増やす場合、コンテナのIPアドレスは一時的に付与されるので、管理する手法も特有の考え方が必要になるだろう。
よって、複数のコンテナをAPI経由のプログラムで一括管理したくなる。

そこで、コンテナオーケストレーションという概念で包括的に管理する。
絵で見てわかるマイクロサービスの仕組み」では、コンテナオーケストレーションを適用するユースケースとして、
・コンテナの作成とデプロイ
・負荷に応じたスケールアウトやスケールダウンやロードバランシング
・ホストやコンテナのヘルスチェック
があげられてたい。
つまり、動的にコンテナを作成しデプロイして、負荷に応じてスケールアウト・ダウンし、負荷分散させる。
また、コンテナのヘルスチェックのように、サーバー監視の管理サービスも実現してくれる。

コンテナオーケストレーションの実装例としてKubernetesがあげられている。
Kubernetesの優れた汎用的な機能のおかげで、AWSでもAzureでも一般的なクラウドにもコンテナ群をそのまま移行できる、という発想なのだろう。
コンテナの実装は、yamlやJasonなどでドメイン特化言語のように記載されて実現されるのだろう。
それゆえに、yamlなどのドメイン特化言語で、マイクロサービスのコンテナ群を全て実装すれば、検証環境であれ本番環境であれすぐにクラウド上に実装できるはず。

ではそれで全ての問題が解決するのか?
変化の早いビジネス環境において、マイクロサービスを組み合わせることで即座に稼働しやすいだろうが、複雑性は増すだろう。
数多くのコンテナを協調させながら稼働させるには、コンテナの中身を記載したyamlは相当複雑になるだろう。
一昔前に、Antでビルド&デプロイのタスクを書いていた時、宣言的に書いて楽だなと思っていたのに、環境が増えるごとにIF文がAntタスクに紛れ込んでどんどん複雑化したような経験を思い出す。
たぶん、それに似たような事象がKubernetesでも起きるのではないか、と思ったりする。

【6】3つ目は、サーバレスアプリケーションはBPMNのようなワークフローに並列処理を組み合わせたワークロードみたいなものではないか、と思う。

絵で見てわかるマイクロサービスの仕組み」では、サーバレスアプリケーションの基本アーキテクチャは、BaaSとFaaSの2種類があげられている。
BaaSは外部サードパーティのサービスを使うパターン。
FaaSはビジネスロジックをイベントドリブンで実装するパターン。

BaaSはたとえば、Googleアカウント認証やTwitter認証などの外部認証サービス、PayPalのような外部決済サービスがあげられるだろう。
外部サードパーティサービスの方がセキュリティ要件も性能要件もいいならば、そちらのサービスを利用することで、ユーザの利便性も増すだろう。
他方、ユーザ認証やクレジットカード情報を自社システムに持たないデメリットがあるので、顧客情報をより包括的に収集できないデメリットもあるだろう。

FaaSは、BPMNのようなワークフローに並列処理を組み合わせたワークフローに思える。
マイクロサービスをつないで、イベント駆動でマイクロサービスをキックし、一連の業務が流れる感じ。
その場合、並列処理で動くので、商品を購買している間に、検索したり、在庫に問い合わせたりして並列で動かすケースもあるだろう。

サーバーレスアプリケーションはFaaSを想起させる。
AWSならLambdaになるのだろう。
メリットは、アプリケーション開発者はアプリ層のマイクロサービスの実装だけに特化すれば良く、インフラ基盤は考えなくてもクラウド基盤がマネージドサービス等で勝手に管理してくれる、そういうイメージなのだろう。

他方、開発時のデバッグや障害時の復旧はかなり面倒になることが想像される。
複数のマイクロサービスを通したシステム全体テストをやるには、ローカルPCでは無理で、クラウド上に本番同等の検証環境が必要になるだろう。
その分コストも増える。
また、イベントドリブンで連なる一連のマイクロサービスのうち、途中のマイクロサービスで障害が発生して、データの同期が取れなくなった場合、データのロールバック処理は複雑になるだろう。
本来は、データ復旧や障害復旧もクラウド基盤が勝手に自動で上手くやって欲しいが、手作業で設計して入り組んだ複雑なワークフローになっていると難しいだろう。

そんなことを考えると、全てがバラ色の世界ではないだろうと思う。

【7】マイクロサービス設計は従来のアーキテクチャ設計と何が違うのか?

違いの一つは、マイクロサービス設計では、インフラ基盤をクラウドのマネージドサービスで自動化したり、APIで監視サービスやコンテナオーケストレーションを実装できる点にあるだろう。

つまり、従来のオンプレ環境のインフラ基盤は、アプリ開発者の手によって操作できるようになった点が違いになるだろう。
アプリ層からインフラ層まで全て、アプリ開発者がコントロールできるようになったこと。
そんな開発者はフルスタックエンジニアと呼ばれるのだろう。
また、DevOpsとは、そういうフルスタックエンジニアがアプリ層からインフラ層までコントロールして、開発も運用も一体化するプロセスを指すのだろう。

| | コメント (0)

2023/11/12

「ソフトウェアアーキテクチャ・ハードパーツ」の情報リンク~マイクロサービスの設計技法の課題は何なのか

ソフトウェアアーキテクチャ・ハードパーツ ―分散アーキテクチャのためのトレードオフ分析を読んでいて、まだ中身を理解できていない。
ネット上の感想記事を自分用にリンクしておく。

【参考】
『ソフトウェアアーキテクチャ・ハードパーツ』 - Don't Repeat Yourself

(引用開始)
また、最近話題になっていた『ソフトウェアアーキテクチャの基礎』(以降、「基礎」)を執筆した著者陣が書いたもう一冊の本でもあります。
「基礎」はアーキテクトとしての姿勢や、それぞれのアーキテクチャの簡単な概要が中心でしたが、この本はより実践に近く方法論寄りです。「基礎」が「What」を扱うとすれば、本書は「How」を扱うといった関係性でしょうか。
(引用終了)

(引用開始)
現代ではデータをどのように設計し、分割しつつ整合性を保って保管しておくかといった一連の流れの重要度が増しています。この問題についても本書は拾い上げるよう努力しています。[*1]
従来のアーキテクチャの議論では、マイクロサービスはどう分割するかとか、コードの関心事がどうこうとかそういったアプリケーションに限った範囲が中心だったように私は思っています。が、そうではなくデータをどう分割、配置、保管していくかといった問題についても議論に含めるようにしています。
(引用終了)

『ソフトウェアアーキテクチャ・ハードパーツ』完全に理解した - Mirai Translate TECH BLOG

(引用開始)
一言で言うと
「マイクロサービスの大きさと通信方式をどう決定するか」について書かれた書籍です。
(引用終了)

ソフトウェアアーキテクチャ・ハードパーツ - Forkwell Library #12に参加してきた - 天の月

(引用開始)
レガシーで大規模なモノリシックシステムをどう解決していくか?というのを物語形式で紹介してくれているということです。

ソフトウェアの中でも土台となるような部分の決定は「モノリシックなシステムをどう分解していくか?」で前半部分に表現され、「ソフトウェアアーキテクチャをどう決めるか?」は分散システムで直面する難しい問題をどのように決定するか?で後半部分に表現されているということです。

もう少し具体的に言うと、前半部分は戦術的フォークとコンポーネントベース分解を中心に登場人物がトレードオフ分析を行なっている様が描かれており、後半部分は、粒度分解要因と粒度統合要因のバランスによって決定されるという前提をもとに、分解をどこまでするかが具体的に描かれているそうです。
(引用終了)

「ソフトウェアアーキテクチャの基礎」読書感想

【1】「マイクロサービスの大きさと通信方式をどう決定するか」が根本テーマであるとすれば、マイクロサービスの設計上の課題や留意点がテーマになる。

2020年代の現在では、マイクロサービスの実装はAWSなどのクラウド基盤が前提条件だろう。
AWSならEC2ではなく、CloudFormationを使って各種サービスを組み合わせて一体化したシステム設計をするのではないか。
一方、オンプレ環境のシステムでは、弾力的なスケーラビリティ向上、つまりスケールアップやスケールアウトを動的に変更するのは非常に難しい。
逐一サーバースペックをサイジングしてどれだけのスペックを持つべきか見積もりして導入するまでに非常に手間がかかる。

では、マイクロサービスの落とし穴はどこにあるのか?
マイクロサービスの利点や美味しいメリットを得るにはどんな留意点があるのか?

モノリシックな基幹系システムやモノリシックな巨大なシステムをビジネス上の観点でサービスごとに分割して、分散サービス化した時、それぞれのサービスの粒度は小さくなるので運用保守しやすくなる点もあるだろう。
昨今のDevOpsの観点では、小さな開発チームが設計や開発から運用までを担当する流れなので、チームが担当するシステムのサイズは小さい方が実現しやすい。

一方で、複数のサービスを連携して初めて、顧客が満足する1つのユースケースが成り立つような場合、途中でサービスが停止すると成り立たなくなる。
分散サービスのアイデアは20年以上前のCORBAやEJBからずっと言われていては失敗してきたが、クラウド基盤でようやく実現可能な設計手法になった面もあると思う。
僕はまだAWSやクラウド基盤のことは無知なので、今までのオンプレ環境で構築するシステム設計とは違った観点がマイクロサービスの設計にはあるのだろうと思う。

理解できた内容はBlogに残しておこうと思う。


| | コメント (0)

2023/09/30

パッケージ設計の原則の意義は変化しているのか

パッケージ設計の原則についてちょっと議論する場があり、色々考えるものがあった。
考えたことをラフなメモ書き。

【参考】
パッケージ設計の原則を本で学ぶ - Qiita

パッケージ設計6つの原則~ポイントは関連性/依存性/抽象度 | プレイン・プログラム

コンポーネントに関する6つの原則 - Qiita

【1】パッケージ原則6個の復習。

1. パッケージ再利用等価原則 Release Reuse Equivalency Principle
* 再利用の粒度はリリースの粒度と同じ
2. 共通閉鎖原則 Common Closure Principle
* クラスは共に変化し、共に存在する
3. 共通再利用原則 Coomon Reuse Principle
* 共に再利用されないクラスを同じグループに入れるべきではない
4. 非循環依存関係原則 Acyclic Depenedencies Principle
* パッケージ間の依存関係は循環してはいけない
5. 安定依存関係原則 Stable Dependencies Principle
* 安定している方向に依存する
6. 安定抽象原則 Stable Abstracttions Principle
* 安定したパッケージは抽象的であるべきだ

【2】パッケージ再利用等価原則が最も基本の原則と考える。

ちょっと昔のJavaシステム開発であれば、リリースモジュールwar/earがリリースの単位であり再利用の単位になる。
サブシステムごとにwar/earをビルドして検証環境でテストした後、オンプレの複数台のサーバー環境ごとに、複数のAPサーバーへwarを手動でデプロイしていた。
ロードバランサーからデプロイするサーバーを切り離して、1つずつwarファイルをデプロイして起動確認し、確認OKならば外部通信できるように設定していた。
つまり、そういう面倒な手動のリリース作業があった。

オンプレのサーバ環境にwar/earファイルをデプロイする単位は普通はサブシステム単位なので、そういう粒度で再利用しやすくする。
その場合、war/earファイルはできるだけサイズは小さい方がAPサーバ再起動時間も短くなるし、リリース作業も短くなるので、リリース作業ミスの確率も減らせる。

特に最近はAWSのようなクラウド環境では、サーバ環境そのものを使い捨てみたいにコンテナから自動生成するので、コンテナ(リリースする単位)のサイズが小さいほどサービスの再起動時間が短くなり、サービス停止時間も短縮化でき、顧客満足度も高くなる。
JavaGoldを取得した時に、モジュールの話で、モジュールサイズをできるだけ小さくしたい要望がある理由がそこにあると聞いて納得したことがあった。

クラウド上の開発がJavaに与えた影響は何なのか: プログラマの思索

Javaのモジュールシステムは複雑性をより増している: プログラマの思索

Javaのモジュールシステムの考え方をまとめてみた: プログラマの思索

【2】ただし、リリースモジュールの保守性や分割についてトレードオフがある点は理解できる。

実際、サブシステム単位にリリースモジュールwar/earをビルドする場合が多いので、普通はリリースモジュールのファイルサイズは非常に大きくなりがちだ。
なぜなら、リリースモジュールには、Apacheの共通ライブラリ、会社特有の共通ライブラリなどのJarという共通コンポーネントを多数含んでいるからだ。
同様に、RailsのようなWebアプリでも、bundlerの中には共通ライブラリGemを多数含んでいる場合が多い。

すると、リリースモジュールのファイルサイズを小さくしたくなる。
簡単に思いつくのは、リリースモジュールから他のサブシステムと共通で使う共通ライブラリは別出しして、デプロイする時は共通ライブラリは再リリースしなくて良いようにしたい。
APサーバ上に共通ライブラリを別で配置して事前ロードしておいたり、別APサーバ上に共通ライブラリを配置するケースも考えられるだろう。

メリットは、リリースモジュールのうち共通ライブラリは既にAPサーバにデプロイされているので再リリースは不要であり、リリースモジュールのサイズを小さくできる。
その分、ビルド作業時間、リリース作業時間を短縮でき、リリース作業ミスのリスクも減らせるだろう。

一方、デメリットは、共通ライブラリに手を加えた場合、既にデプロイ済みのサブシステムのwar/earファイルに影響が発生してしまう。
デグレがないか事前確認が必要だし、共通ライブラリがサブシステムのAPサーバとは別APサーバにデプロイされていて、共通ライブラリが複数のサブシステムから呼び出されているならば、複数のサブシステムに影響が発生してしまう。
共通ライブラリのリリース作業中にAPサーバを停止する事態が発生すれば、呼び出し側の複数のサブシステムで業務停止してしまうリスクが発生する。

また、共通ライブラリにサブシステムA向けのAPIを追加したり改修して、他のサブシステムB向けのAPIは触らない場合であっても、共通ライブラリをリリースする時にサブシステムAもBにも影響が発生してしまう。

だから、一般には、サブシステムごとに共通ライブラリを含んでリリースモジュールをビルドする場合が多いと思う。
すると、たとえば、サブシステムAの共通ライブラリXのバージョンは1.1、サブシステムBの共通ライブラリXのバージョンは1.2、みたいにコンポーネントのバージョンがサブシステムごとに違ってくる場合も発生するだろう。

つまり、サブシステムで利用する共通ライブラリのバージョン管理、構成管理が重要になってくる。
この仕組みがMavenであり、Railsならbundlerなのだろうと思う。
ライブラリやコンポーネントの構成管理というソフトウェアの複雑性をビルド管理の仕組みで補っているわけだ。

【3】では、昨今のアジャイル開発、DevOps、クラウドなどにより、パッケージ設計の原則の意義は変化しているのか?

メタな観点ではパッケージ設計の原則の意義は変わらない。
リリースモジュールは再利用できる単位であることは変わらないし、モジュールの分割方針やデプロイ方針も基本は変わらない。
しかし、具体的なリリース手順や開発プロセスは影響を受けていると思う。

例えば、SaaSビジネスでは、リリース作業時間は極力短くしたい。
リリース作業時間は広義の意味では、顧客に機能を提供するリードタイムと同じ。
BtoCのSaaSビジネスならば、機能改善の要件定義からリリースまでのリードタイムを短縮化する事は売上に直結する。
ちょっとした機能改善を即座にリリースできれば、顧客満足度も上がり、ユーザ数増加が売上につながるから。

また、特に昨今はクラウドでサーバーごとの仮想化するなどして丸ごとコンテナ化し、コンテナを使い捨てみたいにいくらでもデプロイできるから、リリース作業時間はできるだけ短くしたい。

これは、DevOpsの考え方と非常に相性が良いと思う。
DevOpsで開発チームがシステム運用と一体化したプロセスになるし自然にアジャイル開発になるはず。
つまり、アプリ開発者はアプリも開発するし、クラウド上でインフラ基盤もサーバー基盤もコンテナをプログラム化して自動配置できるようにすれば、開発も運用も一体化できるはず。

そして、リリース作業時間と言うKPIを開発チームが毎回計測し監視すれば、改善すべきか評価できるはず。
リリース作業時間、ビルド時間、デプロイ時間などはアジャイル開発の主要なメトリクスの一部と捉えられるだろう。
システム停止やデータ移行の時間も含めてリリース作業時間に3日間かかっていたのを、1時間で終わらせたり、わずか5分で終わらせれば、その分システム停止時間も短くでき、顧客の業務や顧客の操作時間への影響を減らせる。

そんなことを考えると、アジャイル開発やDevOpsという考え方は、サーバの仮想化やクラウドの技術のおかげで進化している部分も大きいのだろうと思う。
こんなことは既に当たり前の考え方と思うけれど、アプリ層の設計技法もインフラ基盤の仮想化技術に相当影響を受けているのではないか、と思う。

| | コメント (0)

2022/11/06

Go言語でできることは何なのか

Go言語でできることは何なのか、について考えたことをメモ。
全くのGo初心者がいろいろ考えたことのメモ。
間違えていたら後で直す。

【参考】
とほほのGo言語入門 - とほほのWWW入門

Go言語(golang)とは? 特徴・できること・将来性を徹底解説 | 【テックストックMAGAZINE】エンジニア向けスキル・キャリア情報

Go言語にできることってなに?人気の理由をくわしく解説 | 株式会社パソナ(旧パソナテック)|ITエンジニア・ものづくりエンジニアの求人情報・転職情報

Go言語の強みと得意分野を探る(上) - Go言語の強みと得意分野を探る:Computerworld

Go言語の強みと得意分野を探る(中)1 - Go言語の強みと得意分野を探る:Computerworld

Go言語の強みと得意分野を探る(中)2 - Go言語の強みと得意分野を探る:Computerworld

Go言語の強みと得意分野を探る(下) - Go言語の強みと得意分野を探る:Computerworld

Go言語でできることとは?Go言語で作れるアプリの事例を紹介 | プログラミング大陸

Ruby->Go->Scalaという習得順序がエンジニアの爆速の成長に最適である理由 - Qiita

Go言語の書籍を色々読んでみて色々気づきはあった。

Go言語は、マイクロサービスアーキテクチャを実装するプログラミング言語であるらしい。
色々記事を読んでみて、Go言語は、CLIやAPIを作るのに最適な言語であると感じた。

他システムがWebサーバーからデータを取得したり更新しようとする時、APIという公開IFを設けて疎結合な設計にしたい。
Go言語であれば簡単にHTTPでやり取りできるのでWebサーバを立ち上げる必要もなく、普通のクライアントアプリケーションみたいに作ればいい。
また、Go言語では並行プロセスの実装も割と簡単なので、負荷に応じてプロセスを増やせば良く、クラウド上でAPIを公開するためのアプリとして最適。

Go言語でCLIを作るイメージは、Unixコマンドを作るイメージだろうか。
Unixであれば、/binの中に各種コマンドがexeで配置されている。
別システムがバッチ処理をキックしてシステム連携したい場合、CLIという公開IFを叩けば良い。

そんなことを考えると、Go言語はかなり特殊な状況で使うもののように思う。
業務ロジックを実装するレイヤではなく、OSやアプリの間で処理するためのミドルウェア、ないしフレームワークみたいな役割を持つレイヤで実装すべき。

また、Go言語はクラウドと相性がいい。
Go言語はクロスプラットフォームでバイナリファイルを作れるので、CLIやAPIに向く。
また、Go言語で作ったバイナリファイルのサイズを小さくできれば、クラウドのリソースを少なく押さえられる。
また、メソッド呼び出し時のアプリ起動時間を短くでき、並行プロセスで走るアプリの起動時間(ロード時間)も短くできる

クラウド上の開発がJavaに与えた影響は何なのか: プログラマの思索

Javaのモジュールシステムの考え方をまとめてみた: プログラマの思索

つまり、Go言語はクラウド上でCLIやAPIを実装したプログラムに特化した言語なのだろう。
だから、マイクロサービスアーキテクチャと相性が良いと言われているのだろう。
そして、マイクロサービスアーキテクチャはドメインごとの境界で使われるので、ドメイン駆動設計とも相性がよく、それらの設計技法と密接に絡む。

そんなことを考えると、一昔前のオンプレ環境でのWebシステム構築で経験されて蓄積されたアーキテクチャ設計技法は古くなっており、クラウドに特化したアーキテクチャ設計技法をもっと探究していくべきだ、という方向性が出てくるのだろう。
このあたりの考え方もいろいろ調べている。

| | コメント (0)

コンテナはサーバーレスアーキテクチャのための1つの技術

コンテナとは一体何なのか?
コンテナとはサーバーレスアーキテクチャのための1つの技術にすぎない。
AWS初心者のラフなメモ。

【参考】
202106 AWS Black Belt Online Seminar CON110 なぜ今コンテナなのか

JAWS-UG初心者支部#50 ContainerをCICD PileLineでDeploy!! - connpass

[JAWS DAYS 2022] ハンズオン~コンテナサービスをCI/CDパイプラインでデプロイしよう~

AWS初心者向けにハンズオンの勉強会があったので参加してみた。
手順書に書いてある通りに、コマンドを叩くだけでVPSやAPI Gatewayなどの環境が全て作られて、CI/CDパイプラインを試せる。
AWSの実戦経験がないので全然分かっていないが、実際に動く環境を作れて、実際に試して試行錯誤できる経験を得た。
とても良かった。
AWSはたくさんのサービスが既にあるので、それらを組み合わせるだけで開発環境やSaaSを簡単に立ち上げられると実感した。

コンテナとはいったい何なのか?
コンテナとは、VMとWebアプリケーションを一体化したものみたいなイメージ。

コンテナとはどのようなもの?クラウドサービスを動かすのに必要不可欠 | クラウドエース株式会社

Dockerは何がすごいのか?
コンテナを簡単に作れてDeployできること。
クラウド上にDockerファイルをアップロードしてrunすれば、簡単にWebアプリケーションを実行できる。
既にDockerイメージはたくさん配布されている。

なぜコンテナが必要なのか?
VMで仮想サーバを建てて環境構築するだけでは、Deployや運用の手間がかかる。
クラウドでVMとWebアプリケーションを一体化したコンテナで配布すれば、いつでも最新版のWebアプリを立ち上げられる。
つまり、Webアプリケーションがどんどんバージョンアップするたびに、コンテナで新規にデプロイすれば、いつでもクリーンな環境で立ち上げられる。

すると、コンテナをもっと進化させればサーバーそのものが要らないんじゃないの?となる。
AWSラムダがそんな感じだろうか。

今回のハンズオンでは、AWSでCICD PileLineを作る前にAWS VPCをすべてコマンドで作った。
一方、オンプレであれば、ルータを導入してネットワークアドレスを切って、その上にサーバーを構築して、ソースコードをビルドする環境も作ってデプロイして、という手順が必要になる。
だから、AWSは全くの初心者だが、AWS特有のコマンドを叩きながら、なるほど、こういうネットワークを作りたいのね、とか、こういうサーバー構成にしてデプロイしたいのね、とか、色々考えるところがあった。

プログラミングはブロックを積み上げる感覚に似ているが、AWSのサーバー構築もいろんな形のブロックを当てはめて積み木を作っている感覚だった。
この面白そうな感覚はもう少し掘り下げたい。

| | コメント (0)

2022/10/16

クラウド上の開発がJavaに与えた影響は何なのか

クラウド上の開発がJavaに与えた影響は何なのだろうか。
考えがまとまっていないがラフなメモ。
自分はAWSも知らないし、Go言語も知らないので、間違っていたら後で直す。

【参考】
Javaがサーバレスに至るまでの道のり

元JavaエンジニアがGoに感じた「表現力の低さ」と「開発生産性」の話 - DMM inside

Ruby->Go->Scalaという習得順序がエンジニアの爆速の成長に最適である理由 - Qiita

Javaがサーバレスに至るまでの道のりの記事を読むと、いかに軽量のWebアプリケーションを実現するか、に注力しているように思える。

従来のWebアプリケーション開発では、PerlのCGIのようなプロセス指向ではなく、JavaのServletのようなマルチスレッドの方が無駄にリソースを食わず、効率が良いと歌われていた。

しかし、サーバーレス環境では、AWS Lambdaのようにアプリをキックするような仕組みなので、アプリの処理時間だけでなく、アプリのロード時間も短いほど優位だからだ。
サーバーレス環境では、アプリを常駐させて、マルチプロセスで動く。
そして、処理が終わり、無駄に多くなったプロセスはすぐに破棄される。

つまり、クラウドでは、DockerやK8sのようなコンテナのおかげで、アプリ環境を使い捨てにできるメリットがある。
アプリも、負荷分散に応じて必要なだけ常駐プロセスを増やして、不要になれば捨てればいい。

すると、アプリのビルド、デプロイの時間も短い方がいい。
さらに、「起動時間がレスポンスタイムに含まれる」ために、アプリの起動時間も短くできれば、サーバーレス環境ではレスポンスタイムをもっと短くできて、使い勝手が良くなる。

そういう発想がJavaにどんな影響を与えているのか?
クラウド上の開発がJavaに与えた影響は何なのか?

たまたま、Javaのモジュールシステムの話の中で、jlinkコマンドがなぜ必要なのか?という話があった。
JDK9以後は、JREが配布されないので、Javaファイルを実行できない。
そこでjlinkで実行ファイルを作る必要があるという話だったが、さらにもう一つ興味深い話があった。

Java Module System 入門 その1 - YouTube

Java Module System 入門 その2 - YouTube

jlinkコマンドを使うとランタイム専用アプリを作れるが、必要なJDKライブラリだけを読み込んで、Jarファイルを作成する。
すると、jlinkで作られたランタイム専用アプリのサイズは、従来のランタイム専用アプリのサイズよりもかなり小さくなる。
不要なライブラリを除いているからだ。
実際、デモ画面では200Mから30Mまで小さくできた例があった。

つまり、jlinkコマンドを使えば、クラウドのサーバーレス環境でアプリを実行する時、コンパイルしたアプリのサイズを小さくできる。
その分、クラウドのリソースを抑えられるし、アプリの起動時間(ロード時間)も短くできるメリットが出てくる。

すなわち、jlinkコマンドはクラウド上で配布するアプリに適合するように作られたものなのだろう。
Javaもクラウドに特化したアーキテクチャ設計を取り込んでいるのだろう。

そんな話を聞くと、サーバーレス環境のアプリでは、ランタイム専用アプリはバイナリファイルでサイズが小さいほど優位性が高いことになる。
マイクロサービスの実装言語はGoが主流であると聞くが、その理由は、Goで簡単にバイナリファイルが作れて、さらにそのサイズが小さいので、性能的にも優れている点があるのではないだろうか?
そして、Javaもそういう流れの設計手法を取り入れるために、jlinkコマンドのようなアーキテクチャが必要になってきたのではないだろうか?

ここで、クラウド上のシステム設計では、ドメインごとにアプリを細分化したマイクロサービスアーキテクチャが流行していて一般的になってきている。
マイクロサービスアーキテクチャが必要な理由は、普通のWebシステムでもクライアントからのアクセスがブラウザだけでなく、スマホだったりタブレットだったり、色んな端末に対応する必要があるので、公開APIを通じて制御できるよに、色々分割したほうが楽になる点があるだろう。
また、逆コンウェイ戦略のように、システム開発しやすいチーム組織の観点で設計すると、小さなコンポーネントの集まりになるようにシステムを分割して、マイクロサービスアーキテクチャで連携できるようにした方がよい点もあるだろう。

マイクロサービスアーキテクチャのそんな特徴を活かすには、おそらく、Go言語やjlinkコマンドのような実装言語やビルド方法も必要になってくるのだろう。

そんなことを考えると、クラウド上のシステム開発では、フロントWebシステムをRubyやJava、Pythonで作ったとしても、AWS lambdaやマイクロサービスの部分はGo言語やjlinkを使う、といったように、複数のプログラミング言語を適材適所に当てはめて開発する必要性があるのではないか。
つまり、クラウド上の開発は、単にコンテナ部分のアーキテクチャを使いこなすだけでなく、複数のプログラミング言語を適材適所で使い分けるノウハウも必要になってくるのだろう。

この辺りは妄想に近いかもしれないので間違っているかもしれない。
ただ、クラウドというアーキテクチャは、Webリソースをふんだんに使える富豪プログラミングを可能にしたからこそ、それに特化した設計手法がどんどん現れているのだろうと思う。

この発想が正しいのか、これから検証していく。

| | コメント (0)

2022/07/31

WireSharkの入門動画が分かりやすい

WireSharkの入門動画が分かりやすかったので、自分用にリンクをメモ。

【参考】
【#16 ITニュース】WireSharkを使ってDHCP通信の謎を解く - YouTube

【#16 Wire Sharkを使って見た】セキュリティのお勉強 - YouTube

【#17 Wire Sharkを使って見た 2】HTTPS TLS セキュリティのお勉強 - YouTube

【#19 Cookie 】Wireshark 解析 セキュリティのお勉強 - YouTube

インフラ/ネットワークエンジニアのためのネットワーク技術&設計入門はインフラエンジニア向けの良本だ: プログラマの思索

IPアドレッシングの計算方法: プログラマの思索

GNS3上でネットワーク図を作って、pingを色々試せるようになったが、どんなパケットが流れているのか、知るにはWireSharkが必要になる。
GNS3では、WireSharkが付属していて、ルータ間、スイッチ間のパケットを見れる。
しかし、ネットワーク初心者にとってWireSharkは難しい。
理由は、WireSharkで表示されるデータをどのように見ればよいか、分からないからだ。

書籍も色々読んでみたが、実際に動かしていないからイメージもできない。
だが、動画を見て、実際に動くところを見てようやくイメージが湧いてきた。

インフラエンジニアの人に聞くと、スイッチやルータでオンプレのネットワークを作ったとしても、何か障害があれば、WireSharkを見る時が多いらしい。
実際にどんなパケットが流れているのか、見る必要あるらしい。

特に2020年頃から、いろんな分野の解説サイトの動画が出てきて、非常に便利になったと思う。
プログラミングもネットワークも、実際に動かしてみなければ理解しづらい。
そういう意味では、今は動画を見て、手っ取り早く初心者レベルをクリアすればいいのだろう。
基本的な概念さえ押さえれば、後は、書籍や勉強会などでいくらでも知識の幅も深さも広げられる。

| | コメント (0)

2022/01/09

プログラミングしてる時はでっかいピタゴラ装置を作ってるみたいな感じ

「プログラミングしてる時はでっかいピタゴラ装置を作ってるみたいな感じ」というツイートを見つけたすごく共感した。

【参考】
Rui UeyamaさんはTwitterを使っています 「少数派の意見かもしれないけど、プログラミングしてるときはでっかいピタゴラ装置を作ってるみたいな感じで、数学が関係ある感じがあんまりしない。」 / Twitter

結城浩さんはTwitterを使っています 「@rui314 デバッグしてるときと証明読んでるときはなんか似てる。素直に読みつつ穴探ししてるみたいな感覚。」 / Twitter

英語勉強中さんはTwitterを使っています 「@rui314 めちゃくちゃわかります。僕は書いてるとき数学のことなんか考えてないです」 / Twitter

akipiiさんはTwitterを使っています 「プログラミングはこの感覚に近いな」 / Twitter

プログラミングは「ブロックを組み合わせる」感覚に似ている: プログラマの思索

「プログラミングのできる羊とできない山羊を区別する方法」の記事のリンク: プログラマの思索

「60%の人間はプログラミングの素質がない」記事のリンク: プログラマの思索

プログラマに必要なスキル: プログラマの思索

プログラムを書いている時、数学の知識を使っているかと言われるとそうではない気がする。
むしろ、APIやFWのライブラリをまずは頭に叩き込んでおき、自分が実装したい目標に対して、それらAPIをどうやって組み合わせて意図通りに動かすか、に注力している。
ちょうど、ブロックで巨大な積み木を組み立てている感じに似ている。

だから、「プログラミングしてるときはでっかいピタゴラ装置を作ってるみたいな感じ」にはとても共感するし賛同する。

たとえば、RDBでSQLをデータ抽出したり、機械学習や深層学習のライブラリを使って母集団を推定したり、マーケットを予測したり、Web上の通信を暗号化したりする時、数学の理論はAPIやライブラリの中に隠れてしまっている。
それらライブラリを呼び出すだけで、高尚な理論を使えるのは素敵だが、だからと言って、プログラミングが楽になっているわけではないと思う。

一方、やりたいことを実現するには、PythonやRDB、Webサーバー、Dockerなどの開発環境を揃えて、Githubで構成管理し、CIツールでビルド&デプロイできるようにして、Jupyter を動かせるようにしたり、IntelliJなどの開発環境を構築したり、とプログラミングの前準備がすごく多い。
普通の初心者はこの部分で挫折するのだろうと思う。

僕自身、新しい環境を揃えてプログラミングスタイルを覚える時は割と苦痛に感じる時もあった。
Ruby on Railsもそうだし、AWSでの環境構築、GNS3でのCiscoルータ&スイッチの環境構築の時もそうだ。
Python+Anacondaはまだマシだった。
プログラミングは奥が深い。

| | コメント (0)

より以前の記事一覧