Coder Social home page Coder Social logo

Comments (19)

tianxiaoliang avatar tianxiaoliang commented on July 18, 2024

from go-archaius.

xy-github-issue avatar xy-github-issue commented on July 18, 2024

是的这个问题其实几年前我就提出过,只是一直没能落地优化

为什么没有落地啊?有什么困难?

from go-archaius.

tianxiaoliang avatar tianxiaoliang commented on July 18, 2024

涉及接口变更,生态已经长成,这会导致太多开发者需要重新适配

from go-archaius.

xy-github-issue avatar xy-github-issue commented on July 18, 2024

涉及接口变更,生态已经长成,这会导致太多开发者需要重新适配

我倒是觉得这是个修 bug 的更改啦。目前这个设计,业务是很难正确响应配置变更的。且不说前面提到的把配置值复合成单一项对业务带来的不便,go-chassis 自己里面的配置组织,就不是同模块做成一个yaml配置的了,这些配置上的热更新已然很难做好了,比如 go-chassis 里的 CircuitBreakerEventListener,是一次更新多项,就会响应多次、Flush多次的吧,也许还不到bug的程度,但总不是很好的行为。(稍微跑题一个,router 的具体逻辑我还没太搞懂,看到里有个 NewServiceRule函数有个yaml.Unmarshal 的调用,这不是穿透了 archaius 的设计了吗?可以假设所有配置源都能给出 yaml 格式的配置值吗?)

目前这个库star 75,也还没有到不能改的程度吧?相关两头:配置源和业务。配置源主要就是 archaius 内置的这些加一个 apollo 吧?业务方面我不知道你们还有哪些业务要考虑,我的角度最主要的业务方就是 go-chassis 自己。若是真是担心关联的业务方太多,加一个 RegisterModulerListener 之类的API,在不打破原有 RegisterListener (标记为 deprecated, 择机再删掉)的支持基础上,增加模块变更整体通知的支持,如何呢?

from go-archaius.

tianxiaoliang avatar tianxiaoliang commented on July 18, 2024

嗯 关于go chassis配置文件设计,确实有问题。要解决这个问题我们有两个做法,

方案一:从配置中心去做。

我们的新配置中心kie,做出了如下改变

除了key,value之外扩展出了value type,内容是yaml,json,ini,java properties这种。基于这个机制我们会更改自己的设计,用户在设置key value时就可以整段的录入,比如你说的CircuitBreaker配置,value内容是整段内容,触发更新后 listener就可以根据value type进行处理了,这个时候key字段只需要定死,比如只要是以“servicecomb.circuit.”开头都是熔断类配置, 就可以注册监听器了

方案二:如2位所述

from go-archaius.

xy-github-issue avatar xy-github-issue commented on July 18, 2024

我们的新配置中心kie,做出了如下改变

kie 不是也从 archaius 接入?还是说准备完全弃用 archaius ? 如果kie 只是archaius 的一个配置源,那这个问题就还在,archaius 既然想要支持多配置源,就不能只有 kie 一个配置源没问题吧

而且kie 听起来,一个key 对应的value 是一段 json/yaml/ini ,一定是一整段的意思?那么原先 archaius 的 Get / GetBool/ GetInt 等等接口又准备何去何从?准备如何支持用户读取一整配置里的一项呢?

from go-archaius.

tianxiaoliang avatar tianxiaoliang commented on July 18, 2024

kie 不是也从 archaius 接入?还是说准备完全弃用 archaius ? 如果kie 只是archaius 的一个配置源,那这个问题就还在,archaius 既然想要支持多配置源,就不能只有 kie 一个配置源没问题吧

-- 没错,多source的话,关于apollo的适配可以考虑定义key的规范为xxx.json,xxx.yaml也就是像系统文件扩展名那样定义key来使archaius适配。

而且kie 听起来,一个key 对应的value 是一段 json/yaml/ini ,一定是一整段的意思?

-- 对于不同类型archaius有两种处理方式(通过options中的配置项决定),一种方式是不管value type是什么都当正常raw数据处理,直接返回给业务调用者,一种方式是根据value type进行key value的切分(或者说拍平yaml,json)

那么原先 archaius 的 Get / GetBool/ GetInt 等等接口又准备何去何从?准备如何支持用户读取一整配置里的一项呢?

