请选择 进入手机版 | 继续访问电脑版

湖南新梦想

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 637|回复: 0

基于 git 和 CI/CD 的集中化配置管理服务(中)

[复制链接]

2562

主题

2961

帖子

1万

积分

论坛元老

Rank: 8Rank: 8

积分
10523
发表于 2020-12-23 10:49:19 | 显示全部楼层 |阅读模式
本帖最后由 chaomeili 于 2020-12-23 10:50 编辑

    当然你也可以在上面加一些性能上的优化哈,特别是加载 yaml 文件的部分。除了读取 yaml 配置文件的内容外,里面还通过 object-hash 来计算了配置的 revision,方便客户端来检查配置数据的版本更新。
  提供统一的客户端 library
  主体设计和实现就是上面说的这些内容了。不过,还有一项工作很重要,就是提供统一的客户端 library。当大家使用同样的客户端 library 来读取配置的时候,配置管理的坑儿才能算真正占好,后面才方便替换配置管理服务的技术方案。
  library 设计
  首先说一下这个 library 的接口设计吧

  config.get(path)

       提供一个 get 方法,注意:
  参数里面应该是一个 path,准确的说应该是一个 property path
  这个方法应该是 同步执行 的,所以下面我提供了一个 sync 方法,专门用来同步配置数据
  假设完整的配置数据是这样的:

  {
  "mysql": {
  "host": "111.111.11.11",
  "port": 3306,
  "username": "root",
  "password": "123456"
  },
  "redis": {
  "host": "111.111.11.12",
  "port": 6379
  },
  "wechat": {
  "appId": "wx888888888"
  },
  "secret": "foobar"
  }

  那么通过 get 方法应该能够做到下面这些事情:
  config.get("mysql")
  // => {"host": "111.111.11.11", "port": 3306, ...}
  config.get("wechat.appId")
  // => "wx888888888"
  config.get()
  // => {"mysql": {...}, "wechat": {...}, ...}

  也就是说,大家可以通过 get 方法灵活的获取到配置数据的某一部分。这块我们使用了 object-path 这个模块。

  config.sync(host, profile, token)

      提供一个 sync 方法,用来初始话和轮训同步配置数据

  config.on(event, listener)

应该提供事件回调接口,用来检测是否有数据发生变化,这个接口在 Node.js 服务中有一定用处,其他的同步的技术框架应该就不需要了。
  config.mock(object)

       最后,应该有一个 mock 方法,方便支持自动化测试
  一些补充内容
  补充一下主要的实现代码,供大家参考:

  const EventEmitter = require('events').EventEmitter;
  const objectPath = require('object-path');
  class Config {
  constructor(interval) {
  this.interval = interval || 5000;
  this.emitter = new EventEmitter();
  }
  sync(host, profile, token) {
  this.host = host;
  this.profile = profile;
  this.token = token;
  this.data = loadConfigSync(); // 首先同步获取配置数据
  setTimeOut(() => this.watch(), this.interval); // 之后,定时轮训数据
  }
  get(path) {
  return objectPath.get(this.data.config, path);
  }
  loadConfigSync() {
  // 这部分代码就先省略了~
  }
  async loadConfigAsync() {
  // 这部分代码就先省略了~
  }
  async watch() {
  const result = await this.loadConfigAsync();
  if (result.revision !== this.data.revision) {
  this.data = result;
  this.emitter.emit('update', this.data.config);
  }
  setTimeout(() => this.watch(), this.interval);
  }
  }
  module.exports = new Config();
  使用客户端 library 的一般套路:
  // server.js
  const config = require('config-module-name');
  // 1. 调用 sync 方法加载配置
  config.sync(process.env.CONFIG_HOST, process.env.CONFIG_PROFILE, process.env.CONFIG_TOKEN);
  // 2. 启动实际项目的 WebServer
  const server = new WebServer();
  server.serve();


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|湖南新梦想 ( 湘ICP备18019834号-2 )

GMT+8, 2022-5-27 08:04 , Processed in 0.046356 second(s), 20 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表