目次
トレーニング
最後の時間私たちはその置かれ、静的なWebページをダミーに終わったが、ウェブのためのフラッターを使用して開発しました。このページにはサービスの開発の進捗状況が表示されますが、開発の開始日とリリース日のデータをアプリケーションにハードコーディングする必要がありました。したがって、ページ上の情報を変更する機能が失われました。データサーバーアプリケーションを開発する時が来ました。すべてのサービスアプリケーションの図は、記事「Dart言語でのサービス:はじめに、バックエンドインフラストラクチャ」にあります。
この記事では、Aqueductフレームワークを使用してアプリケーションを作成します、さまざまなモードでのパフォーマンスとリソース消費を評価し、WindowsおよびLinuxのネイティブアプリケーションにコンパイルするためのツールキットを作成し、ドメインアプリケーションクラスのデータベーススキーマの移行を処理し、ツールドッカーイメージをパブリックDockerHubレジスタに公開します。
使いやすさ
Aqueductのインストール
Dart開発ツールのセットであるdart-sdkをインストールすることから始めましょう。ここで提案されているように、オペレーティングシステムのパッケージマネージャーを使用してインストールできます。ただし、Windowsの場合、デフォルトではパッケージマネージャはシステムにインストールされていません。これだけ:
- アーカイブをダウンロードして、Cドライブに解凍します。
- , , , . . « »

- Path . dart , , C:\dart-sdk\bin
- , dart pub ( dart)
dart --version
pub -v
- , ,
- aqueduct CLI (command line interface)
pub global activate aqueduct
aqueduct

理論的には、PostgreSQLデータベースサーバーをローカルにインストールすることも可能です。ただし、Dockerを使用すると、この必要性を回避し、開発環境をサーバー上のランタイムと同様にすることができます。
アプリケーションの生成
それでは、VsCodeでサーバーフォルダを開きましょう
code c:/docs/dart_server
最初と2番目の記事を 見たことがない人のために、ソースコードはguthubリポジトリからクローン化できます。
git clone https://github.com/AndX2/dart_server.gitアプリケーションテンプレートを作成しましょう:
aqueduct create data_app
プロジェクトテンプレートの内容を理解しましょう。
- README.md-水道プロジェクトの操作方法、テストの実行方法、APIドキュメントの生成方法などを説明するメモ。サポートファイル。
- pubspec.yaml — pub. , , , .
- config.yaml config.src.yaml — . .
- analysis_options.yaml — ( ). .
- .travis.yml — (continuous Integration). .
- pubspec.lock .packages — pub. — , , — ().
- .dart_tool/package_config.json — , aqueduct CLI. .
- bin/main.dart — (, ). ( ).
- lib/channel.dart — ApplicationChannel — . Aqueduct CPU RAM. ( Dart isolate) () .

