1. 实例的开启与关闭

var zkClient: ZooKeeper = null
try {
zkClient = new ZooKeeper(getZkUrl(), 2000, new Watcher {
override def process(watchedEvent: WatchedEvent): Unit = {}
}) val data = zkClient.getData(s"/hadoop-ha/" + hdfsNameServiceHost + s"/ActiveBreadCrumb", new Watcher {
override def process(watchedEvent: WatchedEvent): Unit = {}
}, new Stat()) val activeNodeInfo = HAZKInfoProtos.ActiveNodeInfo.parseFrom(data) activeNodeInfo.getHostname
} catch {
case ex: Exception => {
logError(s"ERROR: zookeeper connect failure, can not get the active hdfs namenode according to ${hdfsNameServiceHost}", ex)
""
}
}finally {
if (zkClient != null){
zkClient.close()
}
}

  如上述,代码 zkClient 在try中开启,不能再在try中关闭,因为发生异常的时候是关闭不掉的,切记切记切记!!!必须在finally中zkClient.close()才能把zkClient关闭,不这样做的后果就是会不断报连接zkserver失败

2. 异常捕获

2.1 每个方法都需要try catch,内或外的区别

  每个方法里面或者外面都需要try catch。不然会导致程序挂死,占用资源。

2.1 异常后的代码不会执行

  注意:try catch里面需要代码异常之后,异常代码剩下的代码将不会执行,如下示例:

try{
assert(argsCheck(args))
if (dbName != null && dbName != "") {
logInfo(s"use $dbName")
sparkSession.sql(s"use $dbName")
}
processSparkPara
run
sparkSession.stop()
result = true // determine if the taskVars json file exists, if not write the file, if exists overwrite the file
val taskVarsJson = JsonProtocal.taskVarsToJson(TaskVars(systemVars, runtimeVars))
logInfo(s"write taskVarsJsonStr:$taskVarsJson")
// if (!isLocal){
HDFSUtil.writeHDFSFile(taskVarsJsonPath, taskVarsJson)
// }else{
// createLocalFile(taskVarsJsonPath, taskVarsJson)
// }
}catch {
case e: Throwable => {
logError(s"== process failed, please check.",e)
cause = e.getMessage
result = false
}
}

  示例中的run方法发生异常之后,taskVarsJson文件将不会生成,而这将会导致后续的程序异常。如果taskVarsJson文件是程序所必须的,则不能放在try catch里面

try{
assert(argsCheck(args))
if (dbName != null && dbName != "") {
logInfo(s"use $dbName")
sparkSession.sql(s"use $dbName")
}
processSparkPara
run
sparkSession.stop()
result = true }catch {
case e: Throwable => {
logError(s"== process failed, please check.",e)
cause = e.getMessage
result = false
}
} // determine if the taskVars json file exists, if not write the file, if exists overwrite the file
val taskVarsJson = JsonProtocal.taskVarsToJson(TaskVars(systemVars, runtimeVars))
logInfo(s"write taskVarsJsonStr:$taskVarsJson")
// if (!isLocal){
HDFSUtil.writeHDFSFile(taskVarsJsonPath, taskVarsJson)
// }else{
// createLocalFile(taskVarsJsonPath, taskVarsJson)
// }

3. 测试规范

  测试成功,测试不成功两种。不要只测试成功的,遗留不成功,程序不成功也会导致程序线程挂死(占用资源)、不断打印连接不上日志等等异常情况。好像给别人造成不少麻烦...

4. scala的 case class 类构造优化

原代码:
case class Desc(name:String)
val taskDesc = TaskDesc("hello") 类扩展:
case class Desc(name:String, config: Config)
val taskDesc = TaskDesc("hello", null)

  评:上述代码扩展性不好,需要修改原来的老代码。参考如下设计,可以在扩展类的时候,避免修改其他老代码:

