背景#
現在、グループ内の監視データは、システムログデータとビジネスポイントデータの 2 つのプラットフォームに分散しています。システムがオンラインになったり、ビジネスのピーク時には、開発者はオンラインデータを継続的に監視してリスクを予測する必要があります。2 つのプラットフォームを行き来することが頻繁に行われ、ユーザーエクスペリエンスが低下しています。
考え方#
- 2 つのプラットフォームを行き来して確認するのは面倒です。異なるプラットフォームのデータソースを統合することを検討できます。
- アクティブな確認を受動的な感知に変え、ユーザーエクスペリエンスをさらに向上させます。
問題の分解と解決策#
- 最初のポイントに対して、異なるプラットフォームはそれぞれ対応する指標クエリ API を提供しています。この部分では、データソースの定義、設定、および統合を考慮します。
- 指標クエリ API を基に、自社の監視プラットフォームサイトにビジネスインテリジェンス設定モジュールを追加しました。ユーザーはプロジェクトの次元で異なるプラットフォームの監視指標を設定できます。
- 2 番目のポイントに対して、データソースの設定と統合が完了した後、データのプッシュを実装する必要があります。内部の IM ツールは、API を提供して呼び出すことができます。
通常のデータプッシュに加えて、ユーザーがカスタムサイクルで購読プッシュをサポートする必要があります。node-cronを使用して対応する定期タスクを生成します。1 つの購読設定に対して 1 つのタスクがあり、ユーザーが購読設定を更新すると、対応するタスクも更新する必要があります。
現在の解決策は非常に直感的で明確ですが、問題は、自社の監視プラットフォームサービスがPM2
を使用しており、4 つのプロセスを同時に起動していること、およびオンラインクラスターが少なくとも 3 つのマシンを持っていること、同時に実行されているnode-cron
タスクが少なくとも 12 個あることです。したがって、複数のプロセス間の周期タスクの管理の問題が発生します。
全体の負荷分散を考慮して、複数のプロセスが複数のタスクを登録できるようにする必要がありますが、実行されるタスクは 1 つだけであること、およびユーザーが設定を変更した場合、リクエストがどのプロセスに送信されても最新のタスクが登録されることを保証する必要があります。
複数プロセス管理の解決策#
バックエンドの観点からは、分散ロックを実装する必要があることが明らかです。最も一般的な方法は、Redis
のsetnx
コマンドを使用することですが、内部の監視プラットフォームサイトでは現在MongoDB
を使用しているだけで、新しい依存関係を導入しないようにする原則に従って慎重に考えた結果、MongoDB
の組み込みのアトミック操作でも実現できることがわかりました。詳細な手順は以下の通りです。
核心ロジックは、2 つのフラグを設計しました:
- 有効フラグ:複数のプロセスの同期問題を解決します。
- 実行フラグ:複数のプロセスの同時実行問題を解決します。
フラグのルールは、IPv4 アドレス + Node プロセス番号です。プロセス番号はprocess.env.NODE_APP_INSTANCE
を使用して直接取得できますが、IP アドレスは組み込みのnode:os
モジュールを使用する必要があります。
import { networkInterfaces } from 'os';
/**
* IPv4アドレスを返す
*/
export const getIPAddress = () => {
const interfaces = networkInterfaces();
let address = '';
for (const devName in interfaces) {
if (Object.prototype.hasOwnProperty.call(interfaces, devName)) {
const iface = interfaces[devName] || [];
iface.forEach((alias) => {
if (
alias.family === 'IPv4' &&
alias.address !== '127.0.0.1' &&
!alias.internal
) {
address = alias.address;
}
});
}
}
return address;
};
最終的に、フラグの設定によって複数のプロセス管理の問題がうまく解決されました。