Upstart Event System:その概要と使用方法

前書き

*初期化*は、すべてのスクリプトとサービスの動作を制御するためのUnixベースのオペレーティングシステムの中心にある重要な手順です。 これは、起動とシャットダウンの重要なポイントで問題が発生する可能性があり、最適なパフォーマンスを確保することが優先されるサーバー環境では不可欠です。

本質的に、初期化は次の種類のプロセスに従います。

  1. サーバーが起動します

  2. * init *プロセスが実行されます(通常は「+ PID 1+」として)

  3. 事前定義された一連の起動タスクが順番にアクティブになります

初期化は、クラウドサーバーが正常に起動およびシャットダウンできるようにする責任があります。

Unixを基盤とする一部のディストリビューションは、初期化に標準の* init プロセスを利用します。 この記事では、 Upstart *を見ていきます。これは、サーバーの運用を強化できる実用的で強力な代替品です。

従来のinitの何が問題になっていますか?

従来の初期化は線形プロセスに従います。個々のタスクは、システムの起動時に事前定義された順序でロードされます。 特に急速に変化する状況では、これはあまり役に立ちません。 理由を理解するために、たとえば、ストレージデバイスを追加してサーバーの環境を変更したと想像してください。

初期化プロセスでは、環境の突然の変化を考慮することができません。つまり、追加のストレージを認識する前にクラウドサーバーを再初期化する必要があります。 オンザフライ検出は必要なものですが、従来の初期化手順の機能ではありません。

線形シーケンスでの起動にも時間がかかります。これは、高速展開が不可欠なクラウドベースの環境では特に不利です。

また、システムがロードされた後のタスクのステータスについて心配するかもしれません。 残念なことに、* init *は、起動時または電源切断時のみシーケンスに関係します。

同期ブートシーケンスは望ましくありません。 厳格なシステムは昨日のシステムをサポートできますが、今日は動的です。

そこで、* Upstart *が登場します。これらの問題に対する高度な機能を備えたソリューションです。

一連のタスクのプリセットリストではなく、_real-time_イベントに基づいて、この置換initデーモンは、タスクの開始と停止を処理し、システムの実行中にこれらのプロセスを監視します。

この新しい非同期処理により、厳密なブートシーケンスが不要になります。 リアルタイム処理は概念化するのが面倒かもしれませんが、Upstartは最も複雑なシステムをサポートし、* jobs *の構造を使用してすべてをチェックし続けることができます。

Upstartの概要

image:https://assets.digitalocean.com/articles/upstart_event_system/1.png [Upstart Logo]

Upstartイベントシステムは、最初から柔軟に設計されており、従来の初期化システムとは異なるさまざまな概念を利用しています。 ソリューションはデフォルトでRed Hat Enterprise Linux(RHEL)6、GoogleのChrome OS、Ubuntuにインストールされますが、最近の議論によりこれが継続するかどうか混乱が生じています。

仕事

Upstartの世界では、ジョブは作業プロセスであり、タスクジョブ(目的あり)とサービスジョブ(バックグラウンドで実行可能)に分かれています。 また、抽象ジョブもあります。管理特権を持つユーザーによって停止されるまで、永久に実行されるプロセスです。

イベント

ただし、*イベント*は、ジョブまたは別のイベントで特定のアクションをトリガーするために使用される信号または「呼び出し」です。 イベントの一般的な形式は、プロセスの監視を指します: + starting ++ started ++ stopping +`および `+ stopped +

イベントの発行

イベントをブロードキャストするプロセスは「発信」と呼ばれます。これは通常、プロセスまたはジョブの状態が原因ですが、管理者は `+ initctl emit <event> `コマンドを発行してイベントを手動で発行することもできます。 Upstartに関連するさまざまな操作をナビゲートするときに、 ` init control +`コマンドが非常に役立つことに気付くでしょう。

最初のジョブ設定を書く

UpstartはUbuntuで良好に動作することが知られているため、開始する前に* Ubuntu 14.04 Droplet *を起動してください。

準備ができたので、ジョブ構成ファイルが有効であるためには3つの基本原則に従う必要があることを理解することが重要です。

  • 空にしないでください(コンテンツのないファイル)

  • 構文エラーを含めることはできません

  • * stanza *と呼ばれるコマンドブロックを少なくとも1つ含める必要があります

