WEBアプリラーニング(Part2)2021/09/10 WEBアプリケーション(Part2)について学んだことをまとめる マイクロサービス・分散トレーシング 2020/1/28 アプリ設計ではマイクロサービスという方式が使われることがある マイクロサービス ソフトウェア開発の技法の1つであり、1つのアプリケーションを、ビジネス機能に沿った複数の小さいサービスの疎に結合された集合体として構成するサービス指向アーキテクチャ (service-oriented architecture; SOA)の1種 モノリス マイクロサービスのメリット スケールアウトできる 機能が独立しているので、改修が楽になる モノリスよりも依存が少ない マイクロサービスにはインターフェースが重要 インターフェースは簡単には変えられない マイクロサービスの場合それぞれのアプリからログが出力されることになる これらのログ一元管理したい 例えば、、 Elasticsearch Kibana これで監視している 分散トレーシング トレーシングは通信 マイクロサービスはモノリスと比較して、システム全体としての振る舞いを把握することが難しい 障害発生時の原因究明が難しくなったり、システム全体でのパフォーマンスの分析が難しいという問題が顕在化 ↓ 特定のクライアントリクエストを処理するのに関わったサービスを探したり、レイテンシに関するパフォーマンスをデバッグするのに利用される レイテンシ=通信の遅延時間 マイクロサービスの場合、アプリ間の連携は通信にて受け渡ししている そのためアプリごとにログが出力される どういう経路で通信して失敗したのがどこかを突き止める必要があるとき、1リクエストごとにtrace-idが割り振られており(zipkin) 、trace-idで検索することで、それぞれのアプリのログを一括で確認することができる ログの情報はElasticsearchにて保管されている Elasticsearch JSON形式のデータベースだが、sql文とかはなく、検索エンジンみたいな感じ PCF 2020/1/29 IssS Infrastructure as a Service 情報システムの稼動に必要な仮想サーバをはじめとした機材やネットワークなどのインフラを、インターネット上のサービスとして提供する CaaS Container as a Service CaaSはアプリケーションの携帯性を高めるという特徴があります。 コンテナ化と呼ばれる技術を使えば、環境に依存せず利用できるアプリを開発することが可能 PaaS Platform as a Service ソフトウェアを構築および稼動させるための土台となるプラットフォームを、インターネット経由のサービスとして提供する。 開発者は、プラットフォーム上で構築したサービスを自分の顧客に提供することができる。 FaaS Function as a Service サーバレスで利用できるクラウドサービス サービスベンダーがサーバの管理をすべて担うため、アプリ開発者はサーバの存在を意識する必要がありません SaaS Software as a Service これまでパッケージ製品として提供されていたソフトウェアを、インターネット経由でサービスとして提供・利用する G Suite やSalesforceなどがSaaS型サービスの代表例として挙げられる Cloud Foundryとは 業界標準のオープンソースのPaaSソフトウェアのこと Pivotal Cloud Foundryとは Pivotal社が提供しているPaaS環境のことで、Pivotal版のCloud Foundryということ PaaS利用によるメリット 従来ではエンジニアが、アプリケーション開発のみならずサーバ構築から負荷対策によるスケールアウト・ロードバランシングなど、作成したサーバの保守運用まで行う必要があったためとてつもない工数がかかっている サーバに障害があった場合は、休日問わず対応する必要があるため、決してホワイトとは言えない業務を行なっていた ↓ PaaSを利用することによってエンジニアはアプリケーションの開発だけにフォーカスすることができ、サーバの保守運用という報われない仕事から解放されることができる これにより プラットフォームチーム Docker、AWS、Elasticsearch アプリチーム アプリ開発 このように分けている アプリを開発後、「cf push」を実行すると開発したソースコードをPCFにアップロードして PCF側でよしなに色々行われた後に、「https://XXXX」として作成したアプリケーションの画面が見れるようになっている 12 Factor 2020/1/30 THE TWELVE-FACTOR APP そもそもPaaSを実施する上で、下記を実施したい アプリ開発以外の多々設定値に伴う時間とコストを最小化するために宣言的なフォーマットを用いて、セットアップを自動化する 下層のOSへの依存関係を明確化し、実行環境間の移植性を最大化する クラウドプラットフォーム上へのデプロイすることで、サーバ管理やシステム管理を不要なものにする ツール、アーキテクチャ、開発プラクティスを大幅に変更することなくスケールアップできる これらを作り上げるための方法論としてTwelve-Factorがある herokuからきている herokuとは アプリケーションを実行するためのプラットフォームで、サーバやOS、データベースなどの「プラットフォーム」と呼ばれる部分を、インターネット越しに使えるようにしてくれるサービスの一つ herokuを使えば、開発したWEBアプリケーションを面倒な手続きなく簡単に公開することができる 拡張機能が豊富 スケールアウトが簡単 運用をサポートする標準機能が揃っている The Twelve Factors コードベース バージョン管理されている1つのコードベース(GitHub)があり、それをもとにしてどこでもデプロイできる環境とすること。 依存関係 依存関係を明示的に宣言し分離する 1つのアプリを独立して立ち上げることをするために。 設定 Javaの設定とかそういう設定に関しては環境変数に格納しておく バックエンドサービス RDBなどといったデータ保管庫(リソース)はアプリに依存するのではなく、バックエンドとしてアタッチ(取り付け外し)可能な仕組みにしておく ビルド、リリース、実行 ビルド、リリース、実行の3つのステージを厳密に分離する プロセス アプリケーションを1つもしくは複数のステートレスなプロセスとして実行する ステートレス 1つのアプリにのみ特有の情報を付与するようなことはなく、スケールアップしたときにも同様の結果となるようにしておく ポートバインディング ポートバインディングを通してサービスを公開する Webアプリケーションは ポートにバインドすることでHTTPをサービスとして公開し、 そのポートにリクエストが来るのを待つ 並行性 プロセスモデルによってスケールアウトする 廃棄容易性 高速な起動とグレースフルシャットダウンで堅牢性を最大化する すぐに起動でき、すぐにシャットダウンできるようにしておく 開発/本番一致 開発、ステージング、本番環境をできるだけ一致させた状態を保つ ログ ログをイベントストリームとして扱う アプリから出力されるログはイベントの流れを示すものであり、Twelve-Factorとしてはログの送り先やストレージに関しては関知しない →ログをファイルとして取り扱おうが、Elasticsearchから取り扱おうが関与しないということ (ログはログファイルに書き込まれるという概念をもつのではなく、イベントストリームとして捉えよということ) 管理プロセス 管理タスクを1回限りのプロセスとして実行する 12factor 冪等性 2020/2/3 冪等性(idempotence) ある操作を1回行っても複数回行っても結果が同じであることをいう概念 APIを投げたあとに、何らかの外的影響によりレスポンスが返ってこなかったとき、再度APIを投げたとしても返却されるレスポンスは変わらないということである。 RESTのうち POST : 冪等ではない 複数回投げたとき、結果は同じにならない PUT : 冪等 DELETE : 冪等 POSTでユーザ追加処理をするとき、{name:oiso, age:25}というリクエストを2回投げると結果は二人登録されている状態となる 一方でPUT、DELETEは更新、削除を1回実施しても、複数回実施しても実施後のDBの状態は変わらないため、冪等であるということになる Circuit Breaker 遮断機 電力回路・電力機器の正常動作時の負荷電流を開閉するとともに、保護継電器と連携して事故電流(特に短絡事故電流)などを遮断することにより負荷側の設備を保護し、上流側への事故波及を防止する開閉器である Concourse CI CIツール(継続的インテグレーション) Jenkinsみたいなやつ 開発者がアプリ作成し、GiHubにあげるとConcourse CIがmavenからアプリ立ち上げまでを実施してくれる Concourse CIの設定はアプリ側の.ymlに記載しておく Observability 2020/2/4 Observabilityという考え方 この3つの〇についてのこと 関数型インターフェース 2020/2/18 関数型プログラミング 関数 入力に対して出力がただひとつに定まること y = f(x) f(x)という関数の結果はyということ プログラミングでいうなら入力とは引数で出力とは戻り値 メリット 記述自体が簡潔になることが多く、コードが読みやすい テストしやすい パッケージ java.util.function Supplier 結果のサプライヤを表します。 f() = T → 引数なしで特定の結果を返す Consumer 単一の入力引数を受け取って結果を返さないオペレーションを表します。 f(T) = X → 引数を受け取って結果を返さない(void処理) Function<T,R> 1つの引数を受け取って結果を生成する関数を表します。 f(T) = R → 引数を受け取って結果を返す ↑基本はこの3つで操作できる BiFunction<T,U,R> 2つの引数を受け取って結果を生成する関数を表します。 f(T,U) = R Predicate 1つの引数の述語(boolean値関数)を表します。 f(T) = boolean BiFunction<T,BiFunction<U,V,R1>,R2> f{T,f(U,V)} = R2 → 3つの引数を受け取って(T,U,V)結果を返す Circuit Breaker(Hystrix) 2020/2/18 通信失敗が99%であっても1%でも生きているのであればAPIは投げるべきという思想 GeoのHystrixは5秒に1回確認を行っている Hystrixは今後更新されない Geoで使っているからといってHystrixがいいわけではない Resilience4j というライブラリがHystrixの代わりとなる Resilience4j Circuit Breaker 生きているかの確認 Bulkhead 同時処理数 指定した件数を超えるとウエイトしたりする RateLimiter 429 Too Many Requests ユーザーが指定された時間内に多くのリクエストを送信した (“rate limiting”) ことを示す Retry 簡単にリトライできる Cache Circuit Breaker カウントベース と タイムベース カウントベース 指定回数に達した時点の成功の割合をカウントし、生存確認を行う ex)100回のリクエストに対し、OKの割合が指定数よりも低ければオープンにする タイムベース 指定時間内での成功の割合をカウントし、生存確認を行う ex)1分間のリクエストに対し、OKの割合が指定数よりも低ければオープンにする 元ネタ 電気回路のブレーカーのこと。 事故や故障で大きな電流が流れたときに自動的に遮断して配線を保護する機構のことを指す(らしい) RestClientException 2020/3/4 ignoreExceptions = HttpClientErrorExceptionの場合 400系が返ってきたら → サーキットブレーカーはオープンしない 500系が返ってきたら → サーキットブレーカーはオープンする ケースとして多いのが、 ignoreExceptions = RestClientResponseException → なんらかの応答があれば、オープンしない Timeoutエラーに関して=応答がない場合にはオープンする Timeoutエラーは2種類 リクエストしたときにタイムアウトエラー レスポンスされるときにタイムアウトエラー cfとfly 2020/3/4 PCF cfコマンドのインストール https://github.com/cloudfoundry/cli/releases versionは6系であること PCFにログインする cf login -a https://xxxx ログインすると、コマンドが案内してくれる PUSHする (jarが格納されているディレクトリ配下にて実施) ex) cf push hello-world -p target\hello-world-0.0.1-SNAPSHOT.jar cf push APP_NAME [-p PATH] (jarがあるディレクトリで実行) PCF上にアプリが立ち上がる Pivotal Apps Managerで確認 インスタンス数やイベントログを確認できる これで立ち上がるが、業務的にはmanifestから指定してデプロイすることが多いので下記参照 manifest.yml (こちらのコマンドかPUSHが多い) cf pushはデフォルトのインスタンス数、ディスク制限、メモリ制限などでアプリケーションをデプロイする manifest.ymlを用いることで、マニフェストファイルにキーと値のペアを指定してデフォルト値を上書きしてデプロイできる マニフェストのメリット 異なるクラウド間でアプリケーションを移植できるので、一貫性と再現性が保たれる cf push -f ./manifest-dev.yml (-f で指定されたパスのマニフェスト・ファイルが使用されます。) → 上記パスのプロジェクトディレクトリにてPUSHすることで、デプロイされる cf push -f ./some_directory/some_other_directory/ ( -f が指定するパスに存在するmanifest.ymlの使用) .ymlの書き方 applications: - name: my-app memory: 512M host: my-host" マニフェストは3つのダッシュで始まる アプリケーション・ブロックは見出しとそれに続くコロンで始まる アプリケーション名の前にダッシュとスペースが1つある ブロック内の後続の行は、nameと整列するために2つのスペースでインデントされる 最小限のマニフェストでは、アプリケーション名のみが必要 flyコマンド インストール Concourseのダッシュボードの右下からflyコマンドをダウンロードする sudo mv /mnt/c/Users/xxx/Downloads/fly /usr/local/bin/fly sudo chmod 775 /usr/local/bin/fly ログイン fly -t 「ターゲット名」 login -c 「URL」 ログインするためのURLが出るのでアクセス 一覧 fly -t 「ターゲット名」 pipelines pipeline.ymlのチェック pipeline.ymlが適切なファイルかどうかを確認する fly validate-pipeline -c 「パイプラインのファイル名」.yml セット fly -t 「ターゲット名」set-pipeline -p 「パイプライン名」-c 「パイプラインのファイル名」.yml 初期状態はスキップ設定(コンコースの画面上では青字)となるのでpaused設定解除する fly -t 「ターゲット名」unpause-pipeline -p 「パイプライン名」 削除 fly -t 「ターゲット名」 destroy-pipeline -p 「パイプライン名」 パス(スキップ設定) fly -t 「ターゲット名」 pause-job --job 「パイプライン名」/「job名」