实现一个简易的Consul SDK

Consul Consul是一个用于实现分布式系统的服务发现与配置的开源软件,它有如下功能: 服务的注册和发现

Consul

Consul是一个用于实现分布式系统的服务发现与配置的开源软件,它有如下功能:

  • 服务的注册和发现
  • 键值对存储
  • 健康检查
  • 多数据中心支持

node-consul

目前实现最为完备的 Consul 客户端是 node-consul,看看它的功能点:

  • ACL 访问控制
  • Agent 检查/服务注册
  • Health 健康信息获取
  • Catalog 目录列表
  • KV 键值对存取
  • Event 发送事件与列表
  • Query 查询服务信息
  • Status Raft一致性的状态信息

Too much,超出了需求范围,我们需要的是一个类似于探针的包,下载后简单配置一下就开始工作,随着宿主服务启动/关闭而自动注册/注销。然而,这样的包目前似乎没有,只有自己写了,于是有了:

node-consul-sdk

使用

node-consul-sdk的使用很简单,只需在你的服务目录中进行三步操作:

1. 安装

  • npm方式:
npm i consul-sdk --save
  • yarn方式:
yarnaddconsul-sdk

2. 配置

在服务根目录下放一个配置文件 consul.json,格式如下:

{  "serverHost": "127.0.0.1",  "serverPort": 8500,  "secure": false,  "name": "node-consul-sdk",  "host": "192.168.1.1",  "port": 6666}
字段 意义
serverHost consul服务地址(选填,默认值为localhost)
serverPort consul服务端口(选填,默认值为8500)
secure 是否使用安全连接(选填,默认值为false)
name 服务名称
host 服务所在的IP地址
port 服务使用的端口

3. 调用

在服务入口文件中(比如app.js) 引入模块:

<spanclass="pl-c1">require</span>(<span class="pl-s"><span class="pl-pds">'</span>consul-sdk<spanclass="pl-pds">'</span></span>)

实现

考虑到宿主环境的复杂性,实现方式颇为远古,全 es5 制霸:

index.js (程序入口):

(function () {   var path = require('path');  var fs = require('fs');  var lib = require('./libs/lib')  var error = lib.error;  var debug = lib.debug;  var rootDir = path.resolve('./');  var confDir = path.resolve(rootDir, 'consul.json');   debug('location of consul.json:', confDir);  if (!fs.existsSync(confDir)) {    return error('consul.json does not exists in:', confDir);  }   var conf = require(confDir);  debug('content of consul.json:', conf);   var consul = require('consul')({    host: conf.serverHost || 'localhost',    port: conf.serverPort || 8500,    secure: conf.secure || false,    promisify: lib.fromCallback  });   consul.agent.service.register({    name: conf.name,    address: conf.host,    port: conf.port  }).catch(function (err) {    error(err);  });   lib.registerExitHandler(function () {    consul.agent.service.deregister({      id: conf.name    }).catch(function (err) {      error(err);    });  }); })();

libs/lib.js :

var Bluebird  = require('bluebird');var error    = console.error;var debug    = require('debug')('consul-sdk'); function registerExitHandler (callback) {  function exit(signal) {    callback = callback || function() {};    callback();    setTimeout(function() {      process.exit(signal);    }, 500);  }   process.on('exit', function () {    debug('process.on(exit) !!!!!!!!')  });   process.on('SIGTERM', function() {    debug('SIGTERM')    exit(-1);  });   process.on('SIGINT', function () {    debug('Ctrl-C...');    exit(2);  });   process.on('uncaughtException', function(e) {    debug('Uncaught Exception...');    error(e.stack);    exit(99);  });}; function fromCallback(fn) {  return new Bluebird(function (resolve, reject) {    try {      return fn(function (err, data, res) {        if (err) {          err.res = res;          return reject(err);        }        return resolve([data, res]);      });    } catch (err) {      return reject(err);    }  });}; module.exports.registerExitHandler = registerExitHandler;module.exports.fromCallback = fromCallback;module.exports.error = error;module.exports.debug = debug;
未登录用户
全部评论0
到底啦