剑客
关注科技互联网

实现一个简易的Consul SDK

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;
分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址