とりあえず基本のままにしましょう。 すぐに、 + / etc / init`ディレクトリに + testjob.conf + `というファイルを作成します。 この場合、「init」は「初期化」の短縮バージョンとして使用されます。

`+ .conf +`ファイルの関連付けに注意してください。これは、*ジョブ設定ファイル*を作成することを示しています。

このチュートリアルでは、コマンドラインテキストエディター* nano *をお勧めします。 これらのコマンドの中には、 `+ sudo +`で管理者権限が必要な場合があるため、https://www.digitalocean.com/community/tutorials/how-to-add-delete-and-grant-sudo-privileges-to-をチェックしてください。 users-on-a-debian-vps [この記事]で適切なユーザーを作成します。

テストジョブの新しい構成ファイルを作成するには、次を実行します。

sudo nano /etc/init/testjob.conf

それでは、目的の概要を説明しましょう。 このジョブがメッセージと現在のタイムスタンプをログファイルに書き込むようにします*。

ジョブスクリプトの目的と作成者を定義するのに役立つ2つの基本的なスタンザ、 `+ description `と ` author +`があります。 これらをファイルの最初の行として記述します。

description "A test job file for experimenting with Upstart"
author "Your Name"

ここで、システムサービスとプロセスが既にロードされた後に(競合を防ぐために)このジョブを実行するため、次の行に次のイベントを組み込みます。

start on runlevel [2345]

ランレベルとは何か疑問に思うかもしれません。 基本的に、現在のシステム構成を表す単一の値です。 `+ [2345] +`は、一般的なLinuxアクセスとネットワーキングを備えたすべての構成状態を指し、基本的なテスト例に最適です。

次に、実行コードを追加します。 この行は「+ exec +」で始まり、次のコマンドをBashシェルで実行する必要があることを示します。

exec echo Test Job ran at  `date` >> /var/log/testjob.log

この `+ echo `コマンドはバックティックを使用して ` date `をコマンドとして実行し、メッセージ全体をログファイルに書き込みます。 バックティックなしで単語「 date +」を書いた場合、コマンドの出力の代わりに単語自体が印刷されます。

このファイルを保存して閉じます。

ジョブが手動で開始されることでこれが機能することを確認できますが、最初に構成ファイルの構文を確認しましょう。

init-checkconf

問題が検出された場合、このコマンドは特定の行番号と問題を示します。 ただし、テストジョブでは、次のような出力が表示されます。

File /etc/init/testjob.conf: syntax ok

このコマンドは、UpstartジョブおよびWebサーバーなどの他のバックグラウンドサービスの制御に使用できます。

基本的なコマンド構文は次のとおりです。

sudo service <servicename> <control>

この構文は、次の基本的なコントロールで機能します。

  • 再起動:これは停止し、サービスを開始します

  • start:実行されていない場合、これはサービスを開始します

  • stop:実行中の場合、これはサービスを停止します

  • ステータス:これはサービスのステータスを表示します

テストジョブを手動で開始するため、コマンドは次のようになります。

sudo service testjob start

次のコマンドを実行して、 `+ testjob.log +`ファイルを確認します。

cat /var/log/testjob.log

このコマンドは、ファイルをシェルに読み取ります。次のような1行が表示されます。

Test Job ran at Fri Aug 1 08:43:05 BST 2014

これは、テストジョブがセットアップされて準備が整ったことを示しています。

Dropletを再起動してからログインし、ログファイルを再度読み取ります。

cat /var/log/testjob.log

後のタイムスタンプを表示するログの2行目に、Upstartジョブとして実行されたことを確認する必要があります。

Test Job ran at Fri Aug 1 08:44:23 BST 2014

これは、Upstartでできることのほんの一部に過ぎません。 詳細な例については後で説明しますが、ここでは、ジョブの状態とイベントの説明に移ります。

ジョブの状態とイベント

システムジョブは `+ / etc / init / `ディレクトリにあり、ユーザージョブはユーザー自身のinitディレクトリ、 `〜/ .init / +`にあります。

ユーザージョブはユーザー自身のセッションで実行されるため、セッションジョブとも呼ばれます。 これらはシステム全体で実行されず、「+ PID 1+」の指定ではありません。 テストジョブの目的のために、システムの起動時にロードできるように、 `+ / etc / init +`を使用しました。

ジョブのタイプに関係なく、ジョブは*常に*構成ファイル(.conf)で定義され、ファイル名は関連するサービスまたはタスクを表す必要があります。

