阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

HDBS之应用代码优化

196次阅读
没有评论

共计 3298 个字符,预计需要花费 9 分钟才能阅读完成。

一、目录结构树

  • 总体概述
  • 代码检测工具 sonar
  • HDBS 代码优化
  • 总结开发注意点

二、总体概述

进入现在这家公司我的第一个任务就是对 HDBS 进行代码质量优化。HDBS 可能大家不是很了解,现在给大家简单介绍下:HDBS 是 HadoopBaseService 的简称,Hadoop 有了解过大数据的朋友相信并不陌生,BaseService 自然也就是基础服务的意思;所以 HDBS 这个服务主要是基础服务的配置,同时 Hadoop 则表示数据量的大。以下是我暂时了解的应用架构图方便各位理解,毕竟才来这个公司一个星期可能画的不是很完整不过总体就是这么回事:

HDBS 之应用代码优化

二、代码检测工具  

  • 前提描述

这篇文章侧重讲 HDBS 代码存在的质量问题,至于怎么用、怎么搭建 sonar 代码异常检测平台后续再讲。

  • SonarQube简介

SonarQube 系统是一个代码质量检测工具,主要用于检测代码的编写质量,比如:覆盖率、是否包含空指针异常、异常是否正确处理、map 的遍历优化、是否包含无用代码块占据 cpu 资源等。由以下四个组件组成(https://docs.sonarqube.org/display/SONAR/Architecture+and+Integration)

  1.    一个 sonarqube 服务器 包含三个子进程(web 服务(界面管理),搜索服务 计算引擎服务(写入数据库))
  2.  一个 sonarqube 数据库 配置 sonarqube 服务
  3.   多个 sonarqube 插件 位于解压目录 extensions\plugins 目录
  4. 一个或者多个 sonarqube scanners 用于分析特定的项目

HDBS 之应用代码优化

  • 使用 SonarQube(简称 SQ)工作流程

  开发者使用开发工具(eclipse,ide)上传代码到 SCM(源代码管理器)    系统自动同步代码到某个位置 sonarqube scanners 扫描该代码检查质量 将分析结果 将分析结果推送到 SQServer 存储在 SQ 数据库 用户可以使用 eclipse 插件 sonarlint 来同步 sonarqube 服务器配置(java 和 js 版本等)可以实时在线分析。

HDBS 之应用代码优化

 

 三、HDBS 代码优化

  • 代码优化的重要性

通过 sonar 代码检测平台针对性地解决代码中相关问题。在大项目中代码质量尤为重要,虽然这些代码问题并不是错误,在正常的数据情况下是不会发生问题的,但是也有很多情况是数据不正常的时候;一个小小的 bug 可能导致成千上万的订单作废,性能的优化也很重要因为性能的优化可以使得 QPS 显著上升,代码问题最为严重的就可能导致整个实例挂掉(JVM 异常退出)。所以代码质量的提升是重中之重。

  • 如何优化

由于 HDBS 是经由不同的开发人员之手总体代码质量参差不其,虽然公司有一套开发手册但是执行起来似乎比较难;但是事实告诉我们:开发中要尽可能第按照公司开发手册,如果没有就要按照通用的开发规范进行开发,比如遵循阿里的开发规范,毕竟大公司走过的路躺过的坑还是比较多的我们要学会站在巨人的肩膀上往上爬。作为程序员开发效率其实是第一位,在实际开发中我们要学会使用工具来取得开发的最大效率,比如:这里我们采用 sonar 来管理代码质量问题、可以用 SourceTree 来管理 git 代码等;合理使用对应的工具可以达到开发效率的最大化,毕竟公司要的是一个能够有产出的人,如果你一天能够解决的问题而别人需要两天那么你就能得到上司的赏识。

四、总结开发注意点

  • HDBS 代码中发现的问题(部分)
  1. 异常没有正确处理。比如:直接在代码中使用 e.printStackTrace 代码打印异常;这是有一个问题就是:这些代码在本地启动遇到异常后是可以正常打印异常信息,但是当应用部署到 Linux 服务器的时候却可能不会打印,这如果在线上生产环境发生问题需要盘查的时候就尴尬了,因为你可能根本找不到异常的信息也就是说系统压根就没有记录任何异常信息。
    解决方法:LOGGER.error(”xx 异常:{}”,e)
  2. 可能发生 NullPointerException。比如:前面的代码定义了 Map<Object,Object> map=null; 但后面在没有判断 obj 是否为 null 的情况下进行 map.size()的操作;这也是我们需要注意的地方,这种代码逻辑一般我们是不会进行异常处理的,异常处理要遵循:能够不需要异常处理就不要用异常处理不能把异常处理当做工具来使用。这种情况下如果没判断为 null 就进行操作就会发生运行时异常当前线程就会意外终止。
    解决方法:先判断是否为 null
  3. Map 的遍历方式优化。在开发中我见过很多人是这样遍历 Map 的:先得到 keySet()视图,然后遍历 keys,通过 get(key)的方式来获取对应的 value。这种遍历性能其实是很差的,因为我们在遍历 keys 的时候需要花费一定的时间,在 get(key)的时候又会花费一定的时间;我们都知道 Map 的 get()是要计算 hashCode 然后通过 hashCode 计算数组的下标,如果有 hash 冲突又会遍历链表,这种遍历方式显然是低效的,cpu 资源是宝贵的这种方式会严重占用 cpu 并且时间花费的要长得多。
    解决方法 :通过 entrySet() 获取 key、value 视图,一次遍历就可以获取对应的 value,而不需要通过 get();不过你也可以用迭代遍历,这都是可以的。
  4. 日志打印不规范。比如:LOGGER.info(“请求参数:”+params.toString); 日志是盘查问题的关键信息,所以在一个系统中无处不在,一个线程可能产生的 log 数量就是成百上千行,如果每条日志都这么打印的话会严重影响整个应用的性能。因为字符串拼接的性能是很差的,相信我们都对 String 不陌生,像这种 String c=a+ b 的方式性能有多好自己也清楚。
    解决方法:LOGGER.info(“请求参数:{}”,params.toString)
  5. 没有考虑线程安全问题。如:在多线程系统应用 HashMap;线程安全的概念简单来讲就是:同一个代码块在单线程和多线程的执行情况下的结果是一样的,否则线程非安全。如果在多线程系统应用了 HashMap 可能导致多个线程之间数据混淆或者是严重占用系统资源,占用系统资源即为发生了循环链表的问题,具体为什么产生循环链表这里就不多加阐述了;同时 String、StringBuffer、StringBuilder 也类似。
    解决方法:用 HashTable 或者 ConCurrentHashMap 替换 HashMap
  6. 无效代码。比如:Date date=new Date(),在判断 date 是否是空的时候用 if( date!=null && !””.equal(date));我们都知道 date 是 Date 类型永远也不可能是 String 类型,但是在写代码的时候我们却又一个习惯喜欢加上 ””.equal(date)来判断,当然这么写是不会有错的,虽然 Date 不是 Strng 但是由于 is- a 的原则他们的父类都是 Object,而 equal 是 Object 的方法所以那样判断自然也没有错。这里讲的不单单是 Date 这个类型,如果是非 String 类型都这样;还有就是当我们使用 List<String> list=new ArrayList<> 的方式的时候,后续用 list 这个对象的时候不需要判断是否为 null,因为 new 出来的对象在没有被 JVM 回收之前引用的对象永远是非 null。
    解决方法:去除无效代码
  7. 合理使用同步锁。比如:全局定义了一个 private static final DateFormat df=new SimpleDateFormat(“yyyy-MM-dd HH:MM:ss”)变量; 在该类中使用到 df 对象的时候都应用了同步锁;如果在线程并大量大的时候同步锁会严重占用系统资源的开销,因为获得锁与释放锁的过程都是需要占用资源的同时也会带来并发量的下降,所以在能不用同步锁解决问题的时候尽可能不使用锁,万不得已的时候就可以使用。
    解决方法:去除同步锁,在方法中定义局部变量:DateFormat df=new SimpleDateFormat(“yyyy-MM-dd HH:MM:ss”)

正文完
星哥玩云-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-22发表,共计3298字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中