实现一个简易的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

}

字段意义
serverHostconsul服务地址(选填,默认值为localhost)
serverPortconsul服务端口(选填,默认值为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
到底啦