-- 无论value type是什么,都可以用Get搞定

from go-archaius.

xy-github-issue avatar xy-github-issue commented on July 18, 2024

没错,多source的话,关于apollo的适配可以考虑定义key的规范为xxx.json,xxx.yaml也就是像系统文件扩展名那样定义key来使archaius适配。

似乎扯远了一点,我们讨论的问题,不是具体的单一个配置源的问题。它不是apollo 的问题(File 配置源/Memory配置源不是都一样),也不是 kie 能解决的问题。archaius 设计要支持多配置源,为业务屏蔽了配置源的细节,配置源应该是对等的。虽然看上去你们从 kie 得到了一些启发,但是希望别把它做成特例。

回到现在的问题:
我理解的 archaius 主要接口目前

  1. Get/GetXxx : 用于读取单个配置项的值,GetXxx 接口提供了轻量的使用方式(无须反射反序列化等)给用户,还是有价值的。这些接口目前只能读完整 key对应的配置,Get/GetValue 可以扩展到支持读一个前缀,来支持读一个模块的所有配置(当然我觉得这样没有意义,要配合反序列化对业务才有用,不如直接给个 Unmarshal(key, &conf) 接口)。
  2. RegisterListener 支持订阅配置变更,变更通知行为是,n个 key 匹配到订阅的 pattern 时,会分 n 次通知。

在这个现状基础上,可以清楚地看到 RegisterListener 的通知行为是不符合实际业务场景的,我对你们的思路理解是:
设计一个返回 Raw 配置的能力,跟解决上述问题没有一点关系。把问题解决了的是,为业务设定了一个非明文的限制:有更新关联的配置项,只能做成一项,值做成复合结构。一方面,未满足这个非明文限制的业务,比如 go-chassis 里的那些,还是要改的,要改配置设计。其它业务方仿照这个方式设计理念都要硬改过来,这不是也一样破坏兼容破坏生态?另一方面必然导致 GetXxx 这些接口能力受限,复合的配置值,业务关心的最终还是内部的每一项,GetXxx 接口没有能力拿到的。所以做完这些之后,似乎 archaius 没有变得更好。

然后关于返回 Raw 的能力,正如前述,业务拿到Raw 的配置意义并不大,最终还是解析得到具体的配置项。所以对于你提到的

一种方式是不管value type是什么都当正常raw数据处理,直接返回给业务调用者

我其实不是很理解,新增这个选项这个能力的意义。似乎就是因为,限制业务配置值必须是复合结构,处理复合结构需要 raw 数据?

from go-archaius.

tianxiaoliang avatar tianxiaoliang commented on July 18, 2024

回到这个场景:

项目中配置的使用,一般都是多个配置项合在一起使用,比如mysql的配置一般都会有账号、密码、端口地址等。如果在项目运行过程中,需要修改该项配置,同时修改了账号、密码和端口。event就会通知同一个模块多次,业务方没有考虑这种情况的时候,就会热更新多次,存在问题,即使订阅多个key,感觉也不能避免回调方回调多次的情况。

既然archaius事件是多个,这说明你一次在配置中心改了好几个key value对,这操作真的很繁琐,没从运维人员的真实需求出发去设计,我作为运维人员改好db的配置了,然后去业务配置管理改配置,要操作好几个kv记录,这就像go chasssis的circuit breaker配置一样反人类。我的答案是:运维人员其实希望操作一条配置记录就可以管理业务方的db配置,所以把配置作为整体的段落保存在远程配置中心,archaius拉过来把这个段落当做value用。从使用者的真实需求出发,从设计一开始就考虑他们是怎么操作的

“要改配置设计。其它业务方仿照这个方式设计理念都要硬改过来,这不是也一样破坏兼容破坏生态?“

--- 回答你的关于我这边也重新设计的问题,没错,我必须重新设计将反人类的部分重做

from go-archaius.

xy-github-issue avatar xy-github-issue commented on July 18, 2024

既然archaius事件是多个,这说明你一次在配置中心改了好几个key value对,这操作真的很繁琐,没从运维人员的真实需求出发去设计,我作为运维人员改好db的配置了,然后去业务配置管理改配置,要操作好几个kv记录,这就像go chasssis的circuit breaker配置一样反人类。我的答案是:运维人员其实希望操作一条配置记录就可以管理业务方的db配置,所以把配置作为整体的段落保存在远程配置中心,archaius拉过来把这个段落当做value用。从使用者的真实需求出发,从设计一开始就考虑他们是怎么操作的

