配置管理库typesafe.config

Typesafe Config库详解

Typesafe的Config库,纯Java写成、零外部依赖、代码精简、功能灵活、API友好。支持Java properties、JSON、JSON超集格式HOCON以及环境变量。它也是Akka的配置管理库.

  • 纯java实现,无任何依赖
  • 充分的测试
  • 支持: Java properties, JSON, and a human-friendly JSON superset
  • 可以合并各种格式的配置文件
  • 可以通过文件、urls、classpath加载配置
  • 支持多层嵌套的配置方式
  • 识别Java system properties, 如java -Dmyapp.foo.bar=10
  • 可以转换长短,大小等单位。如配置文件中timeout=10s,则可以转换成任意的毫秒或者
  • 类型转换,比如yes可以转换为boolean类型的true
  • JSON superset features:
    • comments
    • includes
    • substitutions ("foo" : ${bar}"foo" : Hello ${who})
    • properties-like notation (a.b=c)
    • less noisy, more lenient syntax
    • substitute environment variables (logdir=${HOME}/logs)

目前config只支持配置文件,如果想从数据库获取配置文件,需要自己diy。 config库很擅长合并配置。

Example

默认加载classpath下的application.conf,application.json和application.properties文件。通过ConfigFactory.load()加载。

# these are our own config values defined by the app
simple-app {
    answer=42
}
 
# Here we override some values used by a library
simple-lib.foo="This value comes from simple-app's application.conf"
simple-lib.whatever = "This value comes from simple-app's application.conf"
public class SimpleLibContext {
    private Config config;
 
    //指定配置文件
    public SimpleLibContext(Config config) {
        this.config = config;
        config.checkValid(ConfigFactory.defaultReference(), "simple-lib");
    }
 
    // 默认加载classpath下的application.*
    public SimpleLibContext() {
        this(ConfigFactory.load());
    }
 
    //打印
    public void printSetting(String path) {
        System.out.println("The setting '" + path + "' is: " + config.getString(path));
    }
 
    public static void main(String[] args) {
        SimpleLibContext s = new SimpleLibContext();
        s.printSetting("simple-app.answer");
    }
}

ConfigFactory.load()会加载配置文件,默认加载classpath下的application.conf,application.json和application.properties文件。当然也可以调用ConfigFactory.load(confFileName)加载指定的配置文件。

配置内容即可以是层级关系,也可以用”.”号分隔写成一行:

host{  
  ip = 127.0.0.1  
  port = 2282  
}
host.ip = 127.0.0.1  
host.port = 2282 

即json格式和properties格式。(貌似*.json只能是json格式,*.properties只能是properties格式,而*.conf可以是两者混合,而且配置文件只能是以上三种后缀名)

如果多个config 文件有冲突时,解决方案有:
1. a.withFallback(b) //a和b合并,如果有相同的key,以a为准 
2. a.withOnlyPath(String path) //只取a里的path下的配置
3. a.withoutPath(String path) //只取a里出path外的配置
例如:

派生到我的代码片
Config firstConfig = ConfigFactory.load("test1.conf");  
Config secondConfig = ConfigFactory.load("test2.conf");  
  
//a.withFallback(b)  a和b合并,如果有相同的key,以a为准  
Config finalConfig = firstConfig.withOnlyPath("host").withFallback(secondConfig);

 