これらの各ジョブには、「+ start」または「+ stop」という目標があります。 これらの2つの目標の間には、目標に関するジョブの現在のアクションを定義する一連のタスク状態があります。 重要な状態は次のとおりです。

  • 待機中:処理の初期状態

  • 開始:ジョブが開始されるところ

  • 事前開始:事前開始セクションがロードされる場所

  • 生成:スクリプトセクションが実行されようとしている場所

  • 開始後:開始後の操作が行われる場所

  • 実行中:ジョブが完全に機能している場所

  • 事前停止:事前停止操作が行われる場所

  • 停止:ジョブが停止される場所

  • killed:ジョブが停止した場所

  • ポストストップ:ポストストップ操作が行われる場所-クリーンアップする

開始後状態の後、ジョブは実行中として定義されます。 ジョブの停止準備が整う前停止がトリガーされるまで実行され続け、ジョブは強制終了され、定義されている場合は停止後の*クリーンアップ*手順が実行されます。

次のコマンドでUpstartシステムログ( `+ / var / log / upstart / `ディレクトリにある)の優先度を ` debug +`に設定することにより、ジョブが状態間でどのように遷移するかを表示できます。

sudo initctl log-priority debug

*状態はイベントではなく、イベントは状態*ではないことに注意してください。 4つのイベント(開始、開始、停止、停止)はUpstartによって発行されますが、タスクの状態はジョブのライフタイムのステージ間の遷移を定義します。

これで、サービスジョブを記述して、最初の構成の要素を組み込んだより焦点の絞られた例に進む準備ができました。 これは、基本的なテスト構成の実行から本番用のスクリプトへの移行方法を示します。

詳細な例:サービスジョブ

導入部で簡単に説明したように、サービスジョブには、プロセスをバックグラウンドで実行できるようにするスクリプト構成ファイルが含まれます。 *基本的なNode.jsサーバー*をゼロからセットアップします。

Nodeに慣れていない場合は、本質的に「サーバーサイドおよびネットワーキングアプリケーション用のクロスプラットフォーム環境」(Wikipedia)です。

Node.jsは非常に軽量なパッケージですが、Ubuntu 14.04にはデフォルトではインストールされません。 まず、クラウドサーバーにインストールしてください。

sudo apt-get install nodejs

それでは、サービスの仕事を始めましょう。 `+ nodetest.conf `という名前の新しいジョブ設定ファイルを ` / etc / init +`に作成します。 目的を参照してファイルに名前を付けることが不可欠なので、このサービスジョブはNode.jsテスト用であることを認識できます。

sudo nano /etc/init/nodetest.conf

事前にUpstartの構成を理解することが重要であるため、Nodeアプリケーション自体については後の例で説明します。

まず最初に。 まず、ジョブの説明と作成者の行を入力して構成を定義します。

description "Service for a test node.js server"
author      "Your Name"

このNode-poweredサーバーアプリケーションは、サーバーが稼働しているときに起動し、正常にシャットダウンしたときに停止するようにします。 このため、必ず両方の条件を指定してください。

start on filesystem or runlevel [2345]
stop on shutdown

以前のランレベル基準を覚えていますか? `+ filesystem +`イベントと組み合わせると、サーバーが正常に稼働しているときにジョブが確実にロードされます。

これらは基本ですが、今ではさらに複雑になっています。前述の*スタンザ*を使用します。

これはサーバーアプリケーションであるため、ジョブ構成にロギング要素を組み込みます。 Nodeアプリケーションの起動時と停止時にログを記録するため、3つの異なるスタンザを使用してサービスアクションを分離します-+ script ++ pre-start script +、および + pre-stop script +

これらがよく知られていると思うなら、あなたは絶対に正しい。 事前開始と事前停止はジョブの状態ですが、スタンザでも機能します。 これが意味することは、ジョブの状態に基づいて異なるコマンドを実行できることです。

ただし、記述する最初のスタンザはジョブスクリプト自体です。 これにより、ノードバックグラウンドサーバーのプロセスIDが取得され、アプリケーションスクリプトが実行されます。 スタンザ内のコマンドのインデントに注意してください-これは構文的に正しい書式設定に不可欠です。

script

   export HOME="/srv"
   echo $$ > /var/run/nodetest.pid
   exec /usr/bin/nodejs /srv/nodetest.js

end script