archaius的设计不应该为特定的某一种配置中心的操作而定制,工具应该是解放业务的,而不是反过来让业务束手束脚。

针对你提到的这个运维操作很麻烦的事情,虽然我觉得同时改两个配置居然很麻烦一定是配置中心没做好,与archaius 不太相关。但既然觉得业务要因为archaius去为运维考虑这个,我们不妨来分析分析:

实际的业务场景下,一个mysql 的配置何止用户名密码,还有连接读写各种超时及连接池几个大小的各种配置,如果你真的了解这个场景的话。除去 mysql 之外,各种业务模块也会有各自的多项配置的场景。

业务的配置项的个数,是由业务的特性而定的。你把它做成一个key,运维人员操作时,需要修改的,依然是具体的业务配置项。我假设你把它串成一段json 吧,像这样:

  • mysql : {"user": "root", "pwd": "123", ...}

那运维的修改是

  • mysql : {“user”: "rootnew", "pwd": "456"}

一样是两处编辑,何来的简化?
运维的大脑里处理的,不会是一个复合的结构,而依然是具体的用户密码超时连接数(用户名密码也不需要可读不需要理解,但超时连接数就很需要了。反倒是做成一个复合结构的值展示在他眼前的时候,如果配置中心没有做好的话,他要自行解析修改再打包成所要的格式,这是不是更反人类?)。
退一万步,那怕业务配置项拆成了100个,配置中心一样可以提供输入复合配置的功能给运维用(现实中也已经有这种产品这种功能存在),编辑好后一次页面操作一次发布,何来不便?


下面还有另两个问题,相关性不那么大,同样是配置中心做得够好的话可以解决的。
打成了复合结构了之后,复合结构内的

其一、配置中心在发布配置前需要要差异对比展示,发布配置后需要有历史变更的展示。
一个这样的差异展示:

  • 旧 mysql: {"user": "root", "pwd": "123", ...}, 新 mysql:{“user”: "rootnew", "pwd": "456"}

和一个这样的差异

  • 旧 mysql.user: root 新 mysql.user: rootnew
  • 旧 mysql.pwd: 123 新 mysql.pwd: 456

是否高下立判?更别提如果有连接数之类的需要可读需要理解的配置。

其二、分折配置项的形式,配置建立好后,配置key 已定,修改只涉及值。合并配置项成复杂结构的形,复杂结构内的 key 就凭白多了被改到的风险了。这是不是也是反人类呢?

这里的种种,源头都在于复合的结构是存储是传输用的,运维的人脑处理的,依然是单项的值。

from go-archaius.

tianxiaoliang avatar tianxiaoliang commented on July 18, 2024

旧 mysql: {"user": "root", "pwd": "123", ...}, 新 mysql:{“user”: "rootnew", "pwd": "456"}

这个json按照pretty格式输出后,不就好对比了么

一样是两处编辑,何来的简化?

三种接口 cli,rest api,ui,改几个mysql配置项交互几次,不是反人类么,尤其是ui的加载速度,现在go chassis有好几个治理规则都有这种错误的设计

from go-archaius.

xy-github-issue avatar xy-github-issue commented on July 18, 2024

旧 mysql: {"user": "root", "pwd": "123", ...}, 新 mysql:{“user”: "rootnew", "pwd": "456"}
这个json按照pretty格式输出后,不就好对比了么

是的,我不怀疑特定的配置中心可以做更多的工作去帮助运维。这只是配置中心的问题。串穿始终的思路,是解放业务。

archaius 既然想要支持多个配置源,就不要为特定的配置中心适配,还请匆忘初心。kie 我并不关心。

一样是两处编辑,何来的简化?
三种接口 cli,rest api,ui,改几个mysql配置项交互几次,不是反人类么,尤其是ui的加载速度,现在go chassis有好几个治理规则都有这种错误的设计

这里我没有理解。是否误解了我的问题或误解了编辑
针对这一句一样是两处编辑,何来的简化,我对比的两方,是

  • 折开配置项的运维工作

  • 合并配置为复杂值单一配置项的运维工作

