FIT 提供了一套配置机制,用于在开发、运行及调试过程中进行配置管理,提供了分层管理、优先级管理功能。本节将介绍配置机制的优先级、常用配置项、导入及使用以及解码器的使用方式。
FIT 支持如下集中方式的配置加载,其优先级如下:
- 加载来自命令行的配置;
- 加载来自系统属性的配置;
- 加载来自环境变量的配置;
- 加载来自配置文件的配置:
- 如果前述配置中,指定了配置文件,则从指定的配置文件中加载配置;
- 否则,从默认的文件中加载。
- 应用配置文件 > 框架配置文件 > 插件配置文件
关于各部分的具体配置方式将在 3.3 中详细介绍。
从命令行中解析 -key=value 或 key=value 的信息加载至配置中,示例如下:
fit debug -XX:MaxGCPauseMillis=200 server.http.port=8081
上述命令表示:设置垃圾回收最大暂停时间为 200 毫秒;服务器的 Http 服务端口号为 8081。
对于key的设置请遵守如下规范:
- 对于Java相关参数,如设置内存大小、垃圾回收机制等,请使用
-key=value; - 对于程序相关参数,如端口号等具体内置需要,请使用
key=value方式。
直接通过System.getProperties()所获取的系统属性生成配置,示例如下:
{
"java.runtime.name": "OpenJDK Runtime Environment",
"java.protocol.handler.pkgs": "modelengine.itframework.protocol",
...
"path.separator": ",",
"java.vm.name": "OpenJDK 64-Bit Server VM",
"file.encoding.pkg": "sun.io",
"user.country": "CN",
"user.script": "",
"sun.java.launcher": "SUN_STANDARD",
...
}上述示例,简要展示了如 java.runtime.name, java.vm.name等 Java 系统属性信息;
通过该方式将获取当前 Java 系统的所有属性,并加载至配置中。
直接通过System.getenv()所获取的环境变量生成配置,示例如下:
{
"PATH": "xxx",
"USERDOMAIN_ROAMINGPROFILE": "CHINA",
...
"USERNAME": "xxx",
"JAVA_HOME": "C:\Program Files\xxx\jdk1.8.0_402\",
"MSYS": "disable_pcon",
"OS": "Windows_NT",
"HOMEDRIVE": "C:",
...
}上述示例,简要展示了如 PATH, USERNAME等系统环境变量信息;
通过该方式将获取当前系统的所有环境变量的信息,并加载至配置中。
配置文件分为两类:外部配置文件、内置配置文件,FIT 优先从外部配置文件中读取配置,当外部配置文件中不存在相关配置时,才会使用内置配置文件的配置。
外部配置文件的内容示例如下:
application:
name: 'application' # 默认应用名
worker:
id: 'default-worker-id' # 默认的进程唯一标识,该配置需要进行覆盖,避免workerId相同注册服务混乱
host: 'localhost' # 该配置需要修改为真实启动的本地ip地址
environment: 'local' # 默认环境标
environment-sequence: 'local' # 默认环境调用链
exit:
graceful: true- 支持通过命令行设置
-config-file=xx指定配置文件路径。 - 未指定时,默认读取
framework/fit/java/fit-runtime/src/main/resources/fitframework.yml的配置文件,在编译后存储在build/conf/fitframework.yml中。对于仅需修改框架配置文件的场景,可临时修改build/conf/fitframework.yml后,无需编译直接启动。
以 fit-service-registry 插件的 application.yml 的示例如下:
plugin:
registry:
sync:
period: 15
heartbeat:
sync:
initial-delay: 5
period: 2
alive-time: 5
worker:
expire-time: 20
fit:
beans:
packages:
- 'modelengine.fit.service'- 存在某种场景下可能会有多个配置文件,每个配置文件对应一个环境或者一种配置,可通过前述的方式指定
fit.profiles.active=xxx,将加载活动配置文件中的配置; - 未指定时,默认读取检索
application.properties,application.ymal,application.yml中的信息,并生成配置默认的内置配置。
在FIT中,配置由容器进行管理,通过注入 Config 可以获取所有的配置信息进行自定义的使用。
使用示例如下:
@Component
public class ConfigTest {
private final Config config;
public ConfigTest(Config config) {
// 注入至容器。
this.config= config;
}
void useConfigUse() {
// 获取配置中包含的键的集合。
Set<String> keys = this.config.keys();
// 获取指定键的配置值,并转换成指定类型。
String configA = this.config.get("A", String);
}
}更丰富的配置使用接口如下:
String name():获取配置的名称;Set<String> keys():获取配置中包含的键的集合;Object get(String key, Type type):获取指定键的配置的值,并转换成指定类型;<T> T get(String key, Class<T> clazz):获取指定键的配置的值,并转换成指定类型;decrypt(@Nonnull ConfigDecryptor decryptor):对所有配置进行解密,需根据5重写解密器;<T> List<T> list(String key, Class<T> elementClass):获取指定键的配置的值的列表,并将每一个值转换成指定类型;
@Value
允许开发者在代码中注入来自属性文件的值,示例如下:
resourcs/application.properties内容如下
default-expire-time: 30
fit:
beans:
packages:
- 'xxx'
- 'xxx'- 代码开发中使用如下:
public RegistryServer(@Value("${default-expire-time}") int defaultExpireTime, WorkerCache cache) {
this.defaultExpireTime = defaultExpireTime;
this.cache = notNull(cache, "The worker cache cannot be null.");
}@Value注解可以直接放在字段上,用于注入属性文件中定义的值。- 语法为
@Value("${property.name}"),其中property.name是属性文件中的键名。
@AcceptConfigValues
用来管理和绑定外部配置(如属性文件、环境变量等)到 Java 对象,使用示例如下:
@Component
@AcceptConfigValues("server.http")
public class DefaultHttpConfig implements HttpConfig {
...
}- 通常会创建一个类来包含所有相关的配置属性,然后通过在这个类上添加
@AcceptConfigValues注解; - 可以指定一个前缀,Fit 将所有带有这个前缀的属性绑定到同名的类字段上;
FIT 支持配置文件中的值使用系统属性或环境变量进行替换。标准的${name}属性占位符语法可以在配置文件中的任意位置进行使用,并在插件启动时进行替换,示例用法如下:
配置文件示例:
a:
b: '${1}'
c: '{"2" : "3"}'
d: '${hello} : ${bye} : {ok}'
n: ${hello}
x: '{"name" : "bob"}'
y: '{"1" : 2, "2" : ${hello}}'配置结果示例:
a.b: null
a.c: {"2" : "3"}
a.d: 你好 : 再见 : {ok}
a.n: 你好
a.x: {"name" : "bob"}
a.y: {"1" : 2, "2" : 你好}在处理敏感信息时,例如数据库的用户名和密码、API 密钥等,为了保护数据的安全性,通常会对这些信息进行加密。
在需要加解密的场景下,用户可以在自定义插件内实现 ConfigDecryptor,重写 decrypt 方法,满足所需的解密需求。

