概述
- 配置文件
概念:一种计算机文件,可给 计算机程序 配置 参数和初始设置
场景:软件开发时,生产环境数据库账号密码 应写到配置文件,不应明文写到代码中
常见的配置文件后缀 | 示例 |
---|---|
.properties |
Kafka的server.properties 用于Java的日志配置文件 log4j.properties |
.xml |
Hadoop的core-site.xml |
.ini |
MySQL的my.ini |
.cnf |
MySQL的my.cnf |
.conf |
Redis的redis.conf |
.yml |
ElasticSearch的elasticsearch.yml |
.bashrc |
每个运行Bash用户的个性化设置 |
.json 、.config.js |
前端常用 |
properties文件是Java中的一种配置文件,文件后缀为
.properties
,内容格式为key=value
,用#
注释
- 传参
本文的传参是指:通过 命令行 来给程序传递参数
传参方式有:位置传参、键值对传参…
当参数多于1个时,建议使用 键值对传参
场景:日期、并行度
规范
-
为了 数据开发 的 代码规范:
配置格式 统一使用 properties
传参方式 统一使用 键值对传参 -
生产环境的配置文件 统一 存放到HDFS
测试配置 写到 本地配置文件
优先级(大者覆盖小者):
临 时 配 置 > 生 产 配 置 临时配置 > 生产配置 临时配置>生产配置
命 令 行 参 数 > H D F S 配 置 文 件 命令行参数 > HDFS配置文件 命令行参数>HDFS配置文件 -
配置文件命名
【建议】全小写
【强制】下划线分隔单词
示例:sqoop_mysql2hive.properties
-
配置文件路径(两种方式):
业务/子业务/存储媒介.properties
部门/小组/岗位.properties
业务 | 子业务 | 媒介 | 配置文件路径 | 参数 |
---|---|---|---|---|
金融 | 股票 | MySQL | /config /finance /stock /mysql.properties |
host user password database |
数据中台 | HBase | /config /data_center /hbase.properties |
zkUrl |
|
数据中台 | Kafka | /config /data_center /kafka.properties |
bootstrap-server |
部门 | 小组 | 员工ID | 配置文件路径 | 参数 |
---|---|---|---|---|
IT | 大数据 | 实时计算 | /config /it /big_data /rt.properties |
queue_name |
IT | 大数据 | 数据仓库 | /config /it /big_data /dw.properties |
queue_name |
IT | 算法 | 自然语言处理 | /config /it /ai /nlp.properties |
queue_name |
代码模板
Python2
#!/usr/bin/python2
# coding:utf-8
"""
获取参数的工具类
获取参数的方式
1、properties配置文件
2、命令行传参
参数格式
key=value
命令行传参示例:
python2 a.py ymd=2021-12-31 sql='带空格的value可用单引号包裹'
参数优先级(大者覆盖小者)
命令行参数 > HDFS配置文件 > 本地配置文件
临时配置 > 生产配置 > 测试配置
详细链接:
https://yellow520.blog.csdn.net/article/details/122088401
"""
class ParameterUtil:
def __init__(self, hdfs_file='', local_file=''):
self.dt = dict()
if local_file:
self._read_local_file(local_file)
if hdfs_file:
self._cat_hdfs(hdfs_file)
self._get_cmd_parameters()
def _read_local_file(self, file_path):
"""从本地读取配置文件,并获取参数"""
try:
with open(file_path) as f:
self._properties2dict(f.read())
except IOError:
print('本地配置文件不存在')
def _cat_hdfs(self, file_path):
"""从HDFS读取配置文件,并获取参数"""
from subprocess import check_output, CalledProcessError
cmd = 'hadoop fs -cat ' + file_path
try:
self._properties2dict(check_output(cmd, shell=True))
except CalledProcessError:
print('HDFS配置文件不存在')
def _properties2dict(self, properties):
"""properties文件内容解析"""
for r in properties.strip().split('\n'):
if (not r.startswith('#')) and (r.find('=') > 0):
k, v = r.split('=', 1)
self.dt[k.strip()] = v.strip()
def _get_cmd_parameters(self):
"""从命令行获取参数"""
from sys import argv
for a in argv[1:]:
k, v = a.split('=', 1)
self.dt[k.strip()] = v.strip()
def get(self, key, default=None):
"""获取参数值"""
return self.dt.get(key, default)
Python3
from time import time, strftime
from datetime import date, timedelta
import os
import platform
from subprocess import check_output, CalledProcessError
class Timer:
def __init__(self):
self.t = time() # 起始秒数
def __del__(self):
if self.__str__():
print('结束时间:%s' % self.now)
print('运行时间:%s' % self)
def __str__(self):
t = self.seconds
if t < 1:
return ''
elif t < 60:
return '%.2fs' % t
elif t < 3600:
return '%.2fmin' % (t / 60)
else:
return '%.2fh' % (t / 3600)
@property
def seconds(self) -> float:
"""程序运行秒数"""
return time() - self.t
@property
def now(self) -> str:
"""当前时间字符串"""
return strftime('%Y-%m-%d %H:%M:%S')
@property
def today(self) -> date:
return date.today()
@property
def yesterday(self) -> str:
yesterday = self.today - timedelta(days=1)
return yesterday.strftime('%Y-%m-%d')
@property
def this_year(self) -> int:
return self.today.year
@property
def last_year(self) -> int:
return self.this_year - 1
@property
def this_month(self) -> str:
"""本月,格式YYYY-MM"""
return '%04d-%02d' % (self.this_year, self.today.month)
@property
def last_month(self) -> str:
"""上个月,格式YYYY-MM"""
last_day_of_last_month = self.today - timedelta(days=self.today.day) # 上个月的最后一天
last_month = last_day_of_last_month.month # 上个月
year = last_day_of_last_month.year # 上个月所在的年份
ym = '%04d-%02d' % (year, last_month) # 上个月的完整格式:YYYY-MM
return ym
class Executor(Timer):
def debug(self, text):
"""仅在Windows打印"""
if platform.system() == 'Windows':
print('[DEBUG {}] {}'.format(self.now, text))
@staticmethod
def execute(cmd):
"""执行Linux命令"""
os.system(cmd)
@staticmethod
def evaluate(cmd):
"""执行Linux命令并获取返回值"""
return check_output(cmd, shell=True)
class ParameterUtil(Executor):
"""https://yellow520.blog.csdn.net/article/details/122088401"""
def __init__(self, *hdfs_files):
super().__init__()
self.dt = dict()
for hdfs_file in hdfs_files:
self._cat_hdfs(hdfs_file)
self._get_cmd_parameters()
def _cat_hdfs(self, file_path):
"""从HDFS读取配置文件,并获取参数"""
cmd = 'hadoop fs -cat ' + file_path
try:
self._properties2dict(self.evaluate(cmd))
except CalledProcessError:
print('HDFS配置文件不存在')
def read_local_file(self, file_path):
"""从本地读取配置文件,并获取参数"""
try:
with open(file_path) as f:
self._properties2dict(f.read())
except IOError:
print('本地配置文件不存在')
def _properties2dict(self, properties):
"""properties文件内容解析"""
for r in properties.strip().split('\n'):
if (not r.startswith('#')) and (r.find('=') > 0):
k, v = r.split('=', 1)
self.dt[k.strip()] = v.strip()
def _get_cmd_parameters(self):
"""从命令行获取参数"""
from sys import argv
for a in argv[1:]:
k, v = a.split('=', 1)
self.dt[k.strip()] = v.strip()
def get(self, key, default=None):
"""获取参数值"""
return self.dt.get(key, default)
@property
def ymd(self) -> str:
"""获取日期,格式YYYY-MM-DD,默认昨天"""
return self.get('ymd', self.yesterday)
@property
def ym(self) -> str:
"""获取日期,格式YYYY-MM,默认上个月"""
return self.get('ym', self.last_month)
Java(待完善)
import java.io.FileInputStream;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Properties;
/**
* ParameterUtil parameters = new ParameterUtil(args, "mysql.properties", "kafka.properties");
* String ymd = parameters.get("ymd");
*/
public class ParameterUtil {
Properties p = new Properties();
public ParameterUtil(String[] args, String... hdfsPaths) {
//获取HDFS上的配置文件
for (String hdfsPath : hdfsPaths) {
catHdfs(hdfsPath);
}
//命令行传参
for (String arg : args) {
String[] kv = arg.split("=", 1);
p.setProperty(kv[0].trim(), kv[1].trim());
}
}
/** 读取HDFS上的配置文件 */
private void catHdfs(String hdfsPath) {
try {
Process process = Runtime.getRuntime().exec("hadoop fs cat " + hdfsPath);
InputStream inputStream = process.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
if (!line.startsWith("#") && line.contains("=")) {
String[] kv = line.split("=", 1);
p.setProperty(kv[0].trim(), kv[1].trim());
}
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
/** 读取本地properties配置文件 */
public void readLocalFile(String localPath) {
try {
p.load(new FileInputStream(localPath));
} catch (IOException e) {
e.printStackTrace();
}
}
public String get(String key) {
return p.getProperty(key);
}
public String get(String key, String defaultValue) {
return p.getProperty(key, defaultValue);
}
}
本文来自博客园,作者:大码王,转载请注明原文链接:https://www.cnblogs.com/huanghanyu/