CppCloud分布式配置设计


1.概况

借鉴spring cloud config的设计({application}-{profile}.properties)

  • {application} 即是配置文件名中的前部分
  • {profile} 配置文件的后部分
  • {label} 所属git的分支

CppCloud采用json格式配置,有如下特点。 - 查询灵活
提供查询某一部分配置或者文件级查询 - 继承和合并
可以像面向对象继承特性那样,比如A继承B,那么B里面的配置在A都有,且在A里可以覆盖定义某个自己想变动的配置;对于多个项目共享一些公有配置很有用。 - 变化通知
当某个配置修改时,之前有订阅了该配置的应用都会得到通知,这个通知是服务端推送的,不用轮循请求。

2.元配置

即CppCloud分布式配置模块程序的配置,CppCloud启动时加载_meta.json(默认配置文件目录是./conf,可以重新指定),该文件指定好各配置文件的继承关系; 元配置_meta.json可选,当没有时那个所有配置无继承关系。

_meta.json:

{
    "conf_inherit": 
    {
        "app1-dev.json": "common.json app1.json", # 从左到右关系越来越优先,空格分开
        "app1-test.json": "app1.json"
    },
    "app_profile": # 客户应用主配置定义,机房定义,机架定义
    {
        "tag1": # tag匹配
        {
            "_rack": 40,
            "app1": "app1-dev.json"
        },
        "192.168.228.10": # ip匹配
        {
            "_idc": 1,
            "_rack": 2,
            "app1": "app1-dev.json",
            "app2": "app2-test.json",
            "Web-Ctrl": "web.json"
        },

        "default": 
        {
            "app1": "app1-default.json"
            "app2": "app2-default.json"
        }
    }
}

3.普通配置

要求必须符合标准JSON格式的文件,建议命名为{appname}-{profile}.json形式。

app1.json:

{
    "key1":"key1 in app1",
    "hojl":"hejinlong"
}


app1-dev.json:

{
    "key1":"key1 in app1-dev",
    "key2":"key2 in app1-dev",
    "key3": 
    {
        "subkey3": "value3"
    }
}


app2-dev.json:

{
    "key1":"key1 in app2-dev",
    "key3":"key3 in app2-dev",
    "key4": 1234
}

4.协议报文

4.1 启动获取主配置

应用一启动时首次自报身份CMD_WHOAMI_REQ(0x0001)请求,如果有则返回"mconf"属性, 即为本应用的主配置。

  • 主配置作用:
    在sdk里在查询操作时可以省略文件名,对只需简单配置的应用更加简化。
  • 设定主配置:
    在元配置里指定即_meta.json。 参考上面元配置节的示例,在app_profile项下,拿cli的tag和ip属性比较app_profile下的子键,进入匹配的Map里,取到cli的svrname属性对应的值就是主配置名;如果tag处获取不到,则查ip,最后到default,优先级由高到低;都没获取到就是空。

4.2 列出所有配置文件

  • 请求报文 (CMD_GETCFGNAME_REQ=0x0010)
    无需包体

  • 响应报文 (CMD_GETCFGNAME_RSP=0x1010) |键名|说明| |----|--| |filename|配置名,响应返回所有配置文件名| |flag|文件存在标记,0不存在或已被删除,1正常存在可用| |mtime|文件修改时间截,分布式配置文件同步时以此时间作衡量,新的可覆盖旧的,旧的不能覆盖新的。| json { "$filename": [$flag, $mtime ], "app1-dev": [1, 1539252977] }

4.3 获取具体配置

  • 请求报文 (命令CMD_GETCONFIG_REQ=0x000E)

    键名 必填 说明
    file_pattern 配置名,譬如app1-dev.json,或应用配置比较多时,可以使用目录前缀
    key_pattern 查询键串,当要返回配置中的某一部分时使用;如果不指定默认返回整个文件级内容,多级键之前用/分隔,譬如/key1/key12/key123。
    gt_mtime 当配置文件的最后更新时间大于此时间截时才回复文件内容,否则回复"ok"或"fail"。
    inbase 是否包含继承关系,包含的话则先按照_meta.json元配置定义来先生成一个完整json内容。

    json { "file_pattern": "app1-dev", "key_pattern": "/", "gt_mtime": 1539596952, "incbase": 0 }

  • 响应报文 (命令CMD_GETCONFIG_RSP=0x100E) |键名|说明| |---|----| |mtime|文件的最后更新时间| |contents|文件的内存内容| |注意:|当请求时gt_mtime已最新时整个包体返回"ok"|

    json { "mtime":1539596952, "contents": { "key1": "value1", "key2": 2222 } } + 示例

    譬如,拿上面的普通配置示例说明,为方便说明,注意以下响应只写"contents"的值的内容。 ````json A请求 { "file_pattern": "app1-dev", "incbase": 0 } A响应 --> { "key3":{"subkey3":"value3"}, "key2":"key2 in app1-dev", "key1":"key1 in app1-dev" }

    B请求(继承) { "file_pattern": "app1-dev", "incbase": 1 } B响应 --> { "key2":"key2 in app1-dev", "hojl":"hejinlong", "key3":{"subkey3":"value3"}, "key1":"key1 in app1-dev" }

    C请求(含查询键) { "file_pattern": "app1-dev", "incbase": 0, "key_pattern": "/key3" } C响应 --> { "subkey3":"value3" }

    D请求(含查询键,多级) { "file_pattern": "app1-dev", "incbase": 0, "key_pattern": "/key3/subkey3" } D响应 --> "value3"

    E请求(不存在的键) { "file_pattern": "app1-dev", "incbase": 0, "key_pattern": "/key9" } E响应 --> null

    ````

4.4 修改配置

修改时应当以原始文件且非继承为单位进行,不能只修改文件的某一部分。

  • 请求报文 (命令CMD_SETCONFIG_REQ=0x000F) |键名|必填|说明| |----|--|----| |filename|是|配置名,响应返回所有配置文件名| |mtime|否|文件修改时间截,分布式配置文件同步时以此时间作衡量,新的可覆盖旧的,旧的不能覆盖新的。 不填写时会以收到时的时间填充。| |contents|是|具体json配置文件的内容,中心端收到请求时将contents值中的内容存放。 json { "filename": "app1-dev.json", "mtime": 1539333414, "contents":{ ... } }
  • 响应报文 (命令CMD_SETCONFIG_RSP=0x100F) json { "code": 0, "desc": "success" }

4.5 订阅配置变化

当客户应用需要知道何时某个配置发生变化时,客户应用可以发出CMD_BOOKCFGCHANGE_REQ请求,把文件名作为参数附带传给后台,那么当已订阅的配置变化时,客户应用会收到变化通在推送(4.6节)。

  • 请求报文 (命令CMD_BOOKCFGCHANGE_REQ=0x0014) |键名|必填|说明| |----|--|----| |file_pattern|是|配置文件名| |incbase|否|是否匹配配置继承,默认0| json { "file_pattern": "app1-dev.json" }
  • 响应报文 (CMD_BOOKCFGCHANGE_RSP=0x100F) json { "code": 0, "desc": "success" }

4.6 配置变化通知

当配置发生修改时,配置文件的mtime会改变。后台会推送通知给已订阅(4.5)了该配置的客户应用。 + 请求报文 (命令CMD_EVNOTIFY_REQ = 0x0015) |键名|必填|说明| |----|--|----| |notify|是|通知类型,此处是"cfg_change"| |filename|否|发生变化的文件名| |mtime|否|文件的更新时间截|

```json { "notify": "cfg_change", "filename": "app-dev.json", "mtime": 15012341234 }

  • 响应报文

    (可选,一般无需回复)