- lib/data_app.dart — . (library) dart_app
- test/ — . -, . Postman.
構成
解決すべき最初のタスクは、起動時にアプリケーションをセットアップすることです。Aqueductには、構成ファイルからパラメーターを抽出するための組み込みメカニズムがありますが、このメカニズムは、Dockerコンテナーで実行する場合にはあまり便利ではありません。私たちは異なる行動を取ります:
- 変数のリストをコンテナオペレーティングシステムに渡しましょう。
- コンテナ内でアプリケーションを起動するときに、オペレーティングシステムの環境変数を読み取り、それらを初期構成に使用します。
- ネットワーク上で実行中のアプリケーションのすべての環境変数を表示するためのルートを作成しましょう(これは、管理パネルからアプリケーションの状態を表示するときに役立ちます)。
/ lib フォルダーに、環境変数にアクセスするためのいくつかのフォルダーと最初のリポジトリを作成します。コンストラクターの
EnvironmentRepositoryは、オペレーティングシステムから環境変数をMap <String、String>辞書として読み取り、プライベート変数_envに保存します。辞書の形式ですべてのパラメーターを取得するメソッドを追加しましょう:lib / service / EnvironmentService -EnvironmentRepositoryデータアクセスの論理コンポーネント:
依存性注入
ここで、コンポーネントの依存関係を停止して処理する必要があります。
- ネットワークコントローラには、可変サービスのインスタンスが必要です。
- サービスはアプリケーション全体で一意である必要があります。
- サービスを作成するには、最初に変数リポジトリのインスタンスを作成する必要があります。
GetIt ライブラリを使用してこれらの問題を解決します。接続に必要なパッケージpubspec.yaml:
インジェクターコンテナのインスタンス作成LIB /ジ/ di_container.dartを、リポジトリとサービスの登録と方法を記述します 通話アプリケーションの調製方法でDIコンテナの初期化方法:
ネットワーク層
lib / controller / ActuatorController -httpネットワーキングコンポーネント。アプリケーションのサービスデータにアクセスするためのメソッドが含まれています。lib/ controller / Routes でコントローラーのルートハンドラーを宣言しましょう:
最初のスタート
実行するには、次のものが必要です。
- アプリケーションをDockerイメージにパッケージ化し、
- docker-composeスクリプトにコンテナを追加します。
- リクエストをプロキシするようにNGINXを構成します。
アプリケーションフォルダにDockerfileを作成します。これは、Dockerのイメージをビルドして実行するためのスクリプトです 。docker -compose.yamlスクリプトに アプリケーションコンテナを追加します。アプリケーションの構成変数を使用してdata_app.envファイルを作成します 。NGINXデバッグに新しい場所を追加します。configconf.dev.d/ default.conf: デバッグを実行します。ビルド前フラグのあるスクリプト:
docker-compose -f docker-compose.yaml -f docker-compose.dev.yaml up --build
スクリプトは正常に実行されましたが、いくつかの注意点があります。
- グーグルからの公式ダーツ画像は290MBアーカイブされています。開梱すると、はるかに多くのスペース(754MB)を使用します。画像とそのサイズのリストを表示します。
docker images - ビルドとJITのコンパイル時間は100秒以上でした。セール中のアプリを実行するには多すぎます
- 起動直後のドッカーダッシュボードのメモリ消費量300MB
- ストレステスト(ネットワークGET / api /アクチュエータ/リクエストのみ)では、1つの分離で実行されているアプリケーションのメモリ消費量は350〜390MBの範囲です。
おそらく、私たちの予算VPSのリソースは、そのようなリソースを大量に消費するアプリケーションを実行するのに十分ではありません。確認しよう:
- 新しいバージョンのアプリケーション用のフォルダーをサーバー上に作成し、プロジェクトの内容をコピーします
ssh root@dartservice.ru "mkdir -p /opt/srv_2" && scp -r ./* root@91.230.60.120:/opt/srv_2/ - 次に、このフォルダにWebページプロジェクトを/ opt / srv_1 / public /から転送して/ opt / srv_1 / sertbot /フォルダの内容全体(NGINXのSSL証明書とボットログを暗号化しましょう)を転送し、キーを/ optからコピーする必要があります。 / srv_1 / dhparam /
- 別のコンソールでサーバーリソースモニターを起動します
htop
- / opt / srv_2 /フォルダーでdocker -composeスクリプトを実行してみましょう
docker-compose up --build -d - 起動前のアプリケーションビルドは次のようになります。
- そして-作業中:
利用可能な1GBのRAMのうち、アプリケーションは不足しているページングファイルを「占有」して1.5GBを消費します。はい、アプリケーションは起動しましたが、負荷容量については話していません。 - スクリプトを停止しましょう:
docker-compose down
AOT
解決すべき3つのタスクがあります。
- ダーツアプリケーションによるRAMの消費を削減します。
- 起動時間を短縮し、
- アプリケーションのドッカーコンテナのサイズを縮小します。
解決策は、実行時にダーツを放棄することです。バージョン2.6以降、dartアプリケーションはネイティブ実行可能コードへのコンパイルをサポートします。Aqueductは、バージョン4.0.0-b1以降のコンパイルをサポートしています。
水道橋CLIをローカルで削除することから始めましょう。
pub global deactivate aqueduct
新しいバージョンをインストールします。
pub global activate aqueduct 4.0.0-b1
pubspec.yamlで依存関係を上げましょう
:ネイティブアプリケーションを構築しましょう:
aqueduct build
結果は、サイズが約6MBの単一ファイルdata_app.aotアセンブリになります。次のようなパラメータを使用して、このアプリケーションをすぐに起動できます。
data_app.aot --port 8080 --isolates 2
起動直後のメモリ消費量は10MB未満です。
負荷がかかっているところを見てみましょう。テストパラメータ:ネットワークGET /アクチュエータ要求、利用可能な最大速度で100スレッド、10分。結果:
合計:平均速度-1.4kV JSON応答本体で1秒あたり13kリクエスト、平均応答時間-7ミリ秒、メモリ消費量(2インスタンスの場合)42MB。エラーはありません。
アプリケーションの6つのインスタンスでテストを繰り返すと、もちろん平均速度は19k / sに上昇しますが、メモリ消費量が64 MBの場合、プロセッサの使用率は45%に達します。
これは素晴らしい結果です。
コンテナパッキング
ここでもう1つの問題に直面します。それは、dartアプリケーションを現在のOSのネイティブにしかコンパイルできないことです。私の場合、これはWindows10x64です。ドッカーコンテナでは、もちろんLinuxディストリビューションの1つ、たとえばUbuntu20.10を好みます。
ここでの解決策は、Ubuntuのネイティブアプリケーションを構築するためにのみ使用される中間のドッキングスタンドです。それを書いてみましょう/ dart2native / Dockerfile: それをaqueduct_builder:4.0.0-b1という名前のdockerイメージにビルドして、古いバージョンがある場合はそれを上書きします。
docker build --pull --rm -f "dart2native\Dockerfile" -t aqueduct_builder:4.0.0-b1 "dart2native"
確認しよう:
docker images
ネイティブアプリケーションdocker-compose.dev.build.yamlのビルドスクリプトを作成しましょう: ビルドスクリプトを実行します。
docker-compose -f docker-compose.dev.build.yaml up
Ubuntu用にコンパイルされたファイルdata_app.aotはすでに9MBかかります。起動時に、19 MBのRAMを使用します(2つのインスタンスの場合)。同じ条件でローカル負荷テストを実行しましょう。ただし、NGINXプロキシ(GET、100スレッド)を備えたコンテナで:
平均して、1秒あたり5.3kリクエスト。同時に、RAMの消費量は55MBを超えませんでした。設置されているダーツと水道橋に比べて、画像サイズが840MBから74MBに減少しました。アプリケーションを起動するための
新しいスクリプトdocker-compose.aot.yamlを作成しましょう。これを行うには、ベースイメージ「空の」Ubuntu:20.10をインストールして、data_appdescriptionブロックを置き換えます。アセンブリファイルをマウントして、起動コマンドを変更してみましょう。
もう1つのサービスの問題を解決しましょう。実際、ダーツと水道橋がインストールされたドッカービルドイメージは、非常に再利用可能なツールです。パブリックレジスタにアップロードして、既製のダウンロード可能なイメージとして接続することは理にかなっています。これには以下が必要です。
- DockerHubのようなパブリックレジスタに登録します。
- 同じログインでローカルにログインする
docker login - ログイン/タイトルを使用してアップロードされた画像の名前を変更します:タグスキーム
docker image tag a365ac7f5bbb andx2/aqueduct:4.0.0-b1 - イメージをレジスタにアンロードします
docker push andx2/aqueduct:4.0.0-b1
https://hub.docker.com/repository/docker/andx2/aqueduct/general
これで、パブリックイメージを使用するようにビルドスクリプトを変更できます
データベース接続
Aqueductには、PostgreSQLデータベースを操作するためのORMがすでに組み込まれています。それを使用するには、次のものが必要です。
- データベース内のレコードを記述するドメインオブジェクトを作成します。
- . : , , . Aqueduct , , ManagedObject ( ), , . .
- . , , .
- , aqueduct, , seed() — - .
- aqueduct CLI.
docker-compose.aot.yamlスクリプトで新しいdockerコンテナをPostgreSQLデータベースに接続することから始めましょう。Linux Alpine(組み込みアプリケーション用のLinuxの「コンパクト」バージョン)に基づくレディイメージ: ここでは、環境変数ファイルdata_db.envに注意を払う必要があります。実際、イメージは、これらの変数をユーザー名、ホスト、ポート、およびアクセスパスワードとして使用するように事前構成されています。これらの変数をファイルに追加しましょう: 値は条件付きで与えられます。 また、ホストフォルダ./data_db/をデータベースデータを保存するためのコンテナにマウントします。 次に、data_appアプリケーションで、/ service / DbHelperクラスを追加して、環境変数を使用してデータベースに接続します。
ORMが管理するドメインオブジェクトを作成して、クライアントアプリケーションの設定を取得しましょう。 リポジトリとサービスを追加して設定を追加し、現在のバージョンを取得します。 ネットワークコントローラー: DIコンテナーに新しいコンポーネントを登録 します。ルーターに新しいコントローラーとエンドポイントを追加します。 次に、データベース移行ファイルを生成します。実行しましょう:
aqueduct db generateその結果、プロジェクトフォルダに移行ファイルが作成されます。
サービスの問題を解決する必要があります。水道橋(およびダーツ)がインストールされたシステムからコンテナで実行されているデータベースに移行を適用する必要があります。これは、ローカル開発中とサーバー上で実行する必要があります。この場合、以前に作成および公開されたイメージをAOTアセンブリに使用します。対応するdocker-composeデータベース移行スクリプトを作成しましょう
。興味深い詳細は、データベース接続文字列です。スクリプトを実行するときに、環境変数を引数として持つファイルを渡し、スクリプトでの置換にこれらの変数を使用できます。
docker-compose -f docker-compose.migrations.yaml --env-file=./data_app.env --compatibility up --abort-on-container-exit
起動フラグにも注意を払いましょう。
- --compatibility --docker-composeバージョンの2.xスクリプトとの互換性。これにより、デプロイオプションを使用して、コンテナによるリソースの使用を制限できますが、バージョン3.xでは無視されます。RAM消費量を200MBに、CPU使用量を50%に制限しました
- --abort-on-container-exit-このフラグは、スクリプト実行モードを設定して、スクリプトコンテナーの1つが停止すると、他のすべてが終了するようにします。したがって、データベーススキーマを移行するコマンドが実行され、水道橋のあるコンテナが停止すると、docker-composeはデータベースコンテナも終了します。
出版物
アプリケーションの公開の準備をするには、次のことを行う必要があります。
- data_app.env data_db.env. , POSTGRES_PASSWORD=postgres_password
- docker-compose.aot.yaml docker-compose.yaml.
- /api/actuator. .
アプリケーションフォルダ./data_app/をサーバーにコピーします。ここで重要な点は、copyコマンドの-pスイッチ(ファイル属性を保持しながらコピー)です。ネイティブアプリケーションを構築するときに、data_app.aotファイルに実行権限を設定することを思い出してください。
scp -rp ./data_app root@dartservice.ru:/opt/srv_1
また、コピーしましょう:
- NGINX構成を変更しました./conf.d/default.conf
- 起動および移行スクリプトdocker-compose.yaml、docker-compose.migrations.yaml
- 環境変数data_app.envおよびdata_db.envを持つファイル
サーバーに/ opt / srv_1 / data_dbフォルダーを追加します。これは、データベースコンテナにマウントされるホストファイルシステムボリュームです。すべてのPostgreSQLデータはここに保存されます。
mkdir /opt/srv_2/data_db
データベーススキーマを移行するためのスクリプトを実行してみましょう。
docker-compose -f docker-compose.migrations.yaml --env-file=./data_app.env up --abort-on-container-exit
アプリケーションスクリプトを実行してみましょう。
docker-compose up -d
->ソースコードgithub
結論の代わりに
バックエンドアプリケーションのフレームワークの準備が整いました。次の記事では、それに基づいて、サービスユーザーを承認するための新しいアプリケーションを作成します。これを行うには、oAuth2仕様を使用し、VKおよびGithubと統合します。