NodeJsサービス登録とサービス発見実現
9264 ワード
前言
作者がNodeJsを勉強し始めたばかりなので、レベルは本当に限られています.本論文はノートを勉強しているようで、NodeJsを勉強し始めたばかりの友達と読むのに適しています.
サービス治理
もしあなたのチームがマイクロサービスの構築を模索しているなら、このメカニズムは各サービスに動的に住所を作成することができます.同時にこれらのサービスアドレスのダイナミックな変化を感知することができます.サービス登録とサービス発見はこの中の一つの仕組みです.大体の流れは:
その中:登録センター:zookeeper サービス提供者:NodeJsアプリケーションサービス サービス消費者:NodeJs API Gateway Zoo Keeperサービス登録センター
Zoo Keeperのアイデンティティは管理者であり、分散型のデータ整合性の解決策であり、分散型のタスクはデータの公開と購読、負荷の均衡、ネーミングサービス、分散式の協調と通知、クラスタ管理、指導選挙、分散式のロック、分散型の行列などを実現することができる.この文章はすべての面について解説しません.作者もまだ触れていませんから.私達の目標はZoo Keeperを利用してサービスの登録センターを実現することです.興味があれば、自分で研究してみてもいいです.後で研究したらまたシェアします.
1、ツリーモデルを利用してサービスアドレスを構築し、データ構造を記憶する
zk内部には木のようなメモリモデルがあります.ファイルシステムと似ています.いくつかのディレクトリがあります.各ディレクトリにはいくつかのフォルダ、ファイルがあります.
zkには4つのノードがあります.持久ノード:セッションが終了すると、ノードは削除されない 持続的な順序ノード:セッションが終了すると、ノードは削除されず、ノード名は増加数の拡張子 を持参する.一時ノード:セッションが終了すると、ノードは を削除される.一時的な順序ノード:セッションが終了すると、ノードは削除され、ノード名は増加数の拡張子 を持参する.
長いノードだけがサブノードを持つことができる.
現在はクラスタ配置アプリケーションが一般的であるので、クラスタ配置におけるサービスアドレスの状況を見てみよう.例えば、アプリケーションAを持っている場合、アプリケーションAは2台のマシンに配備されています.マシンIPはそれぞれ127.1.0.1と127..0.2、アプリケーションサービスポート6666、アプリケーションAはこの2つのサービスアドレスがあります.
全てのサービスアドレスのルートノードとしてノードを指定しますので、このノードは永続的ノードであるべきです.n個のアプリケーションを持っています.各アプリケーションにはn台のマシンがありますので、アプリケーションノードもサブノードを持っています.各マシンはアプリケーションサービスを起動する時にzkにアドレスを登録し、サービスのオフライン時にzkのアドレスを削除しますので、臨時ノードの特徴を使ってこの挙動にぴったりです.同時に順番ノードを使って自動的にノード名を管理してくれます.
私達はすべてnode操作を使うので、zkのnodeクライアントnode-zookeeper-clientを使います.
2、アプリ起動前にzkを接続する
もともと私はeggajsプラグインで書いたのですが、ここでフレームのものを取り除いて、他のものを取り出して、フレームにフックしません.
実はサービス登録が完了しました.
NodeJs API Gatewayゲートウェイサービス
上はすでにサービスが開始された時にzkに登録されました.今はインターフェースを起動してサービスにアクセスする時、サービスの住所を知る必要があります.これはサービス発見過程です.
API Gatewayは文字通りAPIの入り口であり、ルーティング要求に用いられる.実は、ルーティング要求だけでなく、API Gatewayはプロトコルを変換して、データ、認証、制限速度などのロジックを統合することができます.
例えば、フロントエンドにユーザ取得の要求があり、こう書くべきである.
締め括りをつける
以上は簡単に実現されました.使えますが、API Gatewayではすでにもらったサービスアドレスをキャッシュしてzk変化を購読します.例えばサービスを選ぶ時に負荷のバランスを取ることができます.
作者がNodeJsを勉強し始めたばかりなので、レベルは本当に限られています.本論文はノートを勉強しているようで、NodeJsを勉強し始めたばかりの友達と読むのに適しています.
サービス治理
もしあなたのチームがマイクロサービスの構築を模索しているなら、このメカニズムは各サービスに動的に住所を作成することができます.同時にこれらのサービスアドレスのダイナミックな変化を感知することができます.サービス登録とサービス発見はこの中の一つの仕組みです.大体の流れは:
その中:
Zoo Keeperのアイデンティティは管理者であり、分散型のデータ整合性の解決策であり、分散型のタスクはデータの公開と購読、負荷の均衡、ネーミングサービス、分散式の協調と通知、クラスタ管理、指導選挙、分散式のロック、分散型の行列などを実現することができる.この文章はすべての面について解説しません.作者もまだ触れていませんから.私達の目標はZoo Keeperを利用してサービスの登録センターを実現することです.興味があれば、自分で研究してみてもいいです.後で研究したらまたシェアします.
1、ツリーモデルを利用してサービスアドレスを構築し、データ構造を記憶する
zk内部には木のようなメモリモデルがあります.ファイルシステムと似ています.いくつかのディレクトリがあります.各ディレクトリにはいくつかのフォルダ、ファイルがあります.
zkには4つのノードがあります.
長いノードだけがサブノードを持つことができる.
現在はクラスタ配置アプリケーションが一般的であるので、クラスタ配置におけるサービスアドレスの状況を見てみよう.例えば、アプリケーションAを持っている場合、アプリケーションAは2台のマシンに配備されています.マシンIPはそれぞれ127.1.0.1と127..0.2、アプリケーションサービスポート6666、アプリケーションAはこの2つのサービスアドレスがあります.
全てのサービスアドレスのルートノードとしてノードを指定しますので、このノードは永続的ノードであるべきです.n個のアプリケーションを持っています.各アプリケーションにはn台のマシンがありますので、アプリケーションノードもサブノードを持っています.各マシンはアプリケーションサービスを起動する時にzkにアドレスを登録し、サービスのオフライン時にzkのアドレスを削除しますので、臨時ノードの特徴を使ってこの挙動にぴったりです.同時に順番ノードを使って自動的にノード名を管理してくれます.
私達はすべてnode操作を使うので、zkのnodeクライアントnode-zookeeper-clientを使います.
2、アプリ起動前にzkを接続する
もともと私はeggajsプラグインで書いたのですが、ここでフレームのものを取り除いて、他のものを取り出して、フレームにフックしません.
const { createClient, ACL, CreateMode } = require('node-zookeeper-client');
const zkClient = createClient('127.0.0.1:2181');
const promisify = require('util').promisify;
zkClient.connect();
zkClient.once('connected', () => {
registerService();
});
// zkClient promise
const proto = Object.getPrototypeOf(zkClient);
Object.keys(proto).forEach(fnName => {
const fn = proto[fnName];
if (proto.hasOwnProperty(fnName) && typeof fn === 'function') {
zkClient[`${fnName}Async`] = promisify(fn).bind(zkClient);
}
});
// host port
// serviceName
const { serviceName, host, port } = config;
async function registerService() {
try {
// ,
const rootNode = await zkClient.existsAsync('/services');
if (rootNode == null) {
await zkClient.createAsync('/services', null, ACL.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
}
// ,
const servicePath = `/services/${serviceName}`;
const serviceNode = await zkClient.existsAsync(servicePath);
if (serviceNode == null) {
await zkClient.createAsync(servicePath, null, ACL.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
}
// , , name ,
const addressPath = `${servicePath}/address-`;
const serviceAddress = `${host}:${port}`;
const addressNode = await zkClient.createAsync(addressPath, Buffer.from(serviceAddress), ACL.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
} catch (error) {
throw new Error(error);
}
}
上のコードは実は簡単です.zkに接続してから、ルートノードが作成されているかどうかを判定します.もしないなら、アプリケーションノードが作成されているかどうかを判断して、ないならば作成します.最後にマシンノードを作成します.ここでは、一時的な順序ノードを使って、私達が唯一のnameを維持する面倒を省きます.hostとportは格納内容として、これはappの配置が必要な場合に配置システムが提供され(自動配備システムを使用すれば)、アドレスがBufferに変更されて保存される.実はサービス登録が完了しました.
NodeJs API Gatewayゲートウェイサービス
上はすでにサービスが開始された時にzkに登録されました.今はインターフェースを起動してサービスにアクセスする時、サービスの住所を知る必要があります.これはサービス発見過程です.
API Gatewayは文字通りAPIの入り口であり、ルーティング要求に用いられる.実は、ルーティング要求だけでなく、API Gatewayはプロトコルを変換して、データ、認証、制限速度などのロジックを統合することができます.
例えば、フロントエンドにユーザ取得の要求があり、こう書くべきである.
fetch('/api/user/get', {
method: 'POST',
body: { id: 1 },
headers: {
// header service
'servive-name': 'user'
}
})
API Gatewayの本質もサービスです.Eggajsを使って作成したサービスは中間部品にパッケージされていることを発見しました.だからここでは中間部品の内容だけを展示して、他の自分はeggの文書を見ます.const proxy = require('koa-proxies');
module.exports = (options, app) => {
return async (ctx, next) => {
const serviceName = ctx.request.headers['servive-name'];
if (!serviceName) {
ctx.throw(404, 'no service found.');
}
const servicePath = `/services/${serviceName}`;
const addressNodes = await app.zookeeper.getChildrenAsync(servicePath);
const size = addressNodes.length;
if (size === 0) {
ctx.throw(404, 'no service found.');
}
let addressPath = `${servicePath}/`;
if (size === 1) {
addressPath += addressNodes[0];
} else {
//
addressPath += addressNodes[parseInt(Math.random() * size)];
}
const serviceAddress = await app.zookeeper.getDataAsync(addressPath);
if (!serviceAddress) {
ctx.throw(404, 'no service found.');
}
await proxy('/', {
target: `http://${serviceAddress}/`,
})(ctx, next);
};
};
上のミドルウェアでは、headersのservice-nameに基づいてアプリケーションのサービスアドレスをすべて取得し、あるポリシーに従ってサービスを選択し、プロキシを使って対応するサービスに転送します.締め括りをつける
以上は簡単に実現されました.使えますが、API Gatewayではすでにもらったサービスアドレスをキャッシュしてzk変化を購読します.例えばサービスを選ぶ時に負荷のバランスを取ることができます.