Spark笔记(5):scala两种配置参数的方法

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.jsonapplication.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))
  }
}

结果如下,在dev0dev1中可以实现相同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工具就会如下显示:

IDEA显示截图
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

你可能感兴趣的:(Spark笔记(5):scala两种配置参数的方法)