重写示例如下:
@Component
public class TestConfigDecryptor implements ConfigDecryptor {
private final Decryptor decryptor;
public TestConfigDecryptor (Decryptor decryptor) {
this.decryptor = decryptor;
}
private static boolean isEncrypted(String value) {
// 根据自定义的需求判断是否需要解密。
...
return result;
}
@Override
public Optional<String> decrypt(String key, String originValue) {
// 根据自定义的需求对原始键值对进行解密。
...
return result;
}
}以下是 FIT 的内置配置项及相关说明,当开发者自定义配置项时,请避免占用内置配置项,避免冲突。
| 配置项名 | 配置项类型 | 配置项作用 | 配置项说明 |
|---|---|---|---|
| applicatiopn.name | String | 应用名称 | |
| application.extensions | Map<String, Object> | 应用扩展信息 | 请控制扩展项的数量,避免过多 |
| 配置项名 | 配置项类型 | 配置项作用 | 配置项说明 |
|---|---|---|---|
| matata.registry.host | String | 注册中心的地址 | |
| matata.registry.port | Integer | 注册中心的端口号 | |
| matata.registry.protocol | Integer | 与注册中心交互的传输协议 | 值为 0 表示 Rsocket 的传输协议;值为 2 表示 Http 的传输协议;值为 3 表示Grpc 的传输协议;值为 4 表示 Https 的传输协议 |
| matata.registry.environment | String | 注册中心的环境标 | |
| matata.registry.extensions | Map<String, Object> | 扩展信息集合 | 请控制扩展项的数量,避免过多 |
| matata.registry.available-services | List<AvailableService> | 可用服务地址的配置列表 | AvailableService 具体配置见 available-services; 请控制列表的大小,避免过多 |
| 配置项名 | 配置项类型 | 配置项作用 | 配置项说明 |
|---|---|---|---|
| genericable-name | String | 服务的名字 | |
| genericable-id | String | 服务的唯一标识 | 仅支持数字、大小写字母以及 '-'、'_'、'*'、'.' 字符且长度在128以内 |
| genericable-version | String | 服务的版本号 | |
| fitable-id | String | 服务实现的唯一标识 | 仅支持数字、大小写字母以及 '-'、'_'、'*'、'.' 字符且长度在128以内 |
| fitable-version | String | 服务实现的版本号 | |
| formats | String | 服务支持的序列化方式列表 |
| 配置项名 | 配置项类型 | 配置项作用 | 配置项说明 |
|---|---|---|---|
| id | String | 运行进程的唯一标识 | |
| instanceId | String | 运行进程实例的唯一标识 | |
| host | String | 运行进程的地址 | |
| domain | String | 运行进程的域名 | |
| environment | String | 运行进程的环境标信息 | |
| raw-environment-sequence | String | 运行进程的压缩的环境链信息 | |
| environment-sequence | List<String> | 运行进程的环境链信息 | 请控制列表的大小,避免过多 |
| 配置项名 | 配置项类型 | 配置项作用 | 配置项说明 |
|---|---|---|---|
| http.secure.ignore-hostname | Boolean | 客户端 Http 是否忽略对服务器主机名的身份认证 | |
| http.secure.ignore-trust | Boolean | 客户端 Http 是否忽略服务器根证书 | |
| http.secure.encrypted | Boolean | 客户端 Http 的获取密码是否加密 | 当某配置项使用加密内容时,请开启该配置 |
| http.secure.trust-store-file | String | 客户端 Http 的秘钥库的文件地址 | 注意填充绝对路径 |
| http.secure.key-store-file | String | 客户端 Http 的秘钥库的秘钥项的文件地址 | 注意填充绝对路径 |
| http.secure.trust-store-password | String | 客户端 Http 的秘钥库的密码 | 请尽量使用加密密码,并开启解密配置,保证隐私 |
| http.secure.key-store-password | String | 客户端 Http 的秘钥库的秘钥项的密码 | 请尽量使用加密密码,并开启解密配置,保证隐私 |
| http.secure.secure-random-enabled | Boolean | 客户端 Http 的安全相关的是否使用强随机数 | 无配置时默认采用安全随机数 |
| http.secure.secure-protocol | String | 客户端 Http 的安全相关的安全通信协议 | 默认采用 TLSv1.2 安全通信协议 |
| 配置项名 | 配置项类型 | 配置项作用 | 配置项说明 |
|---|---|---|---|
| http.enabled | Boolean | 服务端 Http 的端口是否打开 | 当server.http.secure.enabled==flase或server.http.enabled==true或server.http.enabled==null && server.http.port==xxx,则开启 http 协议。 |
| http.port | Integer | 服务端 Http 的端口号 | |
| http.to-register-port | Integer | 服务端 Http 的注册的端口号 | |
| http.large-body-size | long | 服务端 Http 的巨大消息体的阈值 | |
| http.secure.enabled | Boolean | 服务端 Http 的安全相关的端口是否打开 | 当server.http.secure.enabled==false则不启用 https,其余情况均开启 https;当前框架未配置该项,即默认开启 https。 |
| http.secure.need-client-auth | Boolean | 服务端 Http 的安全相关的是否校验客户端证书 | |
| http.secure.port | Integer | 服务端 Http 的安全相关的端口号 | |
| http.secure.to-register-port | Integer | 服务端 Http 的安全相关的注册的端口号 | |
| http.secure.trust-store-file | String | 服务端 Http 的安全相关的秘钥库的文件地址 | 注意填充绝对路径 |
| http.secure.encrypted | Boolean | 服务端 Http 的安全相关的获取密码是否加密 | 当某配置项使用加密内容时,请开启该配置 |
| http.secure.key-store-file | String | 服务端 Http 的安全相关的秘钥库的秘钥项的文件地址 | 注意填充绝对路径 |
| http.secure.trust-store-password | String | 服务端 Http 的安全相关的秘钥库的密码 | 请尽量使用加密密码,并开启解密配置,保证隐私 |
| http.secure.key-store-password | String | 服务端 Http 的安全相关的秘钥库的秘钥项的密码 | 请尽量使用加密密码,并开启解密配置,保证隐私 |
| http.secure.secure-random-enabled | Boolean | 服务端 Http 的安全相关的是否使用强随机数 | 无配置时默认采用安全随机数 |
| http.secure.secure-protocol | String | 服务端 Http 的安全相关的安全通信协议 | 默认采用 TLSv1.2 安全通信协议 |
当开启 https 时,需要配置证书、秘钥等信息,请按照上述规范进行配置,否则会提示
Https server enabled by default, but https is not configured correctly.
| 配置项名 | 配置项类型 | 配置项作用 |
|---|---|---|
| logging.level | String | 日志的打印级别 |
| logging.config | String | 日志的配置文件 |
| 配置项名 | 配置项类型 | 配置项作用 | 配置项说明 |
|---|---|---|---|
| fit.profiles.active | String | 需要激活的 profile | |
| fit.beans.packages | String[] | 需要扫描的包路径 | 当所创建的项目为插件时,该值必须配置 |
| fit.datasource.primary | String | 所选用的数据源名称 | |
| fit.datasource.instances | Map<String, Object> | 所配置的数据源集合 | 请控制数据源的数量,避免过多 |
| fit.datasouce.instances.sample.mode | String | sample 数据源的模式 | 可选用shared及exclusive两种模式,分别表示共享及独占数据源 |
| fit.datasouce.instances.sample.url | String | sample 数据源的 url | |
| fit.datasouce.instances.sample.password | String | sample 数据源的密码 | 请尽量使用加密密码,并开启解密配置,保证隐私 |
| fit.datasouce.instances.sample.druid | Map<String, Object> | druid的相关配置 |
| 配置项名 | 配置项类型 | 配置项作用 | 配置项说明 |
|---|---|---|---|
| fit.message-serializer.large-data-size | Long | 表示反序列化数据大小的阈值 | 默认不设置上限 |
1 对于非基本类型的配置项,请控制数量及大小,避免出现配置加载困难
FIT 提供了一套配置机制,用于在开发、运行及调试过程中进行配置管理,提供了分层管理、优先级管理功能。开发者需要进行 FIT 框架的必要配置以及个性化配置,在这个过程中可能存在以下的风险点,请注意管控。
- 建议保证运行环境的安全性,避免攻击者修改配置;
- 建议对隐私信息进行加密处理,并开启相应的解密配置,避免隐私泄露;
- 使用
FIT内置配置时,请按照文档配置,并注意约束; - 使用自定义配置时,请避免使用
FIT内置配置项,避免冲突; - 建议配置项数量保持在合理范围内,过多的配置项可能会导致加载缓慢,甚至可能影响框架的启动和运行效率;
- 建议配置文件保持在合理的大小范围内,过大的配置文件会导致加载缓慢,甚至可能影响框架的启动和运行效率;
- 建议控制集合形式的配置项的长度,过长的集合会导致加载缓慢,甚至可能影响框架的启动和运行效率;