<think>我们遇到了一个配置缺失的错误:`com.typesafe.config.ConfigException$Missing: No configuration setting found for key 'kafka'`。这个错误发生在Flink作业中,具体是在尝试加载Kafka配置时,没有找到名为'kafka'的配置项。 ### 错误分析 1. **错误类型**:`ConfigException$Missing`,表示在配置文件中缺少必要的配置项。 2. **错误位置**:在`KafkaConfig`类的第50行,尝试从配置中获取字符串值时发生。 3. **配置框架**:使用的是Typesafe Config(常见于Scala项目,但Java中也有使用)。 ### 原因 - 代码中使用了`Config`对象来获取配置,例如: ```java Config config = ConfigFactory.load(); String brokers = config.getString("kafka.brokers"); ``` 但是,在配置文件中(如`application.conf`或`reference.conf`)没有定义`kafka`相关的配置项。 ### 解决方案 #### 1. 检查配置文件 确保在Flink作业的配置文件中(通常是`application.conf`或`application.properties`)有正确的Kafka配置。例如: 在`application.conf`中: ```hocon kafka { brokers = "kafka-broker1:9092,kafka-broker2:9092" topic = "my-topic" group.id = "my-group" } ``` 或者在`application.properties`中(如果使用Properties格式): ```properties kafka.brokers=kafka-broker1:9092,kafka-broker2:9092 kafka.topic=my-topic kafka.group.id=my-group ``` #### 2. 确保配置文件被正确加载 - 配置文件必须放在类路径下(如`src/main/resources`)。 - 如果使用Flink提交作业,确保配置文件被打包到JAR文件中。 #### 3. 使用Flink的配置参数覆盖 在提交Flink作业时,可以通过`-D`参数来覆盖配置值。例如: ```bash flink run -d -c com.example.MainClass \ -Dkafka.brokers="kafka-broker1:9092,kafka-broker2:9092" \ -Dkafka.topic="my-topic" \ -Dkafka.group.id="my-group" \ your-job.jar ``` #### 4. 修改代码,增加默认值或配置检查 为了避免因配置缺失导致作业失败,可以在代码中增加默认值或配置检查: ```java Config config = ConfigFactory.load(); String brokers; try { brokers = config.getString("kafka.brokers"); } catch (ConfigException.Missing e) { // 使用默认值 brokers = "localhost:9092"; // 或者抛出更明确的异常 throw new RuntimeException("Kafka brokers not configured", e); } ``` #### 5. 检查配置加载机制 确保在创建`Config`对象时没有指定其他配置文件而忽略了默认的配置文件。例如,如果使用以下方式加载配置,则不会加载默认的`application.conf`: ```java Config config = ConfigFactory.empty(); // 这将得到一个空配置 ``` 应该使用: ```java Config config = ConfigFactory.load(); // 加载默认配置文件 ``` ### 示例代码 假设我们有一个`KafkaConfig`类,用于加载Kafka配置: ```java import com.typesafe.config.Config; import com.typesafe.config.ConfigFactory; public class KafkaConfig { private final String brokers; private final String topic; private final String groupId; public KafkaConfig() { Config config = ConfigFactory.load(); // 使用try-catch处理缺失的配置 this.brokers = getConfigOrThrow(config, "kafka.brokers"); this.topic = getConfigOrThrow(config, "kafka.topic"); this.groupId = getConfigOrThrow(config, "kafka.group.id"); } private String getConfigOrThrow(Config config, String path) { if (config.hasPath(path)) { return config.getString(path); } else { throw new RuntimeException("Missing configuration for: " + path); } } // Getters... } ``` ### 总结 - 错误原因:配置文件中缺少`kafka`相关的配置项。 - 解决步骤: - 添加正确的配置到配置文件中。 - 确保配置文件在类路径下。 - 通过命令行参数覆盖配置。 - 在代码中增加配置缺失的处理逻辑。 §§相关问题§§: 1. Typesafe Config 库如何加载配置文件? 2. 在 Flink 作业中,如何动态加载配置? 3. 如何为 Flink 作业指定外部配置文件? 4. 除了 Typesafe Config,Flink 中还有哪些配置管理方式?</think>## Flink 配置缺失问题分析与解决方案 ### 错误分析 你遇到的错误是:`com.typesafe.config.ConfigException$Missing: No configuration setting found for key 'kafka'`。这表明你的 Flink 应用程序在加载配置时,无法找到名为 `kafka` 的配置项。具体原因可能是: 1. **配置文件缺失**:应用未正确加载包含 Kafka 配置的文件 2. **配置路径错误**:代码中引用的配置路径与实际配置不匹配 3. **配置加载机制问题**:在 Flink 环境中配置加载方式不正确 4. **依赖冲突**:Typesafe Config 库版本冲突 ### 解决方案 #### 1. 添加正确的 Kafka 配置 在 `src/main/resources/application.conf` 中添加 Kafka 配置: ```hocon kafka { bootstrap.servers = "localhost:9092" group.id = "flink-consumer-group" auto.offset.reset = "earliest" topic = "input-topic" # 如果需要 SSL 认证 security.protocol = "SSL" ssl.truststore.location = "/path/to/truststore.jks" ssl.truststore.password = "password" } ``` #### 2. 修复配置加载代码 在 Flink 作业中正确加载配置: ```java import com.typesafe.config.Config; import com.typesafe.config.ConfigFactory; public class KafkaConfigLoader { public static Properties loadKafkaProperties() { Config config = ConfigFactory.load(); // 加载默认配置文件 Properties props = new Properties(); // 检查配置是否存在 if (!config.hasPath("kafka")) { throw new RuntimeException("Missing 'kafka' configuration section"); } // 获取 Kafka 配置 Config kafkaConfig = config.getConfig("kafka"); // 设置 Kafka 属性 props.put("bootstrap.servers", kafkaConfig.getString("bootstrap.servers")); props.put("group.id", kafkaConfig.getString("group.id")); props.put("auto.offset.reset", kafkaConfig.getString("auto.offset.reset")); // 添加更多配置... return props; } } ``` #### 3. 在 Flink 作业中使用配置 在 Flink 流处理作业中正确使用 Kafka 配置: ```java import org.apache.flink.streaming.connectors.kafka.FlinkKafkaConsumer; import org.apache.flink.api.common.serialization.SimpleStringSchema; public class KafkaFlinkJob { public static void main(String[] args) throws Exception { // 加载 Kafka 配置 Properties kafkaProps = KafkaConfigLoader.loadKafkaProperties(); // 创建 Kafka 消费者 FlinkKafkaConsumer<String> consumer = new FlinkKafkaConsumer<>( kafkaProps.getProperty("topic"), new SimpleStringSchema(), kafkaProps ); // 设置检查点 consumer.setStartFromGroupOffsets(); // 创建 Flink 环境 StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); env.enableCheckpointing(5000); // 每 5 秒一次检查点 // 添加 Kafka 源 DataStream<String> stream = env.addSource(consumer); // 数据处理逻辑... stream.print(); // 执行作业 env.execute("Kafka Flink Processing Job"); } } ``` #### 4. 确保配置文件正确打包 在 Maven 的 `pom.xml` 中确保资源文件正确打包: ```xml <build> <resources> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.conf</include> <include>**/*.properties</include> </includes> </resource> </resources> </build> ``` #### 5. 处理配置缺失的异常 在代码中添加更友好的错误处理: ```java try { Config config = ConfigFactory.load(); String brokers = config.getString("kafka.bootstrap.servers"); } catch (ConfigException.Missing e) { LOG.error("Missing Kafka configuration: {}", e.getMessage()); LOG.error("Please ensure your application.conf contains 'kafka' section"); System.exit(1); } ``` ### 常见问题排查 1. **配置文件位置错误**: - 确保 `application.conf` 在类路径的根目录下(`src/main/resources`) - 检查文件名拼写是否正确(区分大小写) 2. **配置加载顺序问题**: - Flink 会先加载 `flink-conf.yaml` 再加载应用配置 - 使用 `ConfigFactory.parseResourcesAnySyntax("application")` 显式加载 3. **依赖冲突**: ```xml <!-- 确保使用兼容的 Typesafe Config 版本 --> <dependency> <groupId>com.typesafe</groupId> <artifactId>config</artifactId> <version>1.4.2</version> </dependency> ``` 4. **环境变量覆盖**: - 检查是否设置了 `CONFIG_FILE` 环境变量覆盖了默认配置 ### 总结 该错误的核心问题是 Flink 应用未能正确加载 Kafka 配置。解决方案包括: 1. 创建正确的 `application.conf` 配置文件 2. 使用 Typesafe Config 库正确加载配置 3. 在 Flink Kafka 消费者中使用加载的配置 4. 确保配置文件被打包到最终 JAR 中 5. 添加友好的错误处理逻辑 通过以上步骤,你的 Flink 应用应该能正确加载 Kafka 配置并正常运行。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值