Nodeにはホームディレクトリ変数を設定する必要があるため、なぜスタンザの最初の行で「+ / srv 」がエクスポートされるのか。 次に、 ` $$ +`を使用して、使用可能なプロセスIDを取得し、ジョブのPIDファイルを作成します。 それが準備できたら、Node.jsアプリケーションがロードされます。これは後で記述します。

ここで、シンプルなアプリケーションロギングに使用される「+ pre-start 」と「 pre-stop +」に注目します。 日付は、開始メッセージまたは停止メッセージとともに、ジョブのログファイルに追加されます。

pre-start script
   echo "[`date`] Node Test Starting" >> /var/log/nodetest.log
end script

事前停止スタンザには別の行が含まれていることに注意してください。サーバーをシャットダウンする手順の一部としてPIDファイルを削除します(事前停止の動作)。

pre-stop script
   rm /var/run/nodetest.pid
   echo "[`date`] Node Test Stopping" >> /var/log/nodetest.log
end script

これが、Upstartジョブの構成全体を並べ替えたものです。参照のために、ここでもすべてを説明します。

description "Test node.js server"
author      "Your Name"

start on filesystem or runlevel [2345]
stop on shutdown

script

   export HOME="/srv"
   echo $$ > /var/run/nodetest.pid
   exec /usr/bin/nodejs /srv/nodetest.js

end script

pre-start script
   echo "[`date`] Node Test Starting" >> /var/log/nodetest.log
end script

pre-stop script
   rm /var/run/nodetest.pid
   echo "[`date`] Node Test Stopping" >> /var/log/nodetest.log
end script

ファイルを保存して閉じます。

`+ exec `行で述べたように、Node.jsスクリプトはサーバーから実行されるため、希望の場所に ` nodetest.js `ファイルを作成します(この例では ` / srv / +`が使用されます)。

sudo nano /srv/nodetest.js

これはUpstartのチュートリアルであるため、Node.jsのコードのレビューにはあまり時間をかけませんが、このスクリプトが達成することの概要は次のとおりです。

  • NodeのHTTPモジュールを要求してロードする

  • HTTP Webサーバーを作成する

  • ヘッダーにステータス200(OK)応答を提供します

  • 出力として「Hello World」を記述します

  • ポート8888でリッスンする

Nodeアプリケーションを実行するために必要なコードは次のとおりです。直接コピーして時間を節約できます。

var http = require("http");

http.createServer(function(request, response) {
   response.writeHead(200, {"Content-Type": "text/plain"});
   response.write("Hello World");
   response.end();
}).listen(8888);

Node.jsファイルを保存した後、最後に確認することは、Upstartジョブの構文が有効かどうかです。 いつものように、構成チェックコマンドを実行すると、出力として確認を受け取るはずです。

init-checkconf /etc/init/nodetest.conf

File nodetest.conf: syntax ok

ジョブ設定を取得し、構文を確認し、Node.jsコードを保存します。準備が整ったら、Dropletを再起動して、http:// IP: 8888 または関連ドメインにアクセスしてください。

ウィンドウの左上隅に「Hello World」が表示されている場合、Upstartサービスジョブは機能しています。

状態ベースのロギングの確認については、事前定義されたログファイルを読むと、タイムスタンプ付きの `+ Starting `行が表示されます。 サーバーをシャットダウンするか、サービスジョブを手動で停止すると、ログに「 Stopping +」行が書き込まれます。この行は、必要に応じて確認することもできます。

cat /var/log/nodetest.log

[Sun Aug 17 08:08:34 EDT 2014] Node Test Starting
[Sun Aug 17 08:13:03 EDT 2014] Node Test Stopping

標準の起動、停止、再起動などを実行できます。 次のような構文を持つ、このサービスのコマンド、およびその他の同様のUpstartジョブ。

sudo service nodetest restart

結論

このチュートリアルでは、Upstart Event Systemの表面のみをスクラッチします。 従来の初期化の背景を読み、オープンソースのUpstartソリューションがより強力な選択肢である理由を見つけ、独自のジョブを書き始めました。 基本を理解したので、可能性は無限です。

Upstart公式ウェブサイトのロゴ、著作権オリジナルデザイナー/ Canonical Ltd.

前の投稿:復元力のあるGoアプリケーションをDigitalOcean Kubernetesに展開する方法
次の投稿:Ubuntu 14.04でRedisデータをバックアップおよび復元する方法