spark
很多时候我们需要把一些参数保存在文件里,等程序运行时动态加载,分享两种scala调用的方式:1.Typesafe的Config库
2.java.util.Properties类
简单介绍其一些用法
1.Typesafe的Config库
纯Java写成、零外部依赖、代码精简、功能灵活、API友好。支持Java properties、JSON、JSON超集格式HOCON以及环境变量。它也是Akka的配置管理库。
maven依赖
com.typesafe
config
1.4.0
概述
- 纯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
默认加载classpath下的application.conf,application.json和application.properties文件。通过ConfigFactory.load()加载。
java实现方式
import com.typesafe.config.Config;
import com.typesafe.config.ConfigFactory;
public class CommonConfig {
private Config config;
//指定配置文件
public CommonConfig(Config config) {
this.config = config;
config.checkValid(ConfigFactory.defaultReference(), "simple-lib");
}
// 默认加载classpath下的application.*
public CommonConfig() {
this(ConfigFactory.load());
}
//打印
public void printSetting(String path) {
System.out.println("The setting '" + path + "' is: " + config.getString(path));
}
public static void main(String[] args) {
CommonConfig s = new CommonConfig();
s.printSetting("simple-app.answer");
}
}
scala实现方式
1.工具类
package com.suning.sospdm.utils
import java.io.FileNotFoundException
import java.util
import com.typesafe.config.{Config, ConfigFactory}
import org.apache.commons.collections.CollectionUtils
import org.apache.commons.lang3.{ArrayUtils, StringUtils}
/**
* Description:
* Author: 18051165 WuYu
* Date: 2019/12/30 14:58
*/
object ConfigLoader {
private var config:Config = _
private val PROFILES_ACTIVE_KEY = "app.profiles.active"
/**
* 获取配置信息
* @return Config对象
*/
def getConfig:Config = {
if (config == null || config.isEmpty) {
// 默认方式
var cfg = ConfigFactory.load()
// 配置处理
if(cfg.hasPath(PROFILES_ACTIVE_KEY)){
val activeProfiles = cfg.getAnyRef(PROFILES_ACTIVE_KEY)
activeProfiles match {
case file: String =>
if (!StringUtils.isEmpty(file)) {
try {
cfg = ConfigFactory.load(file)
} catch {
case e: FileNotFoundException => println(e.getMessage)
}
}
case files: util.List[String] =>
if (!CollectionUtils.isEmpty(files)) {
val itr = files.iterator()
while (itr.hasNext) {
try {
val f = itr.next()
val tmpConfig = ConfigFactory.load(f)
cfg = cfg.withFallback(tmpConfig)
} catch {
case e: FileNotFoundException => println(e.getMessage)
}
}
}
case _ =>
}
}
cfg
} else {
config
}
}
/**
* 刷新config
* @return Unit
*/
def refresh():Unit = {config = ConfigFactory.load()}
}
ConfigFactory.load()
会加载配置文件,默认加载classpath下的application.conf
,application.json
和application.properties
文件。
也可以调用ConfigFactory.load(confFileName)
加载指定的配置文件。
2.application.json文件
{
"app": {
"profiles":{
"active": ["./config/dev0.json","./config/dev1.json"]
},
"name": "template",
"master": "local",
"spark": {
"config": {
"testing": {
"memory": "512000000"
},
"hive": {
"enable": false
}
}
},
"resources":{
"data": "E:\\Spark\\myAlgorithmDemo\\src\\main\\resources\\data\\iris.data",
"model": "E:\\Spark\\myAlgorithmDemo\\src\\main\\resources\\model"
}
}
}
3.实例
package com.suning.sospdm.utils
import com.suning.sospdm.utils.ConfigLoader
import com.typesafe.config.Config
/**
* Description:
* Author: 18051165 WuYu
* Date: 2019/12/30 15:27
*/
object ConfigTest {
def main(args: Array[String]): Unit = {
val c = ConfigLoader.getConfig
// 默认地址读取配置
printConfig("app.name", c)
printConfig("app.resources.data", c)
// 指定地址读取
printConfig("app.test0", c)
printConfig("app.test1", c)
}
def printConfig(configName:String, c:Config): Unit = {
println("The setting " + configName + " is: " + c.getString(configName))
}
}
结果如下,在dev0
和dev1
中可以实现相同key,不同value的调用,方便不同环境使用不同的参数,而不用修改其他代码
The setting app.name is: config test
The setting app.resources.data is: E:\Spark\myAlgorithmDemo\src\main\resources\data\iris.data
The setting app.test0 is: this is dev0 config
The setting app.test1 is: this is dev1 config
2.java.util.Properties
Properties是一个键值对存储容器,且键和值的类型都是String,其中键不会重复,文件中后面的会覆盖前面的同名键值对。
*.properties例子
spark.enableHiveSupport = false
spark.memory = 512000000
dataPath = E:/Spark/myAlgorithmDemo/src/main/resources/data
modelPath = E:/Spark/myAlgorithmDemo/src/main/resources/model
scala实现
1.工具类
package com.suning.sospdm.utils
import java.io.InputStream
import java.util.Properties
import org.slf4j.{Logger, LoggerFactory}
/**
* Description: 参数配置
* Author: 18051165 WuYu
* Date: 2019/11/10 15:01
*/
object PropertyUtils extends Serializable {
val log: Logger = LoggerFactory.getLogger(this.getClass)
var p: Properties = _
def apply(): Properties = {
p = new Properties
val fileNames = PropertyFileNameEnum.values
for (fileName <- fileNames) {
loadProperties(fileName.toString)
}
p
}
def loadProperties(fileName: String): Unit = {
var is: InputStream = null
try {
is = this.getClass.getResourceAsStream(fileName)
p.load(is)
} catch {
case e: Exception =>
throw new RuntimeException(e)
} finally {
if (null != is)
try
is.close()
catch {
case e: Exception => throw new RuntimeException(e)
}
}
}
private[utils] object PropertyFileNameEnum extends Enumeration {
type PropertyFileNameEnum = Value
val SPARK: PropertyUtils.PropertyFileNameEnum.Value = Value("/spark.properties")
}
}
默认情况下可以直接读取resources下*.properties
文件,在pom文件中配置maven工具可以设置不同环境,在打包的过程中可以分配配置不同环境下的参数,方便实际工程应用
2.pom文件配置
src/main/resources
dev/*
pre/*
prd/*
*.properties
src/main/resources/${profiles.active}
dev
dev
true
pre
pre
prd
prd
pom文件配置好后,IDEA的Maven工具就会如下显示:
3.实例
package com.suning.sospdm.utils
import java.util.Properties
import com.suning.sospdm.utils.PropertyUtils
/**
* Description:
* Author: 18051165 WuYu
* Date: 2019/12/30 16:34
*/
object PropertyTest {
val prop: Properties = PropertyUtils()
def main(args: Array[String]): Unit = {
printConfig("profiles", prop)
printConfig("spark.enableHiveSupport", prop)
printConfig("spark.memory", prop)
}
def printConfig(propertyName:String, p:Properties): Unit = {
println("The setting " + propertyName + " is: " + p.getProperty(propertyName))
}
}
Maven Profiles默认dev环境的结果:
The setting profiles is: dev
The setting spark.enableHiveSupport is: false
The setting spark.memory is: 512000000
Maven Profiles选择prd环境的结果:
The setting profiles is: prd
The setting spark.enableHiveSupport is: true
The setting spark.memory is: 2048000000