原代码:
case class Desc(name:String)
val taskDesc = TaskDesc("hello") 类扩展:
case class Desc(name:String, config: Config = null)
val taskDesc = TaskDesc("hello)

5. File文件与文件夹, 软连接路径与真实路径

/**
* 清除平台本地目录、HDFS目录前n天冗余日志文件
*/
def cleanExpiredLog(): Unit ={
logInfo("clean expired log start")
try{
val lifeCycleConfig = new LifeCycleConfig
var lifeCycle = lifeCycleConfig.getRunInfoLifeCycle
if (lifeCycle < 1) lifeCycle = 3
val sdfDay = new java.text.SimpleDateFormat("yyyy-MM-dd")
val strDay = sdfDay.format(System.currentTimeMillis() - lifeCycle * 24 * 60 * 60 * 1000)
val tasksFile = new File(FileUtil.getParentPath + File.separator + TaskPath.taskPath + File.separator) val tasksSubFiles = tasksFile.listFiles() for(taskFile <- tasksSubFiles){
// 筛选task任务目录下过期的文件夹
val filterFiles = filterExpiredLog(taskFile, strDay) // 删除过期日志
deleteExpiredLog(filterFiles)
}
}catch{
case ex: Exception =>
logError("clean expired log error, " + ex.getMessage)
}
logInfo("clean expired log end")
} /**
* 根据strDay过滤过期的日志
* @param taskFile 任务文件
* @param strDay 指定需要过滤的日期
* @return
*/
private def filterExpiredLog(taskFile: File, strDay: String): Array[File] ={
val filterFiles = taskFile.listFiles(new FileFilter {
override def accept(pathname: File): Boolean = {
if ((pathname.getName.compareTo(strDay)) <= 0 ){
return true
}else{
return false
}
}
}) filterFiles
} /**
* 删除本地和HDFS上的日志
* @param filterFiles
*/
private def deleteExpiredLog(filterFiles: Array[File]): Unit ={
if (filterFiles.size > 0){
for (file <- filterFiles){
logDebug("need to clean expired log: " + file.getAbsoluteFile)
val strDayLogPath = file.getAbsolutePath
val remoteStrDayLogPath = FileUtil.getSpecifiedInterception(":", strDayLogPath)
// 本地删除日志目录
FileUtil.deleteFile(file)
// HDFS删除日志目录
HDFSUtil.deleteHDFSFile(remoteStrDayLogPath)
}
}
}

  评:对文件进行操作时,需判断该文件父类是文件还是文件夹,而且如果是根据统一路径在deleteExpiredLog删除本地日志和HDFS日志的话,需要考虑该路径是否为完整路径(即真实路径)

def cleanExpiredLog(pathname: String, task: String): Unit ={
System.out.println("clean expired log start")
try{
var lifeCycle = 3
if (lifeCycle < 1) lifeCycle = 3
val sdfDay = new java.text.SimpleDateFormat("yyyy-MM-dd")
val strDay = sdfDay.format(System.currentTimeMillis() - lifeCycle * 24 * 60 * 60 * 1000)
val tasksFile = new File(pathname + File.separator + task + File.separator)
//getCanonicalPath为获取完整路径,因为上述路径可能是软连接路径
val tasksCanonicalFile = new File(tasksFile.getCanonicalPath)
val tasksSubFiles = tasksCanonicalFile.listFiles() for(taskFile <- tasksSubFiles){ //这里需要判断文件还是文件夹,否则文件的listFiles会报错
if (tasksFile.isDirectory){
// 筛选task任务目录下过期的文件夹
val filterFiles = filterExpiredLog(taskFile, strDay)
// 删除过期日志
deleteExpiredLog(filterFiles)
}
}
}catch{
case ex: Exception =>
System.out.println("clean expired log error, " + ex.getMessage)
}
System.out.println("clean expired log end")
}

Java代码规范总结,更新持续中的更多相关文章

  1. MyEclipse中阿里JAVA代码规范插件(P3C)的安装及使用

    JAVA代码规范插件(P3C)是阿里巴巴2017年10月14日在杭州云栖大会上首发的,使之前的阿里巴巴JAVA开发手册正式以插件形式公开走向业界.插件的相关信息及安装包都可以在GitHub(https ...

  2. IDEA中阿里JAVA代码规范插件(P3C)的安装及使用

    JAVA代码规范插件(P3C)是阿里巴巴2017年10月14日在杭州云栖大会上首发的,使之前的阿里巴巴JAVA开发手册正式以插件形式公开走向业界.插件的相关信息及安装包都可以在GitHub(https ...

  3. Java代码规范

    Java代码规范 本Java代码规范以SUN的标准Java代码规范为基础,为适应我们公司的实际需要,可能会做一些修改.本文档中没有说明的地方,请参看SUN Java标准代码规范.如果两边有冲突,以SU ...

  4. Java 代码规范,你应该知道的一些工具和用法

    从事编程这个行业,你一定被别人说过或者说过别人这句话:代码要规范!求职面试时也能从 JD 上看到这个要求:要有良好的编程习惯.其实都是在讲代码规范(Code Style)这件事情. 每个人都有自己的编 ...

  5. Java 代码规范,你应该知道的一些工具和用法(转)

    转自:http://yifeng.studio/2017/06/30/coding-with-code-style/ Java 代码规范,你应该知道的一些工具和用法 2017-06-30 从事编程这个 ...

  6. 转!!Java代码规范、格式化和checkstyle检查配置文档

    为便于规范各位开发人员代码.提高代码质量,研发中心需要启动代码评审机制.为了加快代码评审的速度,减少不必要的时间,可以加入一些代码评审的静态检查工具,另外需要为研发中心配置统一的编码模板和代码格式化模 ...

  7. Java代码规范、格式化和checkstyle检查配置文档

    http://www.blogjava.net/amigoxie/archive/2014/05/31/414287.html 文件下载: http://files.cnblogs.com/files ...

  8. JAVA代码规范笔记(上)

    本文为<code conventions-150003>(JAVA代码规范)笔记. 文件组织 1.超过2000行代码的源文件将会比较难以阅读,应该避免. 2.每个Java源文件都包含单一的 ...

  9. Alibaba Java Coding Guidelines,以后的Java代码规范,就靠它了

    前言 对于Java代码规范,业界有统一的标准,不少公司对此都有一定的要求.但是即便如此,庞大的Java使用者由于经验很水平的限制,未必有规范编码的意识,而且即便经验丰富的老Java程序员也无法做到时刻 ...

  10. Alibaba Java Coding Guidelines,以后我的Java代码规范,就靠它了

    前言 对于Java代码规范,业界有统一的标准,不少公司对此都有一定的要求.但是即便如此,庞大的Java使用者由于经验很水平的限制,未必有规范编码的意识,而且即便经验丰富的老Java程序员也无法做到时刻 ...

随机推荐

  1. JDK动态代理为什么必须要基于接口?

    原创:微信公众号 码农参上,欢迎分享,转载请保留出处. 前几天的时候,交流群里的小伙伴抛出了一个问题,为什么JDK的动态代理一定要基于接口实现呢? 好的安排,其实要想弄懂这个问题还是需要一些关于代理和 ...

  2. nginx域名转发

    场景1:因服务器限制,所以只对外开放了一个端口,但是需要请求不同的外网环境,所以在中转服务器上用nginx做了一次转发 实现: server { listen 8051; server_name lo ...

  3. 攻防世界Web_python_template_injection

    题目: 就一句话啥也没有.python 模板注入.刚学菜鸡还不知道python模板有哪些注入漏洞,上网查一下.又学到一个知识点. python常用的web 模板有 Django,Jinja2,Torn ...

  4. 音视频开发者的福音,快速集成AI配音能力

    音视频内容创作者对剪辑应用中的AI配音需求与日俱增.它的优点很多,不光可以解决雇佣人力配音的成本以及创作者本身的口音.语言等限制,还可以大幅提升生产效率.比如,短视频的播放时间短的几十秒,长的vlog ...

  5. 『无为则无心』Python面向对象 — 59、魔法方法

    目录 1.魔法方法__new__() 2.魔法方法__init__() 3.魔法方法__del__() 4.魔法方法__str__()和__repr__() 5.魔法方法__call__() 6.魔法 ...

  6. 如何使用 Rancher Desktop 访问 Traefik Proxy 仪表板

    Adrian Goins 最近举办了关于如何使用 K3s 和 Traefik 保护和控制边缘的 Kubernetes 大师班,演示了如何访问 K3s 的 Traefik Proxy 仪表板,可以通过以 ...

  7. Zabbix是什么?

    概述 Zabbix 是一个企业级的分布式开源监控方案,可以监控服务器健康性以及网络参数的一款软件,Zabbix几乎可以为任何时间配置邮件警告,这样用户可以实时通过邮箱接收服务器所发生的任何问题.对于已 ...

  8. .net 底层运行机制

    1.           CLR C#.NET 平台下,代码是怎么运行的 源代码-->托管模块-->程序集-JIT->编程CPU指令 1.1     在.NET框架下,首先将源代码编 ...

  9. nginx之版本升级方法一

    转至:https://www.cnblogs.com/sblack/p/12809034.html 非线上业务,纯属测试升级,线上业务不要采用此方法,可以采用官方推荐的平滑升级. 环境 Linux c ...

  10. Codeforces Round #750 (Div. 2) E. Pchelyonok and Segments

    传送门 题目大意: 给一个序列,可以在这个序列中从左至右选若干个段,第i段的长度为i,对于任意的段i,段内元素和S[i]<S[i+1],求在该序列中最多可以选出几段. 思路:设dp[i][j]为 ...