我结论是它们并无区别,区别是由于配置中心的造成的而非以上的两种设计选择造成的,与 archaius 无关。折开配置项,也要编辑两处,合并也是编辑两处。编辑发布配置从来是两个分开的动作。想象一下,你打开一个 mysql.yaml 或 mysql.json ,编辑它的两处,保存,使用 archaius 的业务把这个文件的内容当作单一的配置项,还是当作折开的多项,与你的编辑有任何关系吗?

from go-archaius.

tianxiaoliang avatar tianxiaoliang commented on July 18, 2024

嗯 那我是说编辑+之后的生效操作

你期望:

  1. 点开userid文件/ui表单
  2. 编辑一个userid
  3. 点击提交/执行命令/调API
  4. 点开密码文件/ui表单
  5. 编辑一个密码
  6. 点击提交/执行命令/调API

我期望
1.点开mysql配置文件/ui表单
2.编辑一个userid
3.编辑一个密码
4.点击提交/执行命令/调API

archaius 既然想要支持多个配置源,就不要为特定的配置中心适配,还请匆忘初心。kie 我并不关心。

看下最早的提交对接的config center,也没有value type字段,我们的方式就是key是文件名,value是文件内容。

from go-archaius.

tianxiaoliang avatar tianxiaoliang commented on July 18, 2024

回到本身我说的这个问题

涉及接口变更,生态已经长成,这会导致太多开发者需要重新适配

因为一开始的设计,所以我才从配置项设计给出了别的规划方式。并不是说我一定非得这么设计archaius,而是接口已形成,没法改(另外接口的设计人也不是我)

from go-archaius.

xy-github-issue avatar xy-github-issue commented on July 18, 2024

你期望:
点开userid文件/ui表单
编辑一个userid
点击提交/执行命令/调API
点开密码文件/ui表单
编辑一个密码
点击提交/执行命令/

啊,我上面无论任何表述都得不出这个结论吧?
同一模块的配置当然是一起的啊。当然编辑两处,发布一次啊。至于页面编辑,点一次点两次都可以毫无难度。本质跟编辑配置文件再保存没区别。

因为一开始的设计,所以我才从配置项设计给出了别的规划方式。并不是说我一定非得这么设计archaius,而是接口已形成,没法改(另外接口的设计人也不是我)

那我们考虑下加接口不动原有listener的方向呢?

from go-archaius.

xy-github-issue avatar xy-github-issue commented on July 18, 2024

点开userid文件/ui表单
编辑一个userid
点击提交/执行命令/调API
点开密码文件/ui表单
编辑一个密码
点击提交/执行命令/调API

看起来是,你们的配置中心改一项就要提交一次。

from go-archaius.

tianxiaoliang avatar tianxiaoliang commented on July 18, 2024

加接口可以,你们设计提PR即可

from go-archaius.

xy-github-issue avatar xy-github-issue commented on July 18, 2024

加接口可以,你们设计提PR即可

好。
那我考虑做成这样:

  • 新增一个 RegisterModuleListener(event.ModuleListener, prefix ... string) 接口
  • 针对 File/Mem/Apollo/Kie/ConfigCenter 等配置源,在对应的 Watch 函数中,加上触发一次ModuleListener 回调的修改。ENV配置源 原本就没有Watch,本身也不是一个实用的配置源,不改。

可能有争议的点:

  1. ModuleListener 这个命名,不知有无更好的建议
  2. 区配 prefix 还是正则?这里我的考虑是,
  • 一般有关联的配置是相同模块的配置,业务的热更新也是以模块来组织的。而相同模块的配置有相同的前缀应该是合情合理的要求。
  • 即便有不同模块的配置有关联需要同时更新(假设假设假设我有一份很烂很烂很烂的代码,redis 模块用了mysql.user 和 redis.pwd 去联 redis),配置源的组织本来就很难保证它们的修改同时被发现被下发。
  • 正则带来一个不便是,如果我没有写成 ‘^xxxx$’ ,就很容易匹配到其他的配置
    所以选择了 prefix。不知道你这边有无其它考虑?

from go-archaius.

tianxiaoliang avatar tianxiaoliang commented on July 18, 2024

嗯 不一定所有source都需要适配ModuleListener,这个你实现你需要的就行

叫BatchEventsListener,就prefix吧,没问题

from go-archaius.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.