Version记录
时间 | 主要内容 | 作者 |
---|---|---|
2022-01-27 | 初版,包括需求背景、兼容性影响、重要业务逻辑和后续扩展性考虑 | sunxi92 |
中文文档在描述特定专业术语时,仍然使用英文。
需求背景
RocketMQ ACL特性目前只支持单个ACL配置文件,当存在很多用户时该配置文件会非常大,因此提出支持多ACL配置文件的想法。 如果支持该特性那么也方便对RocketMQ用户进行分类。
兼容性影响
当前在支持多ACL配置文件特性的设计上是向前兼容的。
重要业务逻辑
1. ACL配置文件存储路径
ACL配置文件夹是在RocketMQ安装目录下的conf/acl目录中,也可以在该路径新建子目录并在子目录中新建ACL配置文件,同时也保留了之前默认的配置文件conf/plain_acl.yml。 注意:目前用户还不能自定义配置文件目录。
2. ACL配置文件更新
热感知:当检测到ACL配置文件改动会自动刷新数据,判断ACL配置文件是否发生变化的依据是文件的修改时间是否发生变化
3. RocketMQ Broker缓存ACL配置信息数据结构设计
- aclPlainAccessResourceMap
aclPlainAccessResourceMap是个Map类型,用来缓存所有ACL配置文件的权限数据,其中key表示ACL配置文件的绝对路径, value表示相应配置文件中的权限数据,需要注意的是value也是一个Map类型,其中key是String类型表示AccessKey,value是PlainAccessResource类型。 - accessKeyTable
accessKeyTable是个Map类型,用来缓存AccessKey和ACL配置文件的映射关系,其中key表示AccessKey,value表示ACL配置文件的绝对路径。 - globalWhiteRemoteAddressStrategy
globalWhiteRemoteAddressStrategy用来缓存所有ACL配置文件的全局白名单。 - globalWhiteRemoteAddressStrategyMap
globalWhiteRemoteAddressStrategyMap是个Map类型,用来缓存ACL配置文件和全局白名单的映射关系 - dataVersionMap
dataVersionMap是个Map类型,用来缓存所有ACL配置文件的DataVersion,其中key表示ACL配置文件的绝对路径,value表示该配置文件对应的DataVersion。
4.加载和监控ACL配置文件
4.1 加载ACL配置文件
- load()
load()方法会获取”RocketMQ安装目录/conf/acl”目录(包括该目录的子目录)和”rocketmq.acl.plain.file”下所有ACL配置文件,然后遍历这些文件读取权限数据和全局白名单。 - load(String aclFilePath)
load(String aclFilePath)方法完成加载指定ACL配置文件内容的功能,将配置文件中的全局白名单globalWhiteRemoteAddresses和用户权限accounts加载到缓存中, 这里需要注意以下几点:
(1)判断缓存中该配置文件的全局白名单globalWhiteRemoteAddresses和用户权限accounts数据是否为空,如果不为空则需要注意删除文件原有数据
(2)相同的accessKey只允许存在在一个ACL配置文件中
4.2 监控ACL配置文件
watch()方法用来监控”RocketMQ安装目录/conf/acl”目录下所有ACL配置文件和”rocketmq.acl.plain.file”是否发生变化,变化考虑两种情况:一种是ACL配置文件的数量发生变化, 此时会调用load()方法重新加载所有配置文件的数据;一种是配置文件的内容发生变化;具体完成监控ACL配置文件变化的是AclFileWatchService服务, 该服务是一个线程,当启动该服务后它会以WATCH_INTERVAL(该参数目前设置为5秒,目前还不能在Broker配置文件中设置)的时间间隔来执行其核心逻辑。在该服务中会记录其监控的ACL配置文件目录aclPath、 ACL配置文件的数量aclFilesNum、所有ACL配置文件绝对路径fileList以及每个ACL配置文件最近一次修改的时间fileLastModifiedTime (Map类型,key为ACL配置文件的绝对路径,value为其最近一次修改时间)。 该服务的核心逻辑如下: 获取ACL配置文件数量并和aclFilesNum进行比较是否相等,如果不相等则更新aclFilesNum和fileList并调用load()方法重新加载所有配置文件; 如果相等则遍历每个ACL配置文件,获取其最近一次修改的时间,并将该时间与fileLastModifiedTime中记录的时间进行比较,如果不相等则表示该文件发生过修改, 此时调用load(String aclFilePath)方法重新加载该配置文件。
5. 权限数据相关操作修改
(1) updateAclConfigFileVersion(Map
添加对缓存dataVersionMap的修改
(2)updateAccessConfig(PlainAccessConfig plainAccessConfig)
将该方法原有的逻辑修改为:首先判断accessKeyTable中是否包含待修改的accessKey,如果包含则根据accessKey来获取其对应的ACL配置文件绝对路径, 再根据该路径更新aclPlainAccessResourceMap中缓存的数据,最后将该ACL配置文件中的数据写回原文件;如果不包含则会将数据写到”rocketmq.acl.plain.file”配置文件中, 然后更新accessKeyTable和aclPlainAccessResourceMap,最后最后将该ACL配置文件中的数据写回原文件。
(3)deleteAccessConfig(String accessKey)
将该方法原有的逻辑修改为:判断accessKeyTable中是否存在accessKey,如果不存在则返回false,否则将其删除并将修改后的数据写回原文件。
(4)getAllAclConfig()
fileList中存储了所有ACL配置文件的绝对路径,遍历fileList分别从各ACL配置文件中读取数据并组装返回
(5)updateGlobalWhiteAddrsConfig(List
该方法是新增的,完成功能是修改指定ACL配置文件的全局白名单,为后续添加相关运维命令做准备
6. ACL相关运维命令修改
(1)ClusterAclConfigVersionListSubCommand
将printClusterBaseInfo(final DefaultMQAdminExt defaultMQAdminExt, final String addr)方法原有的逻辑修改为: 获取全部的ACL配置文件的DataVersion并输出。注意:获取的全部ACL配置文件的DataVersion集合可能为空,这里需要添加判断
(2)GetBrokerAclConfigResponseHeader
在GetBrokerAclConfigResponseHeader中新增allAclFileVersion字段,它是个Map类型,其key表示ACL配置文件的绝对路径,value表示对应ACL配置文件的DataVersion
(3)ClusterAclVersionInfo
在ClusterAclVersionInfo中废弃了aclConfigDataVersion属性,增加了allAclConfigDataVersion属性,该属性是个Map类型,用来存储所有ACL配置文件的版本数据, 其中key表示ACL配置文件的绝对路径,value表示对应ACL配置文件的DataVersion
7. 关于ACL配置文件DataVersion存储修改
在原来版本中ACL权限数据存储在一个配置文件中,所以只记录了该配置文件的DataVersion,而现在需要支持多个配置文件特性,每个配置文件都有自己的DataVersion, 为了能够准确记录所有配置文件的DataVersion,需要调整相关类型的属性、接口及方法。
(1)PlainPermissionManager
对PlainPermissionManager属性的修改具体如下:
废弃dataVersion属性,该属性在历史版本中是用来存来存储默认ACL配置文件的DataVersion
新增dataVersionMap属性用来缓存所有ACL配置文件的DataVersion,它是一个Map类型,其key表示ACL配置文件的绝对路径,value表示对应配置文件的DataVersion
(2)AccessValidator
对AccessValidator的修改如下:
废弃String getAclConfigVersion();,该接口原来是获取ACL配置文件文件的版本数据
新增Map
getAllAclConfigVersion();该接口是用来获取所有ACL配置文件的版本数据,接口会返回一个Map类型数据, key表示各ACL配置文件的绝对路径,value表示对应配置文件的版本数据
(3)PlainAccessValidator
由于PlainAccessValidator实现了AccessValidator接口,所以相应地增加了getAllAclConfigVersion()方法
后续扩展性考虑
1.目前的修改只支持ACL配置文件存储在”RocketMQ安装目录/conf/acl”目录下,后续可以考虑支持多目录;
2.目前ACL配置文件路径是不支持让用户指定,后续可以考虑让用户指定指定ACL配置文件的存储路径
3.当前updateGlobalWhiteAddrsConfig命令只支持修改”rocketmq.acl.plain.file”文件中全局白名单, 后续可以扩展为修改指定ACL配置文件的全局白名单(如果参数中没有传ACL配置文件则会修改”rocketmq.acl.plain.file”文件)
4.目前ACL数据中的secretKey是以明文形式存储在文件中,在一些对此类信息敏感的行业是不允许以明文落地,后续可以考虑安全性问题
5.目前ACL数据存储只支持文件形式存储,后续可以考虑增加数据库存储
更新时间:2023-08-22 15:38